Skip to content

Commit 0085884

Browse files
Handle non-integer/string opcodes
1 parent e572d2d commit 0085884

File tree

4 files changed

+441
-43
lines changed

4 files changed

+441
-43
lines changed

Zend/zend_compile.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,10 +2753,6 @@ static void zend_compile_keyed_list_assign(zend_ast_list *list, znode *expr_node
27532753
zend_compile_expr(&dim_node, key_ast);
27542754
zend_handle_numeric_op(&dim_node);
27552755

2756-
if (Z_TYPE(dim_node.u.constant) != IS_LONG && Z_TYPE(dim_node.u.constant) != IS_STRING) {
2757-
zend_error_noreturn(E_COMPILE_ERROR, "Key must be an integer or string literal");
2758-
}
2759-
27602756
if (expr_node->op_type == IS_CONST) {
27612757
Z_TRY_ADDREF(expr_node->u.constant);
27622758
}

Zend/zend_vm_def.h

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,43 +2062,75 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV)
20622062
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
20632063
}
20642064

2065-
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST)
2065+
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMPVAR|CV, CONST|TMPVAR)
20662066
{
20672067
USE_OPLINE
20682068
zend_free_op free_op1;
2069+
zend_free_op free_op2;
20692070
zval *container;
2071+
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
20702072

20712073
SAVE_OPLINE();
20722074
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
20732075

20742076
ZEND_VM_C_LABEL(try_fetch_list):
20752077
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
20762078
zval *value;
2077-
2078-
if (Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_LONG) {
2079-
value = zend_hash_index_find(Z_ARRVAL_P(container), Z_LVAL_P(EX_CONSTANT(opline->op2)));
2079+
zend_string *str;
2080+
zend_ulong hval;
2081+
2082+
ZEND_VM_C_LABEL(assign_again_list):
2083+
if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) {
2084+
hval = Z_LVAL_P(offset);
2085+
ZEND_VM_C_LABEL(num_index_list):
2086+
value = zend_hash_index_find(Z_ARRVAL_P(container), hval);
20802087

20812088
if (UNEXPECTED(value == NULL)) {
2082-
zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, Z_LVAL_P(EX_CONSTANT(opline->op2)));
2089+
zend_error(E_NOTICE, "Undefined offset: " ZEND_ULONG_FMT, hval);
20832090
ZVAL_NULL(EX_VAR(opline->result.var));
20842091
} else {
20852092
ZVAL_COPY(EX_VAR(opline->result.var), value);
20862093
}
2087-
} else {
2088-
value = zend_hash_find(Z_ARRVAL_P(container), Z_STR_P(EX_CONSTANT(opline->op2)));
2094+
} else if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) {
2095+
str = Z_STR_P(offset);
2096+
ZEND_VM_C_LABEL(str_index_list):
2097+
value = zend_hash_find(Z_ARRVAL_P(container), str);
20892098

20902099
if (UNEXPECTED(value == NULL)) {
2091-
zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
2100+
zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(str));
20922101
ZVAL_NULL(EX_VAR(opline->result.var));
20932102
} else {
20942103
ZVAL_COPY(EX_VAR(opline->result.var), value);
20952104
}
2105+
if (UNEXPECTED(str != Z_STR_P(offset))) {
2106+
zend_string_release(str);
2107+
}
2108+
} else if (EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) {
2109+
offset = Z_REFVAL_P(offset);
2110+
ZEND_VM_C_GOTO(assign_again_list);
2111+
} else if (Z_TYPE_P(offset) == IS_NULL) {
2112+
str = ZSTR_EMPTY_ALLOC();
2113+
ZEND_VM_C_GOTO(str_index_list);
2114+
} else if (Z_TYPE_P(offset) == IS_DOUBLE) {
2115+
hval = zend_dval_to_lval(Z_DVAL_P(offset));
2116+
ZEND_VM_C_GOTO(num_index_list);
2117+
} else if (Z_TYPE_P(offset) == IS_FALSE) {
2118+
hval = 0;
2119+
ZEND_VM_C_GOTO(num_index_list);
2120+
} else if (Z_TYPE_P(offset) == IS_TRUE) {
2121+
hval = 1;
2122+
ZEND_VM_C_GOTO(num_index_list);
2123+
} else if (Z_TYPE_P(offset) == IS_RESOURCE) {
2124+
zend_error(E_NOTICE, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
2125+
hval = Z_RES_HANDLE_P(offset);
2126+
} else {
2127+
zend_error(E_WARNING, "Illegal offset type");
20962128
}
20972129
} else if (OP1_TYPE != IS_CONST &&
20982130
UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
20992131
EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
21002132
zval *result = EX_VAR(opline->result.var);
2101-
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, EX_CONSTANT(opline->op2), BP_VAR_R, result);
2133+
zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, offset, BP_VAR_R, result);
21022134

21032135
if (retval) {
21042136
if (result != retval) {
@@ -2116,6 +2148,7 @@ ZEND_VM_C_LABEL(try_fetch_list):
21162148
}
21172149
ZVAL_NULL(EX_VAR(opline->result.var));
21182150
}
2151+
FREE_OP2();
21192152
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
21202153
}
21212154

0 commit comments

Comments
 (0)