Skip to content

Commit a1ae0a2

Browse files
committed
inc/dec with undefined vars
1 parent 66b359e commit a1ae0a2

6 files changed

+185
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Inc/dec on undefined variable: warning converted to exception
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function($severity, $m) {
7+
throw new Exception($m, $severity);
8+
});
9+
10+
unset($x);
11+
try {
12+
$x++;
13+
} catch (\Exception $e) {
14+
echo $e->getMessage(), PHP_EOL;
15+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
16+
}
17+
unset($x);
18+
try {
19+
$x--;
20+
} catch (\Exception $e) {
21+
echo $e->getMessage(), PHP_EOL;
22+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
23+
}
24+
unset($x);
25+
try {
26+
++$x;
27+
} catch (\Exception $e) {
28+
echo $e->getMessage(), PHP_EOL;
29+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
30+
}
31+
unset($x);
32+
try {
33+
--$x;
34+
} catch (\Exception $e) {
35+
echo $e->getMessage(), PHP_EOL;
36+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
37+
}
38+
unset($x);
39+
?>
40+
--EXPECT--
41+
Undefined variable $x
42+
UNDEF
43+
Undefined variable $x
44+
UNDEF
45+
Undefined variable $x
46+
UNDEF
47+
Undefined variable $x
48+
UNDEF
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Inc/dec on undefined variable: warning converted to exception
3+
--FILE--
4+
<?php
5+
6+
set_error_handler(function($severity, $m) {
7+
throw new Exception($m, $severity);
8+
});
9+
10+
unset($x);
11+
try {
12+
$y = $x++;
13+
} catch (\Exception $e) {
14+
echo $e->getMessage(), PHP_EOL;
15+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
16+
}
17+
unset($x);
18+
try {
19+
$y = $x--;
20+
} catch (\Exception $e) {
21+
echo $e->getMessage(), PHP_EOL;
22+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
23+
}
24+
unset($x);
25+
try {
26+
$y = ++$x;
27+
} catch (\Exception $e) {
28+
echo $e->getMessage(), PHP_EOL;
29+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
30+
}
31+
unset($x);
32+
try {
33+
$y = --$x;
34+
} catch (\Exception $e) {
35+
echo $e->getMessage(), PHP_EOL;
36+
if (!isset($x)) { echo("UNDEF\n"); } else { var_dump($x); }
37+
}
38+
unset($x);
39+
?>
40+
--EXPECT--
41+
Undefined variable $x
42+
UNDEF
43+
Undefined variable $x
44+
UNDEF
45+
Undefined variable $x
46+
UNDEF
47+
Undefined variable $x
48+
UNDEF

Zend/zend_vm_def.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,13 @@ ZEND_VM_HELPER(zend_pre_inc_helper, VAR|CV, ANY)
14871487
SAVE_OPLINE();
14881488
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
14891489
ZVAL_UNDEFINED_OP1();
1490+
if (UNEXPECTED(EG(exception))) {
1491+
/* Smart branch expects result to be set with exceptions */
1492+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1493+
ZVAL_NULL(EX_VAR(opline->result.var));
1494+
}
1495+
HANDLE_EXCEPTION();
1496+
}
14901497
ZVAL_NULL(var_ptr);
14911498
}
14921499

@@ -1545,6 +1552,13 @@ ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
15451552
SAVE_OPLINE();
15461553
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
15471554
ZVAL_UNDEFINED_OP1();
1555+
if (UNEXPECTED(EG(exception))) {
1556+
/* Smart branch expects result to be set with exceptions */
1557+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1558+
ZVAL_NULL(EX_VAR(opline->result.var));
1559+
}
1560+
HANDLE_EXCEPTION();
1561+
}
15481562
ZVAL_NULL(var_ptr);
15491563
}
15501564

@@ -1604,6 +1618,13 @@ ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY)
16041618
SAVE_OPLINE();
16051619
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
16061620
ZVAL_UNDEFINED_OP1();
1621+
if (UNEXPECTED(EG(exception))) {
1622+
/* Smart branch expects result to be set with exceptions */
1623+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1624+
ZVAL_NULL(EX_VAR(opline->result.var));
1625+
}
1626+
HANDLE_EXCEPTION();
1627+
}
16071628
ZVAL_NULL(var_ptr);
16081629
}
16091630

@@ -1655,6 +1676,13 @@ ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY)
16551676
SAVE_OPLINE();
16561677
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
16571678
ZVAL_UNDEFINED_OP1();
1679+
if (UNEXPECTED(EG(exception))) {
1680+
/* Smart branch expects result to be set with exceptions */
1681+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1682+
ZVAL_NULL(EX_VAR(opline->result.var));
1683+
}
1684+
HANDLE_EXCEPTION();
1685+
}
16581686
ZVAL_NULL(var_ptr);
16591687
}
16601688

Zend/zend_vm_execute.h

Lines changed: 56 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3883,6 +3883,8 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op
38833883
| // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var))));
38843884
| LOAD_32BIT_VAL FCARG1w, opline->op1.var
38853885
| EXT_CALL zend_jit_undefined_op_helper, REG0
3886+
| // Check if undefined error was converted to exception and abort
3887+
| cbz RETVALx, ->exception_handler_undef
38863888
| SET_ZVAL_TYPE_INFO op1_addr, IS_NULL, TMP1w, TMP2
38873889
op1_info |= MAY_BE_NULL;
38883890
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4264,6 +4264,9 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op
42644264
| mov FCARG1d, opline->op1.var
42654265
| EXT_CALL zend_jit_undefined_op_helper, r0
42664266
| SET_ZVAL_TYPE_INFO op1_addr, IS_NULL
4267+
| // Check if undefined error was converted to exception and abort
4268+
| test r0, r0
4269+
| jz ->exception_handler_undef
42674270
op1_info |= MAY_BE_NULL;
42684271
}
42694272
|2:

0 commit comments

Comments
 (0)