From: Nikita Popov Date: Sun, 12 Oct 2014 18:39:07 +0000 (+0200) Subject: Fix incdec of referenced properties X-Git-Tag: POST_NATIVE_TLS_MERGE^2~75^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7e139a59ca7962c98ce1eb75150dd131978b41d;p=php Fix incdec of referenced properties I thought these SEPARATE_ZVAL_IF_NOT_REF usages were safe at first, because incdec op supports reference variables. However this violates the constraint that IS_TMP_VAR variables may not be references (which is an issue if you use the result of the incdec op). Still need to fix the cases where read_property/write_property is used. --- diff --git a/.gdbinit b/.gdbinit index 98bb173a5a..498099a411 100644 --- a/.gdbinit +++ b/.gdbinit @@ -53,11 +53,11 @@ define dump_bt printf "[%p] ", $ex set $func = $ex->func if $func - if $ex->object + if $ex->This->value.obj if $func->common.scope printf "%s->", $func->common.scope->name->val else - printf "%s->", $ex->object->ce.name->val + printf "%s->", $ex->This->value.obj->ce.name->val end else if $func->common.scope diff --git a/Zend/tests/incdec_ref_property.phpt b/Zend/tests/incdec_ref_property.phpt new file mode 100644 index 0000000000..a73b2912ab --- /dev/null +++ b/Zend/tests/incdec_ref_property.phpt @@ -0,0 +1,27 @@ +--TEST-- +Incrementing and decrementing a referenced property +--FILE-- +prop = 1; +$ref =& $obj->prop; +var_dump(++$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop++); +var_dump($obj->prop); +var_dump(--$obj->prop); +var_dump($obj->prop); +var_dump($obj->prop--); +var_dump($obj->prop); + +?> +--EXPECT-- +int(2) +int(2) +int(2) +int(3) +int(2) +int(2) +int(2) +int(1) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 736ce178d6..091b384c33 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -719,7 +719,8 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR| if (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; incdec_op(zptr); @@ -812,12 +813,11 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index af0cd96bbf..9f8be5ceb0 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -17918,7 +17918,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t if (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; incdec_op(zptr); @@ -18010,12 +18011,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -20356,7 +20356,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i if (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; incdec_op(zptr); @@ -20449,12 +20450,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -22368,7 +22368,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (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; incdec_op(zptr); @@ -22461,12 +22462,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -25946,7 +25946,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in if (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; incdec_op(zptr); @@ -26038,12 +26039,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -27815,7 +27815,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde if (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; incdec_op(zptr); @@ -27907,12 +27908,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -29206,7 +29206,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ if (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; incdec_op(zptr); @@ -29299,12 +29300,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -30514,7 +30514,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (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; incdec_op(zptr); @@ -30607,12 +30608,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -32340,7 +32340,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t if (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; incdec_op(zptr); @@ -32432,12 +32433,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -35321,7 +35321,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t if (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; incdec_op(zptr); @@ -35413,12 +35414,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -37592,7 +37592,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in if (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; incdec_op(zptr); @@ -37685,12 +37686,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -39476,7 +39476,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (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; incdec_op(zptr); @@ -39569,12 +39570,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } } @@ -42781,7 +42781,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc if (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; incdec_op(zptr); @@ -42873,12 +42874,11 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in 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 */ have_get_ptr = 1; - SEPARATE_ZVAL_IF_NOT_REF(zptr); - - ZVAL_DUP(retval, zptr); + ZVAL_DEREF(zptr); + ZVAL_COPY(retval, zptr); + SEPARATE_ZVAL_NOREF(zptr); incdec_op(zptr); - } }