mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
fix 64 bit string index usage
This commit is contained in:
parent
f4f9b54983
commit
acad6f4700
4 changed files with 293 additions and 98 deletions
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue