]> granicus.if.org Git - php/commitdiff
Fixed bug #47704 (PHP crashes on some "bad" operations with string offsets)
authorDmitry Stogov <dmitry@php.net>
Wed, 18 Mar 2009 13:11:32 +0000 (13:11 +0000)
committerDmitry Stogov <dmitry@php.net>
Wed, 18 Mar 2009 13:11:32 +0000 (13:11 +0000)
NEWS
Zend/tests/bug47704.phpt [new file with mode: 0644]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 20c212683f955beafcbf386c18f8b72aa32ed973..80f6254021e5cc4201790e62545eed616ecdc29f 100644 (file)
--- a/NEWS
+++ b/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
diff --git a/Zend/tests/bug47704.phpt b/Zend/tests/bug47704.phpt
new file mode 100644 (file)
index 0000000..151754a
--- /dev/null
@@ -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
index 54064509c3a1928df219ba1aa9b93d7603b132cb..e00b41765923ade1657d1c093d2841605e79549f 100644 (file)
@@ -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;
 
index 50176ad13a294db66e8b18e6f71450a3dba85f58..8a7d89917b5cf7b163026ffd317734f31cd4e8a9 100644 (file)
@@ -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;