mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-07 09:17:29 +00:00
Deindirect source elements in zend_hash_merge
If the RHS has INDIRECT elements, we do not those to be added to the LHS verbatim. As we're using UPDATE_INDIRECT, we might even create a nested INDIRECT that way. This is a side-quest of oss-fuzz #26245.
This commit is contained in:
1 parent
1ed5a2a54d
commit
e304468e57
2 files changed
+33
-13
No files matched your search
@@ -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)
|
||||
+17
-13
@@ -1999,7 +1999,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);
|
||||
@@ -2008,18 +2008,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);
|
||||
}
|
||||
@@ -2028,18 +2030,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);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user