From: Nikita Popov Date: Tue, 17 Dec 2019 15:58:10 +0000 (+0100) Subject: Fix leak of dynamic property name in address helper X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7194825c86891ac24a7f87ed93e1d27b6f62f2db;p=php Fix leak of dynamic property name in address helper --- diff --git a/Zend/tests/dynamic_prop_name_leak.phpt b/Zend/tests/dynamic_prop_name_leak.phpt new file mode 100644 index 0000000000..093a42400d --- /dev/null +++ b/Zend/tests/dynamic_prop_name_leak.phpt @@ -0,0 +1,13 @@ +--TEST-- +Dynamic prop name with type conversion in reference position should not leak +--FILE-- +$name; +var_dump($obj); +--EXPECT-- +object(stdClass)#1 (1) { + ["0"]=> + &NULL +} diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 275a3be309..d216c78250 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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)