]> granicus.if.org Git - php/commitdiff
Handle binary_op failure in overloaded assigns
authorNikita Popov <nikita.ppv@gmail.com>
Sun, 23 Sep 2018 13:29:25 +0000 (15:29 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Sun, 23 Sep 2018 13:29:25 +0000 (15:29 +0200)
Zend/tests/throwing_overloaded_compound_assign_op.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/throwing_overloaded_compound_assign_op.phpt b/Zend/tests/throwing_overloaded_compound_assign_op.phpt
new file mode 100644 (file)
index 0000000..e6e79ba
--- /dev/null
@@ -0,0 +1,44 @@
+--TEST--
+Exception in compound assign op should prevent call to overloaded object handlers
+--FILE--
+<?php
+
+class Test {
+    public function __get($k) {
+        $this->$k = 42;
+        return 0;
+    }
+}
+
+$test = new ArrayObject;
+$test[0] = 42;
+try {
+    $test[0] %= 0;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump($test);
+
+$test2 = new Test;
+try {
+    $test2->prop %= 0;
+} catch (Error $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump($test2);
+
+?>
+--EXPECT--
+Modulo by zero
+object(ArrayObject)#1 (1) {
+  ["storage":"ArrayObject":private]=>
+  array(1) {
+    [0]=>
+    int(42)
+  }
+}
+Modulo by zero
+object(Test)#3 (1) {
+  ["prop"]=>
+  int(42)
+}
index 8dd1a8c43cbd3f7762d3351c4f9b9d99d378f29c..e204ae59893390ffa9ab5ed347f6fc2705d96bbb 100644 (file)
@@ -1144,8 +1144,9 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *
                        }
                        ZVAL_COPY_VALUE(z, value);
                }
-               binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value);
-               Z_OBJ_HT_P(object)->write_dimension(object, property, &res);
+               if (binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value) == SUCCESS) {
+                       Z_OBJ_HT_P(object)->write_dimension(object, property, &res);
+               }
                if (z == &rv) {
                        zval_ptr_dtor(&rv);
                }
@@ -1538,8 +1539,9 @@ static zend_never_inline void zend_assign_op_overloaded_property(zval *object, z
                        }
                        ZVAL_COPY_VALUE(z, value);
                }
-               binary_op(&res, z, value);
-               Z_OBJ_HT(obj)->write_property(&obj, property, &res, cache_slot);
+               if (binary_op(&res, z, value) == SUCCESS) {
+                       Z_OBJ_HT(obj)->write_property(&obj, property, &res, cache_slot);
+               }
                if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                        ZVAL_COPY(EX_VAR(opline->result.var), &res);
                }