From: Dmitry Stogov Date: Thu, 26 Oct 2017 11:04:42 +0000 (+0300) Subject: Restore object copying on magic method calls (It was removed in master only). X-Git-Tag: php-7.3.0alpha1~1167 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0772b32ef60c5cefdfca3ca11b7e323d63152e58;p=php Restore object copying on magic method calls (It was removed in master only). --- 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-- +$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-- +$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'");