Browse Source

Fixed bug #47704 (PHP crashes on some "bad" operations with string offsets)

PHP-5.2.1RC1
Dmitry Stogov 18 years ago
parent
commit
9e48089f65
  1. 2
      NEWS
  2. 9
      Zend/tests/bug47704.phpt
  3. 12
      Zend/zend_vm_def.h
  4. 156
      Zend/zend_vm_execute.h

2
NEWS

@ -6,6 +6,8 @@ PHP NEWS
- Fixed memory corruptions while reading properties of zip files. (Ilia)
- Fixed bug #47704 (PHP crashes on some "bad" operations with string offsets).
(Dmitry)
- Fixed bug #47667 (ZipArchive::OVERWRITE seems to have no effect). (Mikko, Pierre)
- Fixed bug #47644 (Valid integers are truncated with json_decode()). (Scott)
- Fixed bug #47639 (pg_copy_from() WARNING: nonstandard use of \\ in a string

9
Zend/tests/bug47704.phpt

@ -0,0 +1,9 @@
--TEST--
Bug #47704 (crashes on some "bad" operations with string offsets)
--FILE--
<?php
$s = "abd";
$s[0]->a += 1;
?>
--EXPECTF--
Fatal error: Cannot use string offset as an object in %sbug47704.php on line %d

12
Zend/zend_vm_def.h

@ -294,6 +294,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (OP1_TYPE == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -545,6 +549,10 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (OP1_TYPE == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -637,6 +645,10 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (OP1_TYPE == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;

156
Zend/zend_vm_execute.h

@ -8553,6 +8553,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -8803,6 +8807,10 @@ static int zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op, ZE
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -8895,6 +8903,10 @@ static int zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_t incdec_op, Z
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -10070,6 +10082,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -10321,6 +10337,10 @@ static int zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t incdec_op, ZEND
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -10413,6 +10433,10 @@ static int zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t incdec_op, ZEN
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -11591,6 +11615,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -11842,6 +11870,10 @@ static int zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t incdec_op, ZEND
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -11934,6 +11966,10 @@ static int zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t incdec_op, ZEN
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -12926,6 +12962,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zva
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -13607,6 +13647,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *r
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -13857,6 +13901,10 @@ static int zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op, ZEND_
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -13949,6 +13997,10 @@ static int zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t incdec_op, ZEND
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -15017,6 +15069,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(z
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -15266,6 +15322,10 @@ static int zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op,
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -15358,6 +15418,10 @@ static int zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incdec_t incdec_op
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -16041,6 +16105,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zva
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -16291,6 +16359,10 @@ static int zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_t incdec_op, Z
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -16383,6 +16455,10 @@ static int zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec_t incdec_op,
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -17022,6 +17098,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zva
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -17272,6 +17352,10 @@ static int zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_t incdec_op, Z
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -17364,6 +17448,10 @@ static int zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec_t incdec_op,
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -18003,6 +18091,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -18269,6 +18361,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -18518,6 +18614,10 @@ static int zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op, ZE
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -18610,6 +18710,10 @@ static int zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_t incdec_op, Z
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -20711,6 +20815,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -20960,6 +21068,10 @@ static int zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op, ZEN
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -21052,6 +21164,10 @@ static int zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t incdec_op, ZE
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -22220,6 +22336,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *r
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -22470,6 +22590,10 @@ static int zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t incdec_op, ZEND_
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -22562,6 +22686,10 @@ static int zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t incdec_op, ZEND
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -23733,6 +23861,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *r
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -23983,6 +24115,10 @@ static int zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t incdec_op, ZEND_
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -24075,6 +24211,10 @@ static int zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t incdec_op, ZEND
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -25059,6 +25199,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -25739,6 +25883,10 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *re
zval **retval = &EX_T(result->u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@ -25988,6 +26136,10 @@ static int zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op, ZEND_O
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@ -26080,6 +26232,10 @@ static int zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t incdec_op, ZEND_
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
if (IS_CV == IS_VAR && !object_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;

Loading…
Cancel
Save