Handle non-integer/string opcodes

This commit is contained in:
Andrea Faulds 2016-01-16 22:24:23 +00:00
parent e572d2d0ad
commit 0085884a61
4 changed files with 461 additions and 63 deletions

View file

@ -2753,10 +2753,6 @@ static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node
zend_compile_expr(&dim_node, key_ast);
zend_handle_numeric_op(&dim_node);
if (Z_TYPE(dim_node.u.constant) != IS_LONG && Z_TYPE(dim_node.u.constant) != IS_STRING) {
zend_error_noreturn(E_COMPILE_ERROR, "Key must be an integer or string literal");
}
if (expr_node->op_type == IS_CONST) {
Z_TRY_ADDREF(expr_node->u.constant);
}

View file

@ -2062,11 +2062,13 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR)
{
USE_OPLINE
zend_free_op free_op1;
zend_free_op free_op2;
zval *container;
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
@ -2074,31 +2076,61 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
ZEND_VM_C_LABEL(try_fetch_list):
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
zend_string *str;
zend_ulong hval;
ZEND_VM_C_LABEL(assign_again_list):
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
ZEND_VM_C_LABEL(num_index_list):
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
ZEND_VM_C_LABEL(str_index_list):
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
ZEND_VM_C_GOTO(assign_again_list);
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
ZEND_VM_C_GOTO(str_index_list);
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
ZEND_VM_C_GOTO(num_index_list);
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
ZEND_VM_C_GOTO(num_index_list);
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
ZEND_VM_C_GOTO(num_index_list);
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
zend_error(E_WARNING, "Illegal offset type");
}
} else if (OP1_TYPE != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
@ -2116,6 +2148,7 @@ ZEND_VM_C_LABEL(try_fetch_list):
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
FREE_OP2();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}

View file

@ -5746,7 +5746,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA
{
USE_OPLINE
zval *container;
zval *offset = EX_CONSTANT(opline->op2);
SAVE_OPLINE();
container = EX_CONSTANT(opline->op1);
@ -5754,31 +5756,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HA
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
zend_error(E_WARNING, "Illegal offset type");
}
} else if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
@ -5796,6 +5828,7 @@ try_fetch_list:
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@ -11323,6 +11356,96 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_
}
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2;
zval *container;
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
SAVE_OPLINE();
container = EX_CONSTANT(opline->op1);
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
zend_error(E_WARNING, "Illegal offset type");
}
} else if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
ZVAL_COPY(result, retval);
}
} else {
ZVAL_NULL(result);
}
} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
container = Z_REFVAL_P(container);
goto try_fetch_list;
} else {
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(container, BP_VAR_R);
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -37872,7 +37995,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
{
USE_OPLINE
zval *container;
zval *offset = EX_CONSTANT(opline->op2);
SAVE_OPLINE();
container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
@ -37880,31 +38005,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDL
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
zend_error(E_WARNING, "Illegal offset type");
}
} else if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
@ -37922,6 +38077,7 @@ try_fetch_list:
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@ -47819,6 +47975,96 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2;
zval *container;
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
SAVE_OPLINE();
container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
zend_error(E_WARNING, "Illegal offset type");
}
} else if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
ZVAL_COPY(result, retval);
}
} else {
ZVAL_NULL(result);
}
} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
container = Z_REFVAL_P(container);
goto try_fetch_list;
} else {
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(container, BP_VAR_R);
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -50936,7 +51182,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_
{
USE_OPLINE
zend_free_op free_op1;
zval *container;
zval *offset = EX_CONSTANT(opline->op2);
SAVE_OPLINE();
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
@ -51044,31 +51292,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_H
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
zend_error(E_WARNING, "Illegal offset type");
}
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
@ -51086,6 +51364,7 @@ try_fetch_list:
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
@ -54483,6 +54762,96 @@ fetch_obj_is_no_object:
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
zend_free_op free_op2;
zval *container;
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
SAVE_OPLINE();
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
try_fetch_list:
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value;
zend_string *str;
zend_ulong hval;
assign_again_list:
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
hval = Z_LVAL_P(offset);
num_index_list:
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
str = Z_STR_P(offset);
str_index_list:
value = zend_hash_find(Z_ARRVAL_P(container), str);
if (UNEXPECTED(value == NULL)) {
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
ZVAL_NULL(EX_VAR(opline->result.var));
} else {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
if (UNEXPECTED(str != Z_STR_P(offset))) {
zend_string_release(str);
}
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
offset = Z_REFVAL_P(offset);
goto assign_again_list;
} else if (Z_TYPE_P(offset) == IS_NULL) {
str = ZSTR_EMPTY_ALLOC();
goto str_index_list;
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
hval = zend_dval_to_lval(Z_DVAL_P(offset));
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_FALSE) {
hval = 0;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_TRUE) {
hval = 1;
goto num_index_list;
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
hval = Z_RES_HANDLE_P(offset);
} else {
zend_error(E_WARNING, "Illegal offset type");
}
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
zval *result = EX_VAR(opline->result.var);
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
if (retval) {
if (result != retval) {
ZVAL_COPY(result, retval);
}
} else {
ZVAL_NULL(result);
}
} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(container) == IS_REFERENCE) {
container = Z_REFVAL_P(container);
goto try_fetch_list;
} else {
if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(container, BP_VAR_R);
}
ZVAL_NULL(EX_VAR(opline->result.var));
}
zval_ptr_dtor_nogc(free_op2);
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@ -57534,18 +57903,18 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER,
ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER,
ZEND_FETCH_LIST_SPEC_CONST_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_FETCH_LIST_SPEC_TMPVAR_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@ -57554,8 +57923,8 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER,
ZEND_FETCH_LIST_SPEC_CV_TMPVAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,

View file

@ -307,7 +307,7 @@ static uint32_t zend_vm_opcodes_flags[184] = {
0x00010107,
0x00000701,
0x00000751,
0x00000307,
0x00000707,
0x06000301,
0x00000000,
0x00000000,