diff options
| -rw-r--r-- | Zend/tests/bug75420.7.phpt | 17 | ||||
| -rw-r--r-- | Zend/tests/bug75420.8.phpt | 17 | ||||
| -rw-r--r-- | Zend/zend_object_handlers.c | 12 |
3 files changed, 44 insertions, 2 deletions
diff --git a/Zend/tests/bug75420.7.phpt b/Zend/tests/bug75420.7.phpt new file mode 100644 index 0000000000..0b9743a880 --- /dev/null +++ b/Zend/tests/bug75420.7.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #75420.7 (Indirect modification of magic method argument) +--FILE-- +<?php +class Test { + public function __set($x,$v) { $GLOBALS["name"] = 24; var_dump($x); } +} + +$obj = new Test; +$name = "foo"; +$name = str_repeat($name, 2); +$obj->$name = 1; +var_dump($name); +?> +--EXPECT-- +string(6) "foofoo" +int(24) diff --git a/Zend/tests/bug75420.8.phpt b/Zend/tests/bug75420.8.phpt new file mode 100644 index 0000000000..2d57c8b1cb --- /dev/null +++ b/Zend/tests/bug75420.8.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #75420.8 (Indirect modification of magic method argument) +--FILE-- +<?php +class Test { + public function __set($x,$v) { $GLOBALS["obj"] = 24; var_dump($this); } +} + +$obj = new Test; +$name = "foo"; +$obj->$name = 1; +var_dump($obj); +?> +--EXPECT-- +object(Test)#1 (0) { +} +int(24) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 0097f45b87..1a4f9f85a7 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -732,9 +732,13 @@ found: uint32_t *guard = zend_get_property_guard(zobj, Z_STR_P(member)); if (!((*guard) & IN_SET)) { + zval tmp_object; + + ZVAL_COPY(&tmp_object, object); (*guard) |= IN_SET; /* prevent circular setting */ - zend_std_call_setter(object, member, value); + zend_std_call_setter(&tmp_object, member, value); (*guard) &= ~IN_SET; + zval_ptr_dtor(&tmp_object); } else if (EXPECTED(!IS_WRONG_PROPERTY_OFFSET(property_offset))) { goto write_std_property; } else { @@ -983,10 +987,14 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo if (zobj->ce->__unset) { uint32_t *guard = zend_get_property_guard(zobj, Z_STR_P(member)); if (!((*guard) & IN_UNSET)) { + zval tmp_object; + /* have unseter - try with it! */ + ZVAL_COPY(&tmp_object, object); (*guard) |= IN_UNSET; /* prevent circular unsetting */ - zend_std_call_unsetter(object, member); + zend_std_call_unsetter(&tmp_object, member); (*guard) &= ~IN_UNSET; + zval_ptr_dtor(&tmp_object); } else { if (Z_STRVAL_P(member)[0] == '\0' && Z_STRLEN_P(member) != 0) { zend_throw_error(NULL, "Cannot access property started with '\\0'"); |
