Skip to content

Commit a8b6f16

Browse files
committed
Handle all known cases
Post increments are converted to pre increments if no return value is used. Ditto for decrement
1 parent dc4d094 commit a8b6f16

7 files changed

+170
-13
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
OSS Fuzz #61469: Undef variable in ++/-- for dynamic property that is unset in error handler
3+
--FILE--
4+
<?php
5+
class C {
6+
function errorHandle() {
7+
unset($this->a);
8+
}
9+
}
10+
$c = new C;
11+
set_error_handler([$c,'errorHandle']);
12+
$c->a += 5;
13+
var_dump($c->a);
14+
?>
15+
--EXPECT--
16+
NULL
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
OSS Fuzz #61469: Undef variable in ++/-- for dynamic property that is unset in error handler
3+
--FILE--
4+
<?php
5+
class C {
6+
function errorHandle() {
7+
unset($this->a);
8+
}
9+
}
10+
$c = new C;
11+
set_error_handler([$c,'errorHandle']);
12+
13+
$v = ($c->a--);
14+
var_dump($c->a);
15+
var_dump($v);
16+
?>
17+
--EXPECT--
18+
NULL
19+
NULL
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
OSS Fuzz #61469: Undef variable in ++/-- for dynamic property that is unset in error handler
3+
--FILE--
4+
<?php
5+
class C {
6+
function errorHandle() {
7+
unset($this->a);
8+
}
9+
}
10+
$c = new C;
11+
set_error_handler([$c,'errorHandle']);
12+
13+
$v = ($c->a--);
14+
var_dump($c->a);
15+
var_dump($v);
16+
?>
17+
--EXPECT--
18+
NULL
19+
NULL

Zend/tests/in-de-crement/oss-fuzz-61469_inc_dec_dynamic_property_unset_error_handler.phpt renamed to Zend/tests/in-de-crement/oss-fuzz-61469_predec_dynamic_property_unset_error_handler.phpt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,8 @@ class C {
99
}
1010
$c = new C;
1111
set_error_handler([$c,'errorHandle']);
12-
13-
($c->a++);
14-
var_dump($c->a);
15-
16-
($c->a--);
17-
var_dump($c->a);
18-
19-
(++$c->a);
20-
var_dump($c->a);
21-
2212
(--$c->a);
2313
var_dump($c->a);
2414
?>
2515
--EXPECT--
2616
NULL
27-
NULL
28-
NULL
29-
NULL
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
OSS Fuzz #61469: Undef variable in ++/-- for dynamic property that is unset in error handler
3+
--FILE--
4+
<?php
5+
class C {
6+
function errorHandle() {
7+
unset($this->a);
8+
}
9+
}
10+
$c = new C;
11+
set_error_handler([$c,'errorHandle']);
12+
(++$c->a);
13+
var_dump($c->a);
14+
?>
15+
--EXPECT--
16+
NULL

Zend/zend_vm_def.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,6 +1059,11 @@ ZEND_VM_C_LABEL(assign_op_object):
10591059
zval *orig_zptr = zptr;
10601060
zend_reference *ref;
10611061

1062+
/* This case can ***ONLY*** happen if get_property_ptr_ptr emits a diagnostic
1063+
* (e.g. undefined property warning) and the property is unset in the error handler */
1064+
if (UNEXPECTED(Z_TYPE_P(zptr) == IS_UNDEF)) {
1065+
ZVAL_NULL(zptr);
1066+
}
10621067
do {
10631068
if (UNEXPECTED(Z_ISREF_P(zptr))) {
10641069
ref = Z_REF_P(zptr);
@@ -1404,6 +1409,11 @@ ZEND_VM_C_LABEL(post_incdec_object):
14041409
if (UNEXPECTED(Z_ISERROR_P(zptr))) {
14051410
ZVAL_NULL(EX_VAR(opline->result.var));
14061411
} else {
1412+
/* This case can ***ONLY*** happen if get_property_ptr_ptr emits a diagnostic
1413+
* (e.g. undefined property warning) and the property is unset in the error handler */
1414+
if (UNEXPECTED(Z_TYPE_P(zptr) == IS_UNDEF)) {
1415+
ZVAL_NULL(zptr);
1416+
}
14071417
if (OP2_TYPE == IS_CONST) {
14081418
prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2);
14091419
} else {

Zend/zend_vm_execute.h

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

0 commit comments

Comments
 (0)