From 8362aebdbfa15e6afb52b2d46f44228ad08cec5e Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 21 Apr 2015 21:04:20 +0800 Subject: [PATCH] Fixed mem leak in assign_to_obj with reference --- Zend/tests/assign_to_obj_001.phpt | 24 ++++++++++++++++++++++++ Zend/zend_execute.c | 27 ++++++++++++++++----------- 2 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 Zend/tests/assign_to_obj_001.phpt diff --git a/Zend/tests/assign_to_obj_001.phpt b/Zend/tests/assign_to_obj_001.phpt new file mode 100644 index 0000000000..4b3cd31b92 --- /dev/null +++ b/Zend/tests/assign_to_obj_001.phpt @@ -0,0 +1,24 @@ +--TEST-- +assgin to object leaks with ref +--FILE-- +a = a(1); + unset($this->a); + } +} + +$a = new A; + +$a->test(); +$a->test(); +echo "okey"; +?> +--EXPECT-- +okey diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index cbe6ef1d80..eb37d48522 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1044,7 +1044,6 @@ fast_assign: } if (!zobj->ce->__set) { - zend_reference *ref = NULL; if (EXPECTED(zobj->properties == NULL)) { rebuild_object_properties(zobj); @@ -1059,11 +1058,22 @@ fast_assign: } else if (value_type != IS_TMP_VAR) { if (Z_ISREF_P(value)) { if (value_type == IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + zend_reference *ref = Z_REF_P(value); + if (--(GC_REFCOUNT(ref)) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } + } else { + value = Z_REFVAL_P(value); + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } } } else if (value_type == IS_CV && Z_REFCOUNTED_P(value)) { Z_ADDREF_P(value); @@ -1073,11 +1083,6 @@ fast_assign: if (retval) { ZVAL_COPY(retval, value); } - if (/*value_type == IS_VAR &&*/ ref) { - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } - } return; } } -- 2.40.0