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
This commit is contained in:
Nikita Popov 2020-10-12 11:24:59 +02:00
commit 5a7f9afb99
4 changed files with 44 additions and 14 deletions

View file

@ -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)

View file

@ -0,0 +1,10 @@
--TEST--
Add $GLOBALS to itself
--FILE--
<?php
$GLOBALS += $GLOBALS;
$x = $GLOBALS + $GLOBALS;
?>
===DONE===
--EXPECT--
===DONE===

View file

@ -2124,7 +2124,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source
{ {
uint32_t idx; uint32_t idx;
Bucket *p; Bucket *p;
zval *t; zval *t, *s;
IS_CONSISTENT(source); IS_CONSISTENT(source);
IS_CONSISTENT(target); IS_CONSISTENT(target);
@ -2133,18 +2133,20 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source
if (overwrite) { if (overwrite) {
for (idx = 0; idx < source->nNumUsed; idx++) { for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx; p = source->arData + idx;
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; s = &p->val;
if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) && if (UNEXPECTED(Z_TYPE_P(s) == IS_INDIRECT)) {
UNEXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { s = Z_INDIRECT_P(s);
continue; }
if (UNEXPECTED(Z_TYPE_P(s) == IS_UNDEF)) {
continue;
} }
if (p->key) { 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) { if (pCopyConstructor) {
pCopyConstructor(t); pCopyConstructor(t);
} }
} else { } else {
t = zend_hash_index_update(target, p->h, &p->val); t = zend_hash_index_update(target, p->h, s);
if (pCopyConstructor) { if (pCopyConstructor) {
pCopyConstructor(t); pCopyConstructor(t);
} }
@ -2153,18 +2155,20 @@ ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source
} else { } else {
for (idx = 0; idx < source->nNumUsed; idx++) { for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx; p = source->arData + idx;
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; s = &p->val;
if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) && if (UNEXPECTED(Z_TYPE_P(s) == IS_INDIRECT)) {
UNEXPECTED(Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { s = Z_INDIRECT_P(s);
continue; }
if (UNEXPECTED(Z_TYPE_P(s) == IS_UNDEF)) {
continue;
} }
if (p->key) { 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) { if (t && pCopyConstructor) {
pCopyConstructor(t); pCopyConstructor(t);
} }
} else { } else {
t = zend_hash_index_add(target, p->h, &p->val); t = zend_hash_index_add(target, p->h, s);
if (t && pCopyConstructor) { if (t && pCopyConstructor) {
pCopyConstructor(t); pCopyConstructor(t);
} }

View file

@ -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) /* {{{ */ 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 */ /* $a += $a */
return; return;
} }