fix 64 bit string index usage

This commit is contained in:
Anatol Belski 2014-09-07 00:54:47 +02:00
parent f4f9b54983
commit acad6f4700
4 changed files with 293 additions and 98 deletions

View file

@ -755,17 +755,46 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
FREE_OP_IF_VAR(free_value);
}
static void zend_assign_to_string_offset(zval *str_offset, zval *value, int value_type, zval *result TSRMLS_DC)
static zend_always_inline zend_long zend_fetch_dimension_str_offset(zval *dim, int type TSRMLS_DC)
{
zend_long offset;
if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
switch(Z_TYPE_P(dim)) {
case IS_STRING:
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
break;
}
if (type != BP_VAR_UNSET) {
zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
}
break;
case IS_DOUBLE:
case IS_NULL:
case IS_FALSE:
case IS_TRUE:
zend_error(E_NOTICE, "String offset cast occurred");
break;
default:
zend_error(E_WARNING, "Illegal offset type");
break;
}
offset = zval_get_long(dim);
} else {
offset = Z_LVAL_P(dim);
}
return offset;
}
static void zend_assign_to_string_offset(zval *str_offset, zend_long offset, zval *value, int value_type, zval *result TSRMLS_DC)
{
zval *str = Z_STR_OFFSET_STR_P(str_offset);
/* XXX String offset is uint32_t in _zval_struct, so can address only 2^32+1 space.
To make the offset get over that barier, we need to make str_offset size_t and that
would grow zval size by 8 bytes (currently from 16 to 24) on 64 bit build. */
uint32_t offset = Z_STR_OFFSET_IDX_P(str_offset);
zend_string *old_str;
if ((int)offset < 0) {
zend_error(E_WARNING, "Illegal string offset: %d", offset);
if (offset < 0) {
zend_error(E_WARNING, "Illegal string offset: " ZEND_LONG_FMT, offset);
zend_string_release(Z_STR_P(str));
if (result) {
ZVAL_NULL(result);
@ -775,7 +804,7 @@ static void zend_assign_to_string_offset(zval *str_offset, zval *value, int valu
old_str = Z_STR_P(str);
if (offset >= Z_STRLEN_P(str)) {
int old_len = Z_STRLEN_P(str);
zend_long old_len = Z_STRLEN_P(str);
Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), offset + 1, 0);
Z_TYPE_INFO_P(str) = IS_STRING_EX;
memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
@ -1141,6 +1170,7 @@ convert_to_array:
zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
goto fetch_from_array;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
@ -1149,34 +1179,13 @@ convert_to_array:
SEPARATE_STRING(container);
}
if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
switch(Z_TYPE_P(dim)) {
case IS_STRING:
if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
break;
}
if (type != BP_VAR_UNSET) {
zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
}
break;
case IS_DOUBLE:
case IS_NULL:
case IS_FALSE:
case IS_TRUE:
zend_error(E_NOTICE, "String offset cast occurred");
break;
default:
zend_error(E_WARNING, "Illegal offset type");
break;
}
offset = zval_get_long(dim);
} else {
offset = Z_LVAL_P(dim);
}
/* This is a dummy, the offset is broken if we're here.
What matters is merely the IS_STR_OFFSET type set below.*/
offset = zend_fetch_dimension_str_offset(dim, type TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(container))) zend_string_addref(Z_STR_P(container));
ZVAL_STR_OFFSET(result, container, offset);
} else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (!Z_OBJ_HT_P(container)->read_dimension) {
zend_error_noreturn(E_ERROR, "Cannot use object as array");

View file

@ -131,7 +131,6 @@ struct _zval_struct {
union {
uint32_t var_flags;
uint32_t next; /* hash collision chain */
uint32_t str_offset; /* string offset */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t silence_num; /* BEGIN_SILENCE op number */
@ -656,12 +655,8 @@ static inline zend_uchar zval_get_type(const zval* pz) {
#define Z_STR_OFFSET_STR(zval) Z_INDIRECT(zval)
#define Z_STR_OFFSET_STR_P(zval_p) Z_STR_OFFSET_STR(*(zval_p))
#define Z_STR_OFFSET_IDX(zval) (zval).u2.str_offset
#define Z_STR_OFFSET_IDX_P(zval_p) Z_STR_OFFSET_IDX(*(zval_p))
#define ZVAL_STR_OFFSET(z, s, i) do { \
Z_STR_OFFSET_STR_P(z) = (s); \
Z_STR_OFFSET_IDX_P(z) = (i); \
Z_TYPE_INFO_P(z) = IS_STR_OFFSET; \
} while (0)

View file

@ -1635,15 +1635,34 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
}
FREE_OP2();
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -1685,9 +1704,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
value = GET_OP2_ZVAL_PTR(BP_VAR_R);
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, OP2_TYPE, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_OP2_TMP_FREE()) {
zval_dtor(value);
}

View file

@ -18345,14 +18345,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -18394,9 +18413,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
value = opline->op2.zv;
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_CONST, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}
@ -20584,15 +20601,34 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
}
zval_dtor(free_op2.var);
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -20634,9 +20670,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_TMP_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (1) {
zval_dtor(value);
}
@ -22732,15 +22766,34 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
}
zval_ptr_dtor_nogc(free_op2.var);
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -22782,9 +22835,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}
@ -24388,14 +24439,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -26129,14 +26199,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -26178,9 +26267,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_CV, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}
@ -35598,14 +35685,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -35647,9 +35753,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
value = opline->op2.zv;
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_CONST, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}
@ -37651,15 +37755,34 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
}
zval_dtor(free_op2.var);
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -37701,9 +37824,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_TMP_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (1) {
zval_dtor(value);
}
@ -39680,15 +39801,34 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
}
zval_ptr_dtor_nogc(free_op2.var);
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -39730,9 +39870,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}
@ -41216,14 +41354,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -42821,14 +42978,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_free_op free_op_data1, free_op_data2;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
zval *variable_ptr = EX_VAR((opline+1)->op2.var);
zend_long offset = 0;
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (UNEXPECTED(Z_STRLEN_P(object_ptr) == 0)) {
goto string_failed;
}
if (dim == NULL) {
zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
}
SEPARATE_STRING(object_ptr);
offset = zend_fetch_dimension_str_offset(dim, BP_VAR_W TSRMLS_CC);
if (!IS_INTERNED(Z_STR_P(object_ptr))) zend_string_addref(Z_STR_P(object_ptr));
ZVAL_STR_OFFSET(variable_ptr, object_ptr, offset);
} else {
string_failed:
zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
}
value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
zend_assign_to_string_offset(variable_ptr, offset, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_TMP_FREE(free_op_data1)) {
zval_dtor(value);
@ -42870,9 +43046,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) {
zend_assign_to_string_offset(variable_ptr, value, IS_CV, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
} else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
if (0) {
zval_dtor(value);
}