]> granicus.if.org Git - php/commitdiff
Restore object copying on magic method calls (It was removed in master only).
authorDmitry Stogov <dmitry@zend.com>
Thu, 26 Oct 2017 11:04:42 +0000 (14:04 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 26 Oct 2017 11:04:42 +0000 (14:04 +0300)
Zend/tests/bug75420.7.phpt [new file with mode: 0644]
Zend/tests/bug75420.8.phpt [new file with mode: 0644]
Zend/zend_object_handlers.c

diff --git a/Zend/tests/bug75420.7.phpt b/Zend/tests/bug75420.7.phpt
new file mode 100644 (file)
index 0000000..0b9743a
--- /dev/null
@@ -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 (file)
index 0000000..2d57c8b
--- /dev/null
@@ -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)
index 0097f45b874c92c26acbcc474befaaf707d43498..1a4f9f85a7058a9575d1c1e4199d3c0c4c860a36 100644 (file)
@@ -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'");