]> granicus.if.org Git - php/commitdiff
Fix const/cv freeing on failed reference assignment
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Dec 2019 08:53:30 +0000 (09:53 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 18 Dec 2019 08:54:10 +0000 (09:54 +0100)
Zend/tests/type_declarations/typed_properties_106.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/type_declarations/typed_properties_106.phpt b/Zend/tests/type_declarations/typed_properties_106.phpt
new file mode 100644 (file)
index 0000000..344cfa5
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+CONST/CV should not be freed on failed reference assignment
+--FILE--
+<?php
+class Test {
+    public ?Type $prop;
+}
+$obj = new Test;
+$ref =& $obj->prop;
+try {
+    $ref = [1];
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    $ary = [1];
+    $ref = $ary;
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+var_dump($ref);
+?>
+--EXPECT--
+Cannot assign array to reference held by property Test::$prop of type ?Type
+Cannot assign array to reference held by property Test::$prop of type ?Type
+NULL
index 3611c5b008afd605bf0bff0c1a2ec86611830916..c1ff85bff86452e07df8a93a086a9db43c65e48c 100644 (file)
@@ -3187,7 +3187,9 @@ ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, zend_uc
                Z_TRY_DELREF_P(value);
        }
        if (!ret) {
-               zval_ptr_dtor(value);
+               if (value_type & (IS_VAR|IS_TMP_VAR)) {
+                       zval_ptr_dtor(value);
+               }
                return Z_REFVAL_P(variable_ptr);
        }