Skip to content

Commit 28df23b

Browse files
committed
Fix leak if error handler changes the value to an allocated value
1 parent 9fbd0fa commit 28df23b

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Unset declared property converted to object in error handler
3+
--FILE--
4+
<?php
5+
class C {
6+
public $a;
7+
function errorHandler() {
8+
$this->a = new stdClass();
9+
}
10+
}
11+
$c = new C;
12+
set_error_handler([$c,'errorHandler']);
13+
unset($c->a);
14+
15+
try {
16+
(++$c->a);
17+
} catch (\TypeError $e) {
18+
echo $e->getMessage(), PHP_EOL;
19+
}
20+
var_dump($c->a);
21+
?>
22+
--EXPECT--
23+
Cannot increment stdClass
24+
object(stdClass)#2 (0) {
25+
}

Zend/zend_object_handlers.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,10 +1117,12 @@ ZEND_API zval *zend_std_get_property_ptr_ptr(zend_object *zobj, zend_string *nam
11171117
ZSTR_VAL(name));
11181118
retval = &EG(error_zval);
11191119
} else {
1120-
zend_error(E_WARNING, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
1121-
/* We set the retval to null AFTER the warning so that an error handler cannot mess
1122-
* with the property value... */
11231120
ZVAL_NULL(retval);
1121+
zend_error(E_WARNING, "Undefined property: %s::$%s", ZSTR_VAL(zobj->ce->name), ZSTR_VAL(name));
1122+
/* If an error handler unsets the property again just consider it to be NULL again */
1123+
if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
1124+
ZVAL_NULL(retval);
1125+
}
11241126
}
11251127
} else if (prop_info && UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) {
11261128
/* Readonly property, delegate to read_property + write_property. */

0 commit comments

Comments
 (0)