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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.