]> granicus.if.org Git - php/commitdiff
Fixed wrong result of cascading assignment to string offset
authorDmitry Stogov <dmitry@php.net>
Tue, 4 Mar 2008 10:06:22 +0000 (10:06 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 4 Mar 2008 10:06:22 +0000 (10:06 +0000)
Fixed memory corruption on cascading assignment of IS_TMP_VAR into string offset
Fixed opcode caches shared memory corruption on cascading assignment of IS_CONST into string offset

Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 5115c7b9fed749374112ed2a8656175ccb753469..66a7bb7030b72bcbb9b1b56b899f21f4540f0c9d 100644 (file)
@@ -652,7 +652,7 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval
 }
 /* }}} */
 
-static inline void zend_assign_to_string_offset(temp_variable *T, zval *value, int value_type TSRMLS_DC) /* {{{ */
+static inline int zend_assign_to_string_offset(temp_variable *T, zval *value, int value_type TSRMLS_DC) /* {{{ */
 {
        if (UG(unicode) && Z_TYPE_P(T->str_offset.str) == IS_STRING && Z_TYPE_P(value) != IS_STRING) {
                convert_to_unicode(T->str_offset.str);
@@ -662,7 +662,7 @@ static inline void zend_assign_to_string_offset(temp_variable *T, zval *value, i
 
                if (((int)T->str_offset.offset < 0)) {
                        zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
-                       return;
+                       return 0;
                }
 
                if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
@@ -699,7 +699,7 @@ static inline void zend_assign_to_string_offset(temp_variable *T, zval *value, i
 
                if (((int)T->str_offset.offset < 0)) {
                        zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
-                       return;
+                       return 0;
                }
 
                if (T->str_offset.offset >= Z_USTRLEN_P(T->str_offset.str)) {
@@ -729,6 +729,7 @@ static inline void zend_assign_to_string_offset(temp_variable *T, zval *value, i
                        }
                }
        }
+       return 1;
 }
 /* }}} */
 
index 974a956a7a4248fa3c18328e30c4146df2dc9452..a424647150de4f99a86cf8a4f75af65cc0fc85e4 100644 (file)
@@ -1586,13 +1586,23 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -1611,14 +1621,23 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
        zval **variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, OP2_TYPE TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, OP2_TYPE TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, IS_OP2_TMP_FREE() TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        FREE_OP1_VAR_PTR();
index 684c77c19cd8a291a806b57bd355939e90e0815a..72d091d5235686b6c52e54feb38493377b0a676d 100644 (file)
@@ -10167,13 +10167,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -10192,14 +10202,23 @@ static int ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12035,13 +12054,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -12060,14 +12089,23 @@ static int ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 1 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13833,13 +13871,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -13858,14 +13906,23 @@ static int ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -14904,13 +14961,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -16271,13 +16338,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -16296,14 +16373,23 @@ static int ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -24175,13 +24261,23 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -24200,14 +24296,23 @@ static int ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -25860,13 +25965,23 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -25885,14 +26000,23 @@ static int ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 1 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -27547,13 +27671,23 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -27572,14 +27706,23 @@ static int ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -28509,13 +28652,23 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -29772,13 +29925,23 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
                variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                if (!variable_ptr_ptr) {
-                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+                       if (zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC)) {
+                               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                                       ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                                       ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(op_data->op2.u.var).str_offset.str)+EX_T(op_data->op2.u.var).str_offset.offset, 1, 1);
+                               }
+                       } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
                } else {
                        value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
-               }
-               if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-                       PZVAL_LOCK(value);
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                               PZVAL_LOCK(value);
+                       }
                }
                FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
@@ -29797,14 +29960,23 @@ static int ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
 
        if (!variable_ptr_ptr) {
-               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC);
+               if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC)) {
+                       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                               ALLOC_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                               INIT_PZVAL(EX_T(opline->result.u.var).var.ptr);
+                               ZVAL_STRINGL(EX_T(opline->result.u.var).var.ptr, Z_STRVAL_P(EX_T(opline->op1.u.var).str_offset.str)+EX_T(opline->op1.u.var).str_offset.offset, 1, 1);
+                       }
+               } else if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
-       }
-
-       if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
-               PZVAL_LOCK(value);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
        }
 
        /* zend_assign_to_variable() always takes care of op2, never free it! */