Edit report at https://bugs.php.net/bug.php?id=64555&edit=1

 ID:                 64555
 Updated by:         ar...@php.net
 Reported by:        ar...@php.net
 Summary:            foreach no longer copies keys if they seem to be
                     interned
 Status:             Open
 Type:               Bug
 Package:            Scripting Engine problem
 PHP Version:        5.5.0beta1
-Assigned To:        
+Assigned To:        nikic
 Block user comment: N
 Private report:     N

 New Comment:

N.B. This indirectly causes a fatal error when using ZF1 forms so the impact is 
very high.


Previous Comments:
------------------------------------------------------------------------
[2013-03-31 11:21:13] ar...@php.net

Description:
------------
Foreach used to always copy string keys:
    key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, 
&int_key, 1, NULL);

Since fcc6611de9054327441786e52444b5f8eecdd525 it instead uses:
    zend_hash_get_current_key_zval(fe_ht, key);

This only copies string keys if IS_INTERNED(), however in some cases (at least 
in get_object_vars() like in the test script) the key name is an unmangled 
property name which is *within* an interned string. So IS_INTERNED is true but 
INTERNED_LEN and INTERNED_HASH are nonsense.

The later unset and assignment in the test script use the nonsense 
INTERNED_HASH.

The simple fix is to make get_object_vars() copy the property names (as in the 
attached patch) but it's quite possible that other code has been broken in the 
same way, so the safer fix might be to force the copy again.


Test script:
---------------
https://gist.github.com/arraypad/5280321

Expected result:
----------------
Unsetting: unsetme
Changing: keepme
array(1) {
  ["keepme"]=>
  int(43)
}
array(1) {
  [0]=>
  string(6) "keepme"
}

Actual result:
--------------
Unsetting: unsetme
Changing: keepme
array(3) {
  ["unsetme"]=>
  int(1)
  ["keepme"]=>
  int(43)
  ["keepme"]=>
  int(42)
}
array(3) {
  [0]=>
  string(7) "unsetme"
  [1]=>
  string(6) "keepme"
  [2]=>
  string(6) "keepme"
}


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=64555&edit=1

Reply via email to