From e919caca86d78a25d4de10d2df2e1c4357ac4408 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 9 Oct 2014 12:02:42 +0200 Subject: [PATCH] Fix bug #68191: Broken reference across objects --- Zend/tests/bug68191.phpt | 21 +++++++++++++++++++ Zend/zend_vm_def.h | 3 ++- Zend/zend_vm_execute.h | 45 ++++++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 Zend/tests/bug68191.phpt diff --git a/Zend/tests/bug68191.phpt b/Zend/tests/bug68191.phpt new file mode 100644 index 00000000000..198c5c7dce1 --- /dev/null +++ b/Zend/tests/bug68191.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #68191: Broken reference across objects +--FILE-- +prop1 = 'abc'; +$obj->prop2 =& $obj->prop1; +$obj->prop2 .= 'xyz'; +var_dump($obj->prop1); + +$obj->prop3 = 1; +$obj->prop4 =& $obj->prop3; +++$obj->prop4; +var_dump($obj->prop3); + +?> +--EXPECT-- +string(6) "abcxyz" +int(2) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6aeac0e2d16..2948b2e1005 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -357,7 +357,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e68cf1945c5..fdbab5e2f97 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -17589,7 +17589,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -20025,7 +20026,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -22036,7 +22038,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -24141,7 +24144,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -25612,7 +25616,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -27481,7 +27486,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -28869,7 +28875,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -30175,7 +30182,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -31481,7 +31489,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -31997,7 +32006,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -34985,7 +34995,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -37253,7 +37264,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -39135,7 +39147,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -41110,7 +41123,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC); @@ -42436,7 +42450,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar && Z_OBJ_HT_P(object)->get_property_ptr_ptr) { zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC); if (zptr != NULL) { /* NULL means no success in getting PTR */ - SEPARATE_ZVAL_IF_NOT_REF(zptr); + ZVAL_DEREF(zptr); + SEPARATE_ZVAL_NOREF(zptr); have_get_ptr = 1; binary_op(zptr, zptr, value TSRMLS_CC);