From: Xinchen Hui Date: Tue, 1 Mar 2016 11:19:07 +0000 (+0800) Subject: Fixed bug #71695 (Global variables are reserved before execution). X-Git-Tag: php-7.0.5RC1~44 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=186844be92d26a74ce61bd71d14053ae5be42602;p=php Fixed bug #71695 (Global variables are reserved before execution). Instead of slow down hash_merge, we may also check the array(whether it contains INDIRECT) outside of the loop, however, consisdering hash_merge is not widly used, I prefer fix this in the current way to keep the codes simple --- diff --git a/NEWS b/NEWS index 2c3eb10509..ae0b4d709b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ PHP NEWS ?? ??? 2016 PHP 7.0.5 - Core: + . Fixed bug #71695 (Global variables are reserved before execution). + (Laruence) . Fixed bug #71629 (Out-of-bounds access in php_url_decode in context php_stream_url_wrap_rfc2397). (mt at debian dot org) . Fixed bug #71622 (Strings used in pass-as-reference cannot be used to diff --git a/Zend/tests/bug71695.phpt b/Zend/tests/bug71695.phpt new file mode 100644 index 0000000000..6747ce0e14 --- /dev/null +++ b/Zend/tests/bug71695.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #71695 (Global variables are reserved before execution) +--FILE-- + "foo"); +} + +provideGlobals(); +echo $foo; +?> +--EXPECT-- +bool(false) +bool(false) +foo diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 11034fe028..1ffaff0361 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1864,7 +1864,6 @@ ZEND_API void ZEND_FASTCALL _zend_hash_merge(HashTable *target, HashTable *sourc uint32_t idx; Bucket *p; zval *t; - uint32_t mode = (overwrite?HASH_UPDATE:HASH_ADD); IS_CONSISTENT(source); IS_CONSISTENT(target); @@ -1874,12 +1873,25 @@ ZEND_API void ZEND_FASTCALL _zend_hash_merge(HashTable *target, HashTable *sourc p = source->arData + idx; if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue; if (p->key) { - t = _zend_hash_add_or_update(target, p->key, &p->val, mode ZEND_FILE_LINE_RELAY_CC); - if (t && pCopyConstructor) { - pCopyConstructor(t); + if (EXPECTED((t = zend_hash_find_ind(target, p->key)) == NULL)) { + t = zend_hash_update_ind(target, p->key, &p->val); + if (t && pCopyConstructor) { + pCopyConstructor(t); + } + } else { + if (!overwrite) { + continue; + } + if (target->pDestructor) { + target->pDestructor(t); + } + ZVAL_COPY_VALUE(t, &p->val); + if (pCopyConstructor) { + pCopyConstructor(t); + } } } else { - if ((mode==HASH_UPDATE || !zend_hash_index_exists(target, p->h))) { + if ((overwrite || !zend_hash_index_exists(target, p->h))) { t = zend_hash_index_update(target, p->h, &p->val); if (t && pCopyConstructor) { pCopyConstructor(t); diff --git a/ext/standard/array.c b/ext/standard/array.c index def7d7c465..6c824cb037 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -5414,6 +5414,7 @@ PHP_FUNCTION(array_map) PHP_FUNCTION(array_key_exists) { zval *key; /* key to check for */ + zval *val; /* val to check for */ HashTable *array; /* array to check in */ #ifndef FAST_ZPP @@ -5429,7 +5430,7 @@ PHP_FUNCTION(array_key_exists) switch (Z_TYPE_P(key)) { case IS_STRING: - if (zend_symtable_exists(array, Z_STR_P(key))) { + if ((val = zend_symtable_find_ind(array, Z_STR_P(key)))) { RETURN_TRUE; } RETURN_FALSE;