diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-10-12 11:25:27 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-10-12 11:25:27 +0200 |
commit | 66ecee624318d1e06c5f94b0bbeac20a65d5c7aa (patch) | |
tree | d6a91c45714729a4dbb89f10b9c1cc62538b276d /Zend/zend_hash.c | |
parent | 8d11576a86275481b34954a163824909c28037ef (diff) | |
parent | 5a7f9afb9902c45218a0fff9112d34e05be7b61c (diff) | |
download | php-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.c | 30 |
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); } |