]> granicus.if.org Git - php/commitdiff
Fix leak in foreach with by-ref iteration of ref array
authorNikita Popov <nikic@php.net>
Sat, 20 Sep 2014 10:46:05 +0000 (12:46 +0200)
committerNikita Popov <nikic@php.net>
Sat, 20 Sep 2014 10:46:05 +0000 (12:46 +0200)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index b4f8c83f1bb5d0e21d3307518996b227f8fd9403..4015855568135ba99da065a4a6b5e0fb33bbee47 100644 (file)
@@ -4464,16 +4464,14 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
                array_ptr = array_ref = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
                ZVAL_DEREF(array_ptr);
                if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
+                       SEPARATE_ARRAY(array_ptr);
                        if (!Z_ISREF_P(array_ref)) {
-                               SEPARATE_ARRAY(array_ptr);
                                array_ref = array_ptr;
                                if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
                                        ZVAL_NEW_REF(array_ptr, array_ptr);
                                        array_ref = array_ptr;
                                        array_ptr = Z_REFVAL_P(array_ptr);                                              
                                }
-                       } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
-                               zval_copy_ctor(array_ptr);
                        }
                        if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
index d575db001821871dddb6c51295031d27116de62d..e236fa64705f1221b378d11b1c2e9c4d56a27319 100644 (file)
@@ -3069,16 +3069,14 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
                array_ptr = array_ref = NULL;
                ZVAL_DEREF(array_ptr);
                if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
+                       SEPARATE_ARRAY(array_ptr);
                        if (!Z_ISREF_P(array_ref)) {
-                               SEPARATE_ARRAY(array_ptr);
                                array_ref = array_ptr;
                                if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
                                        ZVAL_NEW_REF(array_ptr, array_ptr);
                                        array_ref = array_ptr;
                                        array_ptr = Z_REFVAL_P(array_ptr);
                                }
-                       } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
-                               zval_copy_ctor(array_ptr);
                        }
                        if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -9789,16 +9787,14 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
                array_ptr = array_ref = NULL;
                ZVAL_DEREF(array_ptr);
                if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
+                       SEPARATE_ARRAY(array_ptr);
                        if (!Z_ISREF_P(array_ref)) {
-                               SEPARATE_ARRAY(array_ptr);
                                array_ref = array_ptr;
                                if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
                                        ZVAL_NEW_REF(array_ptr, array_ptr);
                                        array_ref = array_ptr;
                                        array_ptr = Z_REFVAL_P(array_ptr);
                                }
-                       } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
-                               zval_copy_ctor(array_ptr);
                        }
                        if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -16424,16 +16420,14 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
                array_ptr = array_ref = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
                ZVAL_DEREF(array_ptr);
                if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
+                       SEPARATE_ARRAY(array_ptr);
                        if (!Z_ISREF_P(array_ref)) {
-                               SEPARATE_ARRAY(array_ptr);
                                array_ref = array_ptr;
                                if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
                                        ZVAL_NEW_REF(array_ptr, array_ptr);
                                        array_ref = array_ptr;
                                        array_ptr = Z_REFVAL_P(array_ptr);
                                }
-                       } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
-                               zval_copy_ctor(array_ptr);
                        }
                        if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -33854,16 +33848,14 @@ static int ZEND_FASTCALL  ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
                array_ptr = array_ref = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
                ZVAL_DEREF(array_ptr);
                if (Z_TYPE_P(array_ptr) == IS_ARRAY) {
+                       SEPARATE_ARRAY(array_ptr);
                        if (!Z_ISREF_P(array_ref)) {
-                               SEPARATE_ARRAY(array_ptr);
                                array_ref = array_ptr;
                                if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
                                        ZVAL_NEW_REF(array_ptr, array_ptr);
                                        array_ref = array_ptr;
                                        array_ptr = Z_REFVAL_P(array_ptr);
                                }
-                       } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) {
-                               zval_copy_ctor(array_ptr);
                        }
                        if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref);
                } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) {