From: Dmitry Stogov Date: Thu, 25 May 2017 07:26:42 +0000 (+0300) Subject: Fixed ZEND_IN_ARRAY related issues X-Git-Tag: php-7.2.0alpha1~57^2~31 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=44ec732752a99334985759a569814bab05d95051;p=php Fixed ZEND_IN_ARRAY related issues --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a35e2acc7b..0a368a4a4b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3644,15 +3644,31 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ zend_op *opline; if (args->children == 3) { - if (args->child[2]->kind != ZEND_AST_ZVAL) { + if (args->child[2]->kind == ZEND_AST_ZVAL) { + strict = zend_is_true(zend_ast_get_zval(args->child[2])); + } else if (args->child[2]->kind == ZEND_AST_CONST) { + zval value; + zend_ast *name_ast = args->child[2]->child[0]; + zend_bool is_fully_qualified; + zend_string *resolved_name = zend_resolve_const_name( + zend_ast_get_str(name_ast), name_ast->attr, &is_fully_qualified); + + if (!zend_try_ct_eval_const(&value, resolved_name, is_fully_qualified)) { + zend_string_release(resolved_name); + return FAILURE; + } + + zend_string_release(resolved_name); + strict = zend_is_true(&value); + zval_ptr_dtor(&value); + } else { return FAILURE; } - strict = zend_is_true(zend_ast_get_zval(args->child[2])); + } else if (args->children != 2) { + return FAILURE; } - if (args->children < 2 - || args->children > 3 - || args->child[1]->kind != ZEND_AST_ARRAY + if (args->child[1]->kind != ZEND_AST_ARRAY || !zend_try_ct_eval_array(&array.u.constant, args->child[1])) { return FAILURE; } @@ -3660,7 +3676,6 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ if (zend_hash_num_elements(Z_ARRVAL(array.u.constant)) > 0) { zend_bool ok = 1; zval *val, tmp; - zend_ulong idx; HashTable *src = Z_ARRVAL(array.u.constant); HashTable *dst = emalloc(sizeof(HashTable)); @@ -3681,7 +3696,8 @@ static int zend_compile_func_in_array(znode *result, zend_ast_list *args) /* {{{ } ZEND_HASH_FOREACH_END(); } else { ZEND_HASH_FOREACH_VAL(src, val) { - if (Z_TYPE_P(val) != IS_STRING || ZEND_HANDLE_NUMERIC(Z_STR_P(val), idx)) { + if (Z_TYPE_P(val) != IS_STRING + || is_numeric_string(Z_STRVAL_P(val), Z_STRLEN_P(val), NULL, NULL, 0)) { zend_array_destroy(dst); ok = 0; break; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 66c4933066..b1888cc857 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8106,10 +8106,12 @@ ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) { USE_OPLINE zend_free_op free_op1; - zval *op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + zval *op1; HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); int result; + SAVE_OPLINE(); + op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -8125,7 +8127,6 @@ ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) zval tmp; result = 0; - SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&tmp, key); compare_function(&tmp, op1, &tmp); @@ -8134,15 +8135,11 @@ ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) break; } } ZEND_HASH_FOREACH_END(); - FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE)) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 832add01c4..4be3872bce 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6423,10 +6423,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HAND { USE_OPLINE - zval *op1 = EX_CONSTANT(opline->op1); + zval *op1; HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); int result; + SAVE_OPLINE(); + op1 = EX_CONSTANT(opline->op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -6442,7 +6444,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HAND zval tmp; result = 0; - SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&tmp, key); compare_function(&tmp, op1, &tmp); @@ -6451,15 +6452,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HAND break; } } ZEND_HASH_FOREACH_END(); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -13815,10 +13812,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE { USE_OPLINE zend_free_op free_op1; - zval *op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zval *op1; HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); int result; + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -13834,7 +13833,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE zval tmp; result = 0; - SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&tmp, key); compare_function(&tmp, op1, &tmp); @@ -13843,15 +13841,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE break; } } ZEND_HASH_FOREACH_END(); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19947,10 +19941,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE { USE_OPLINE zend_free_op free_op1; - zval *op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + zval *op1; HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); int result; + SAVE_OPLINE(); + op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -19966,7 +19962,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE zval tmp; result = 0; - SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&tmp, key); compare_function(&tmp, op1, &tmp); @@ -19975,15 +19970,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE break; } } ZEND_HASH_FOREACH_END(); - zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } zval_ptr_dtor_nogc(free_op1); - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -38331,10 +38322,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER { USE_OPLINE - zval *op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); + zval *op1; HashTable *ht = Z_ARRVAL_P(EX_CONSTANT(opline->op2)); int result; + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_exists(ht, Z_STR_P(op1)); } else if (opline->extended_value) { @@ -38350,7 +38343,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER zval tmp; result = 0; - SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY(ht, key) { ZVAL_STR(&tmp, key); compare_function(&tmp, op1, &tmp); @@ -38359,15 +38351,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER break; } } ZEND_HASH_FOREACH_END(); - - ZEND_VM_SMART_BRANCH(result, 1); - ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); ZVAL_BOOL(EX_VAR(opline->result.var), result); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)