Fix bug #64555: foreach no longer copies keys if they are interned

This commit is contained in:
Nikita Popov 2013-04-03 20:29:19 +02:00
parent 42f94aa978
commit 1f34ccbe34
3 changed files with 45 additions and 1 deletions

2
NEWS
View File

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

42
Zend/tests/bug64555.phpt Normal file
View File

@ -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"
}

View 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;