Skip to content

Commit

Permalink
Fix incdec of referenced properties
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Oct 12, 2014
1 parent 016a96c commit b7e139a
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 67 deletions.
4 changes: 2 additions & 2 deletions .gdbinit
Expand Up @@ -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
Expand Down
27 changes: 27 additions & 0 deletions Zend/tests/incdec_ref_property.phpt
@@ -0,0 +1,27 @@
--TEST--
Incrementing and decrementing a referenced property
--FILE--
<?php

$obj = new stdClass;
$obj->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)
10 changes: 5 additions & 5 deletions Zend/zend_vm_def.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down
120 changes: 60 additions & 60 deletions Zend/zend_vm_execute.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

}
}

Expand Down

0 comments on commit b7e139a

Please sign in to comment.