]> granicus.if.org Git - php/commitdiff
Fix bug #64555: foreach no longer copies keys if they are interned
authorNikita Popov <nikic@php.net>
Wed, 3 Apr 2013 18:29:19 +0000 (20:29 +0200)
committerNikita Popov <nikic@php.net>
Wed, 3 Apr 2013 18:29:19 +0000 (20:29 +0200)
NEWS
Zend/tests/bug64555.phpt [new file with mode: 0644]
Zend/zend_hash.c

diff --git a/NEWS b/NEWS
index 7e83b30d785438e34f356adcdb02bd037dde2e10..974df5e9ed89d9611448347f51e04ed2b0c8d062 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ PHP                                                                        NEWS
 
 - Core:
   . Fixed bug #64565 (copy doesn't report failure on partial copy). (Remi)
+  . Fixed bug #64555 (foreach no longer copies keys if they are interned).
+    (Nikita Popov)
 
 - CURL:
   . Added CURL_WRAPPERS_ENABLE constant. (Laruence)
diff --git a/Zend/tests/bug64555.phpt b/Zend/tests/bug64555.phpt
new file mode 100644 (file)
index 0000000..d5226af
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Bug #64555: Array key within interned string gets wrong hash value
+--FILE--
+<?php
+class Foo {
+    protected $unsetme = 1;
+    protected $keepme = 2;
+     
+    public function test() {
+        $a = get_object_vars($this);
+         
+        foreach ($a as $k => $v) {
+            if ($k == 'unsetme') {
+                echo "Unsetting: $k\n";
+                unset($a[$k]);
+            } else if ($k == 'keepme') {
+                echo "Changing: $k\n";
+                $a[$k] = 42;
+                $a['keepme'] = 43;
+            }
+        }
+         
+        var_dump($a, array_keys($a));
+    }
+}
+$f = new Foo;
+$f->test();
+?>
+--EXPECT--
+Unsetting: unsetme
+Changing: keepme
+array(1) {
+  ["keepme"]=>
+  int(43)
+}
+array(1) {
+  [0]=>
+  string(6) "keepme"
+}
index bca47b330fd0c6fae9ff6bed9cc2050a70ab9c28..27b603eed2d3bc3825de239998dd1b37b7550489 100644 (file)
@@ -1182,7 +1182,7 @@ ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key,
                Z_TYPE_P(key) = IS_NULL;
        } else if (p->nKeyLength) {
                Z_TYPE_P(key) = IS_STRING;
-               Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char *) p->arKey : estrndup(p->arKey, p->nKeyLength - 1);
+               Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
                Z_STRLEN_P(key) = p->nKeyLength - 1;
        } else {
                Z_TYPE_P(key) = IS_LONG;