diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-10-12 11:24:59 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-10-12 11:24:59 +0200 |
commit | 5a7f9afb9902c45218a0fff9112d34e05be7b61c (patch) | |
tree | 7263f88ef62ea504644f5695276352a005173b84 /Zend | |
parent | 9a2e5cfccb3431614c84bfa1f4e1d66370698b6d (diff) | |
parent | 3c4dd73c023e4aea317f774e045fdccc644f24b5 (diff) | |
download | php-git-5a7f9afb9902c45218a0fff9112d34e05be7b61c.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Detect self-addition of array more accurately
Deindirect source elements in zend_hash_merge
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/tests/array_add_indirect.phpt | 16 | ||||
-rw-r--r-- | Zend/tests/array_self_add_globals.phpt | 10 | ||||
-rw-r--r-- | Zend/zend_hash.c | 30 | ||||
-rw-r--r-- | Zend/zend_operators.c | 2 |
4 files changed, 44 insertions, 14 deletions
diff --git a/Zend/tests/array_add_indirect.phpt b/Zend/tests/array_add_indirect.phpt new file mode 100644 index 0000000000..821cc475b9 --- /dev/null +++ b/Zend/tests/array_add_indirect.phpt @@ -0,0 +1,16 @@ +--TEST-- +Array addition should not add INDIRECT elements +--FILE-- +<?php + +$x = 1; +$ary = ['y' => 1]; +$ary += $GLOBALS; +var_dump($ary['x']); +$x = 2; +var_dump($ary['x']); + +?> +--EXPECT-- +int(1) +int(1) diff --git a/Zend/tests/array_self_add_globals.phpt b/Zend/tests/array_self_add_globals.phpt new file mode 100644 index 0000000000..ebad7c3fdf --- /dev/null +++ b/Zend/tests/array_self_add_globals.phpt @@ -0,0 +1,10 @@ +--TEST-- +Add $GLOBALS to itself +--FILE-- +<?php +$GLOBALS += $GLOBALS; +$x = $GLOBALS + $GLOBALS; +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 4fd0c549b5..d35d8afd53 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2124,7 +2124,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source { uint32_t idx; Bucket *p; - zval *t; + zval *t, *s; IS_CONSISTENT(source); IS_CONSISTENT(target); @@ -2133,18 +2133,20 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source if (overwrite) { for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; - if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) && - UNEXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { - continue; + s = &p->val; + if (UNEXPECTED(Z_TYPE_P(s) == IS_INDIRECT)) { + s = Z_INDIRECT_P(s); + } + if (UNEXPECTED(Z_TYPE_P(s) == IS_UNDEF)) { + continue; } if (p->key) { - t = _zend_hash_add_or_update_i(target, p->key, &p->val, HASH_UPDATE | HASH_UPDATE_INDIRECT); + t = _zend_hash_add_or_update_i(target, p->key, s, HASH_UPDATE | HASH_UPDATE_INDIRECT); if (pCopyConstructor) { pCopyConstructor(t); } } else { - t = zend_hash_index_update(target, p->h, &p->val); + t = zend_hash_index_update(target, p->h, s); if (pCopyConstructor) { pCopyConstructor(t); } @@ -2153,18 +2155,20 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source } else { for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; - if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; - if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) && - UNEXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { - continue; + s = &p->val; + if (UNEXPECTED(Z_TYPE_P(s) == IS_INDIRECT)) { + s = Z_INDIRECT_P(s); + } + if (UNEXPECTED(Z_TYPE_P(s) == IS_UNDEF)) { + continue; } if (p->key) { - t = _zend_hash_add_or_update_i(target, p->key, &p->val, HASH_ADD | HASH_UPDATE_INDIRECT); + t = _zend_hash_add_or_update_i(target, p->key, s, HASH_ADD | HASH_UPDATE_INDIRECT); if (t && pCopyConstructor) { pCopyConstructor(t); } } else { - t = zend_hash_index_add(target, p->h, &p->val); + t = zend_hash_index_add(target, p->h, s); if (t && pCopyConstructor) { pCopyConstructor(t); } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 08fc18f261..596581270b 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -934,7 +934,7 @@ ZEND_API zend_string* ZEND_FASTCALL zval_try_get_string_func(zval *op) /* {{{ */ static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */ { - if ((result == op1) && (result == op2)) { + if (result == op1 && Z_ARR_P(op1) == Z_ARR_P(op2)) { /* $a += $a */ return; } |