Skip to content

Commit a3c7dea

Browse files
committed
inc/dec with undefined vars
1 parent fc3df28 commit a3c7dea

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

@@ -1538,6 +1545,13 @@ ZEND_VM_HELPER(zend_pre_dec_helper, VAR|CV, ANY)
15381545
SAVE_OPLINE();
15391546
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
15401547
ZVAL_UNDEFINED_OP1();
1548+
if (UNEXPECTED(EG(exception))) {
1549+
/* Smart branch expects result to be set with exceptions */
1550+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1551+
ZVAL_NULL(EX_VAR(opline->result.var));
1552+
}
1553+
HANDLE_EXCEPTION();
1554+
}
15411555
ZVAL_NULL(var_ptr);
15421556
}
15431557

@@ -1590,6 +1604,13 @@ ZEND_VM_HELPER(zend_post_inc_helper, VAR|CV, ANY)
15901604
SAVE_OPLINE();
15911605
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
15921606
ZVAL_UNDEFINED_OP1();
1607+
if (UNEXPECTED(EG(exception))) {
1608+
/* Smart branch expects result to be set with exceptions */
1609+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1610+
ZVAL_NULL(EX_VAR(opline->result.var));
1611+
}
1612+
HANDLE_EXCEPTION();
1613+
}
15931614
ZVAL_NULL(var_ptr);
15941615
}
15951616

@@ -1641,6 +1662,13 @@ ZEND_VM_HELPER(zend_post_dec_helper, VAR|CV, ANY)
16411662
SAVE_OPLINE();
16421663
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
16431664
ZVAL_UNDEFINED_OP1();
1665+
if (UNEXPECTED(EG(exception))) {
1666+
/* Smart branch expects result to be set with exceptions */
1667+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1668+
ZVAL_NULL(EX_VAR(opline->result.var));
1669+
}
1670+
HANDLE_EXCEPTION();
1671+
}
16441672
ZVAL_NULL(var_ptr);
16451673
}
16461674

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)