summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-10-26 14:04:42 +0300
committerDmitry Stogov <dmitry@zend.com>2017-10-26 14:04:42 +0300
commit0772b32ef60c5cefdfca3ca11b7e323d63152e58 (patch)
treeaaf57d853469c6b8497e2485c1ba80724b446261
parentb09e39830455a85f2af128a78178e738482e89cc (diff)
downloadphp-git-0772b32ef60c5cefdfca3ca11b7e323d63152e58.tar.gz
Restore object copying on magic method calls (It was removed in master only).
-rw-r--r--Zend/tests/bug75420.7.phpt17
-rw-r--r--Zend/tests/bug75420.8.phpt17
-rw-r--r--Zend/zend_object_handlers.c12
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'");