From: Xinchen Hui Date: Sun, 7 Jan 2018 06:17:47 +0000 (+0800) Subject: Fixed bug while dealing with ADD_ARRAY_ELEMENT against an existing const array X-Git-Tag: php-7.3.0alpha1~685 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=63a96ebf6a833aa1a0133948ad537a8d77bf75c7;p=php Fixed bug while dealing with ADD_ARRAY_ELEMENT against an existing const array --- diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 8b5f88cffe..cbfc6de648 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -97,30 +97,33 @@ typedef struct _sccp_ctx { #define IS_PARTIAL_ARRAY(zv) (Z_TYPE_P(zv) == PARTIAL_ARRAY) #define IS_PARTIAL_OBJECT(zv) (Z_TYPE_P(zv) == PARTIAL_OBJECT) +#define MAKE_PARTIAL_ARRAY(zv) (Z_TYPE_INFO_P(zv) = PARTIAL_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) +#define MAKE_PARTIAL_OBJECT(zv) (Z_TYPE_INFO_P(zv) = PARTIAL_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT)) + #define MAKE_TOP(zv) (Z_TYPE_INFO_P(zv) = TOP) #define MAKE_BOT(zv) (Z_TYPE_INFO_P(zv) = BOT) static void empty_partial_array(zval *zv) { - Z_TYPE_INFO_P(zv) = PARTIAL_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + MAKE_PARTIAL_ARRAY(zv); Z_ARR_P(zv) = zend_new_array(8); } static void dup_partial_array(zval *dst, zval *src) { - Z_TYPE_INFO_P(dst) = PARTIAL_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + MAKE_PARTIAL_ARRAY(dst); Z_ARR_P(dst) = zend_array_dup(Z_ARR_P(src)); } static void empty_partial_object(zval *zv) { - Z_TYPE_INFO_P(zv) = PARTIAL_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + MAKE_PARTIAL_OBJECT(zv); Z_ARR_P(zv) = zend_new_array(8); } static void dup_partial_object(zval *dst, zval *src) { - Z_TYPE_INFO_P(dst) = PARTIAL_OBJECT | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + MAKE_PARTIAL_OBJECT(dst); Z_ARR_P(dst) = zend_array_dup(Z_ARR_P(src)); } @@ -1245,7 +1248,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o if (!result) { empty_partial_array(&zv); } else { - Z_TYPE_INFO_P(result) = PARTIAL_ARRAY | (IS_TYPE_REFCOUNTED << Z_TYPE_FLAGS_SHIFT); + MAKE_PARTIAL_ARRAY(result); ZVAL_COPY_VALUE(&zv, result); ZVAL_NULL(result); } @@ -1268,10 +1271,8 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o if (result) { ZVAL_COPY_VALUE(&zv, result); ZVAL_NULL(result); - } else if (op1 && !IS_PARTIAL_ARRAY(op1)) { - array_init(&zv); } else { - empty_partial_array(&zv); + array_init(&zv); } if (op1) { @@ -1279,6 +1280,9 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o /* We can't add NEXT element into partial array (skip it) */ SET_RESULT(result, &zv); } else if (ct_eval_add_array_elem(&zv, op1, op2) == SUCCESS) { + if (IS_PARTIAL_ARRAY(op1)) { + MAKE_PARTIAL_ARRAY(&zv); + } SET_RESULT(result, &zv); } else { SET_RESULT_BOT(result); diff --git a/ext/opcache/tests/opt/sccp_025.phpt b/ext/opcache/tests/opt/sccp_025.phpt new file mode 100644 index 0000000000..020973368e --- /dev/null +++ b/ext/opcache/tests/opt/sccp_025.phpt @@ -0,0 +1,55 @@ +--TEST-- +SCCP 025: ADD_ARRAY_ELEMENT against an existing const array +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0 +--SKIPIF-- + +--FILE-- + array( + 'id' => 1, + ), + 6 => array( + 'viewtopic' => strval("phpBB/viewtopic.$phpEx"), + + ), + ); + + $test_cases = array( + array( + 'expected' => array(6), + ), + ); + + foreach ($test_cases as $case => $case_data) + { + foreach ($case_data['expected'] as $data_set => $expected) + { + $test_cases[$case]['expected'][$data_set] = $expected_data_sets[$expected]; + } + } + + return $test_cases; +} +var_dump(test("xxx")); +?> +--EXPECTF-- +array(1) { + [0]=> + array(1) { + ["expected"]=> + array(1) { + [0]=> + array(1) { + ["viewtopic"]=> + string(19) "phpBB/viewtopic.xxx" + } + } + } +}