]> granicus.if.org Git - php/commitdiff
Fixed ZEND_IN_ARRAY related issues
authorDmitry Stogov <dmitry@zend.com>
Thu, 25 May 2017 07:26:42 +0000 (10:26 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 25 May 2017 07:26:42 +0000 (10:26 +0300)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index a35e2acc7b099ef2bef8da6f98d4046b93cec1df..0a368a4a4bf2885635f596206bba455bd7b9d8df 100644 (file)
@@ -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;
index 66c4933066df52c64ff2c4afd6313383e1548ef5..b1888cc85705833e38f0f76082ea12a8fbc516df 100644 (file)
@@ -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))
index 832add01c4c6ceaf286595ec3b55841777de5dff..4be3872bcefddba00b032ad69826769f69e42f30 100644 (file)
@@ -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)