]> granicus.if.org Git - php/commitdiff
Fixed bug #71695 (Global variables are reserved before execution).
authorXinchen Hui <laruence@gmail.com>
Tue, 1 Mar 2016 11:19:07 +0000 (19:19 +0800)
committerXinchen Hui <laruence@gmail.com>
Tue, 1 Mar 2016 11:19:07 +0000 (19:19 +0800)
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

NEWS
Zend/tests/bug71695.phpt [new file with mode: 0644]
Zend/zend_hash.c
ext/standard/array.c

diff --git a/NEWS b/NEWS
index 2c3eb105099e7f364a48f93e0157b818b0e23b52..ae0b4d709b582b1fadcead85aa55189add3d5e36 100644 (file)
--- 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 (file)
index 0000000..6747ce0
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #71695 (Global variables are reserved before execution)
+--FILE--
+<?php
+function provideGlobals() {
+       var_dump(array_key_exists("foo", $GLOBALS));
+       var_dump(isset($GLOBALS["foo"]));
+       $GLOBALS += array("foo" => "foo");
+}
+
+provideGlobals();
+echo $foo;
+?>
+--EXPECT--
+bool(false)
+bool(false)
+foo
index 11034fe0288e9ff78261acb755be8f43f9decdcd..1ffaff0361e9719dcc449677c5f90d7e561fa72d 100644 (file)
@@ -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);
index def7d7c465b0d3ab15797af5be2da641d3977812..6c824cb037c9d990add3659762af4ab1e6bee62b 100644 (file)
@@ -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;