From ecb67e59d70da30b58e032c88ac8365bddd03a35 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 19 Jul 2017 01:04:36 +0200 Subject: [PATCH] Don't reuse compare_function operands If the same zval is used for the result and one operand, then the function thinks it is responsible for freeing the value in case of a type conversion. --- Zend/zend_vm_def.h | 8 ++++---- Zend/zend_vm_execute.h | 32 ++++++++++++++++---------------- ext/opcache/Optimizer/sccp.c | 10 +++++----- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6c5f5a2790..df80e0874a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8050,13 +8050,13 @@ ZEND_VM_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM) result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; result = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { result = 1; break; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 202d208d0b..99f270e02b 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -6422,13 +6422,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CONST_CONST_HAND result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; result = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { result = 1; break; } @@ -13847,13 +13847,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; result = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { result = 1; break; } @@ -19909,13 +19909,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; result = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { result = 1; break; } @@ -38265,13 +38265,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER result = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; result = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { result = 1; break; } diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 14ea6af99e..cd74ea41e3 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -475,13 +475,13 @@ static inline int ct_eval_in_array(zval *result, uint32_t extended_value, zval * res = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC()); } else { zend_string *key; - zval tmp; + zval key_tmp, result_tmp; res = 0; ZEND_HASH_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&tmp, key); - compare_function(&tmp, op1, &tmp); - if (Z_LVAL(tmp) == 0) { + ZVAL_STR(&key_tmp, key); + compare_function(&result_tmp, op1, &key_tmp); + if (Z_LVAL(result_tmp) == 0) { res = 1; break; } @@ -614,7 +614,7 @@ static inline int ct_eval_func_call( } else if (zend_string_equals_literal(name, "str_split")) { if (Z_TYPE_P(args[0]) != IS_STRING || Z_TYPE_P(args[1]) != IS_LONG - || !Z_LVAL_P(args[1]) <= 0) { + || Z_LVAL_P(args[1]) <= 0) { return FAILURE; } /* pass */ -- 2.50.1