Let me know if I have any issues with my patch/thinking here:
Reproduce code:
<?php
$x = "a";
$x['x']['y'] += 1;
?>
The zend_binary_assign_op_helper_* function isn't checking that the
value returned from _get_zval_ptr_ptr_var is set, so it faults
instead of letting zend_fetch_dimension_address trigger the "Cannot
use string offset as an array" error.
patch:
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.39
diff -u -r1.59.2.29.2.39 zend_vm_def.h
--- Zend/zend_vm_def.h 25 Feb 2007 16:02:43 -0000 1.59.2.29.2.39
+++ Zend/zend_vm_def.h 8 Mar 2007 02:39:02 -0000
@@ -408,11 +408,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
- if (OP1_TYPE != IS_CV && !OP1_FREE) {
+ if (object_ptr && OP1_TYPE != IS_CV &&
!OP1_FREE) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper,
binary_op, binary_op);
} else {
zend_op *op_data = opline+1;
Index: Zend/zend_vm_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
retrieving revision 1.62.2.30.2.39
diff -u -r1.62.2.30.2.39 zend_vm_execute.h
--- Zend/zend_vm_execute.h 25 Feb 2007 16:02:43 -0000 1.62.2.30.2.39
+++ Zend/zend_vm_execute.h 8 Mar 2007 02:39:03 -0000
@@ -8583,11 +8583,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
- if (IS_VAR != IS_CV && !(free_op1.var != NULL))
{
+ if (object_ptr && IS_VAR != IS_CV &&
!(free_op1.var != NULL)) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -10067,11 +10067,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
- if (IS_VAR != IS_CV && !(free_op1.var != NULL))
{
+ if (object_ptr && IS_VAR != IS_CV &&
!(free_op1.var != NULL)) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -11555,11 +11555,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
- if (IS_VAR != IS_CV && !(free_op1.var != NULL))
{
+ if (object_ptr && IS_VAR != IS_CV &&
!(free_op1.var != NULL)) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -12847,11 +12847,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
- if (IS_VAR != IS_CV && !(free_op1.var != NULL))
{
+ if (object_ptr && IS_VAR != IS_CV &&
!(free_op1.var != NULL)) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -13516,11 +13516,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
- if (IS_VAR != IS_CV && !(free_op1.var != NULL))
{
+ if (object_ptr && IS_VAR != IS_CV &&
!(free_op1.var != NULL)) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -14882,11 +14882,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
_get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (IS_UNUSED != IS_CV && !0) {
+ if (object_ptr && IS_UNUSED != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -15885,11 +15885,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
_get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (IS_UNUSED != IS_CV && !0) {
+ if (object_ptr && IS_UNUSED != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -16849,11 +16849,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
_get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (IS_UNUSED != IS_CV && !0) {
+ if (object_ptr && IS_UNUSED != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -17813,11 +17813,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
_get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (IS_UNUSED != IS_CV && !0) {
+ if (object_ptr && IS_UNUSED != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -18079,11 +18079,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr =
_get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (IS_UNUSED != IS_CV && !0) {
+ if (object_ptr && IS_UNUSED != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -20495,11 +20495,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
BP_VAR_W TSRMLS_CC);
- if (IS_CV != IS_CV && !0) {
+ if (object_ptr && IS_CV != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -21971,11 +21971,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
BP_VAR_W TSRMLS_CC);
- if (IS_CV != IS_CV && !0) {
+ if (object_ptr && IS_CV != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -23451,11 +23451,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
BP_VAR_W TSRMLS_CC);
- if (IS_CV != IS_CV && !0) {
+ if (object_ptr && IS_CV != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -24734,11 +24734,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
BP_VAR_W TSRMLS_CC);
- if (IS_CV != IS_CV && !0) {
+ if (object_ptr && IS_CV != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
@@ -25402,11 +25402,11 @@
case ZEND_ASSIGN_DIM: {
zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),
BP_VAR_W TSRMLS_CC);
- if (IS_CV != IS_CV && !0) {
+ if (object_ptr && IS_CV != IS_CV && !0) {
(*object_ptr)->refcount++; /* undo the effect of
get_obj_zval_ptr_ptr() */
}
- if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (object_ptr && Z_TYPE_PP(object_ptr) ==
IS_OBJECT) {
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
- Shire
[EMAIL PROTECTED]
[EMAIL PROTECTED]
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php