]> granicus.if.org Git - php/commitdiff
Fix leak of dynamic property name in address helper
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Dec 2019 15:58:10 +0000 (16:58 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 17 Dec 2019 15:59:35 +0000 (16:59 +0100)
Zend/tests/dynamic_prop_name_leak.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/Zend/tests/dynamic_prop_name_leak.phpt b/Zend/tests/dynamic_prop_name_leak.phpt
new file mode 100644 (file)
index 0000000..093a424
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Dynamic prop name with type conversion in reference position should not leak
+--FILE--
+<?php
+$obj = new stdClass;
+$name = 0.0;
+$ref =& $obj->$name;
+var_dump($obj);
+--EXPECT--
+object(stdClass)#1 (1) {
+  ["0"]=>
+  &NULL
+}
index 275a3be30908458ad55d38f505ceaecb298ea52a..d216c78250377f756756239ca2007d7d44629edb 100644 (file)
@@ -2768,11 +2768,11 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
                        if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) {
                                ZVAL_UNREF(ptr);
                        }
-                       return;
+                       goto end;
                }
        } else if (UNEXPECTED(Z_ISERROR_P(ptr))) {
                ZVAL_ERROR(result);
-               return;
+               goto end;
        }
 
        ZVAL_INDIRECT(result, ptr);
@@ -2783,18 +2783,23 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
                        prop_info = CACHED_PTR_EX(cache_slot + 2);
                        if (prop_info) {
                                if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, NULL, prop_info, flags))) {
-                                       return;
+                                       goto end;
                                }
                        }
                } else {
                        if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, Z_OBJ_P(container), NULL, flags))) {
-                               return;
+                               goto end;
                        }
                }
        }
        if (init_undef && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
                ZVAL_NULL(ptr);
        }
+
+end:
+       if (prop_op_type != IS_CONST) {
+               zend_tmp_string_release(tmp_name);
+       }
 }
 
 static zend_always_inline void zend_assign_to_property_reference(zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC)