com php-src: Fixed ZEND_IN_ARRAY related issues: Ze nd/zend_compile.c Zend/zend_vm_def.h Zend/zend_ vm_execute.h
[email protected] (Dmitry Stogov)
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: 44ec732752a99334985759a569814bab05d95051 Author: Dmitry Stogov <[email protected]> Thu, 25 May 2017 10:26:42 +0300 Parents: 13ee8fd626accebd93f943d2d1d23a6e952e060f Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=44ec732752a99334985759a569814bab05d95051 Log: Fixed ZEND_IN_ARRAY related issues Changed paths: M Zend/zend_compile.c M Zend/zend_vm_def.h M Zend/zend_vm_execute.h
diff_44ec732752a99334985759a569814bab05d95051.txt
(text/plain, 9.2 KB)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index a35e2ac..0a368a4 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 66c4933..b1888cc 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 832add0..4be3872 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)