summaryrefslogtreecommitdiff
path: root/Zend/zend_hash.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-10-12 11:25:27 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-10-12 11:25:27 +0200
commit66ecee624318d1e06c5f94b0bbeac20a65d5c7aa (patch)
treed6a91c45714729a4dbb89f10b9c1cc62538b276d /Zend/zend_hash.c
parent8d11576a86275481b34954a163824909c28037ef (diff)
parent5a7f9afb9902c45218a0fff9112d34e05be7b61c (diff)
downloadphp-git-66ecee624318d1e06c5f94b0bbeac20a65d5c7aa.tar.gz
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Detect self-addition of array more accurately Deindirect source elements in zend_hash_merge
Diffstat (limited to 'Zend/zend_hash.c')
-rw-r--r--Zend/zend_hash.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index c92b869569..6d065cd03e 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -2149,7 +2149,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);
@@ -2158,18 +2158,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);
}
@@ -2178,18 +2180,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);
}