]> granicus.if.org Git - php/commitdiff
Check for zero-length keys in spl_array_skip_protected and don't skip them.
authorAdam Harvey <aharvey@php.net>
Thu, 29 May 2014 17:49:32 +0000 (17:49 +0000)
committerAdam Harvey <aharvey@php.net>
Thu, 29 May 2014 17:49:32 +0000 (17:49 +0000)
Fixes bug #67360 (Missing element after ArrayObject::getIterator).

NEWS
ext/spl/spl_array.c
ext/spl/tests/bug67360.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 8b5acf310a1e2ce1de183ce45ac303762ae4702d..354a796af2bcd05403aa2fb47a82ad520ded1dbb 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ PHP                                                                        NEWS
   . Fixed bug #67308 (Serialize of DateTime truncates fractions of second).
     (Adam)
 
+- SPL:
+  . Fixed bug #67360 (Missing element after ArrayObject::getIterator). (Adam)
+
 ?? ??? 2014, PHP 5.4.29
 
 - COM:
index 68727d1367aceca90660186d55e20a53ebba7d7b..34f3a3818d8bb6301e4f85e254f5c4b7f13b2bf6 100644 (file)
@@ -922,7 +922,14 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR
        if (Z_TYPE_P(intern->array) == IS_OBJECT) {
                do {
                        if (zend_hash_get_current_key_ex(aht, &string_key, &string_length, &num_key, 0, &intern->pos) == HASH_KEY_IS_STRING) {
-                               if (!string_length || string_key[0]) {
+                               /* zend_hash_get_current_key_ex() should never set
+                                * string_length to 0 when returning HASH_KEY_IS_STRING, but we
+                                * may as well be defensive and consider that successful.
+                                * Beyond that, we're looking for protected keys (which will
+                                * have a null byte at string_key[0]), but want to avoid
+                                * skipping completely empty keys (which will also have the
+                                * null byte, but a string_length of 1). */
+                               if (!string_length || string_key[0] || string_length == 1) {
                                        return SUCCESS;
                                }
                        } else {
diff --git a/ext/spl/tests/bug67360.phpt b/ext/spl/tests/bug67360.phpt
new file mode 100644 (file)
index 0000000..552c02a
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+Bug #67360 (Missing element after ArrayObject::getIterator)
+--FILE--
+<?php
+
+$array = array('' => 1, 1 => 2, 3 => 4);
+$ArrayObject = new ArrayObject($array);
+var_dump($ArrayObject);
+$Iterator = $ArrayObject->getIterator();
+var_dump(count($Iterator) === count($array));
+var_dump(iterator_to_array($Iterator));
+
+?>
+--EXPECTF--
+object(ArrayObject)#%d (1) {
+  ["storage":"ArrayObject":private]=>
+  array(3) {
+    [""]=>
+    int(1)
+    [1]=>
+    int(2)
+    [3]=>
+    int(4)
+  }
+}
+bool(true)
+array(3) {
+  [""]=>
+  int(1)
+  [1]=>
+  int(2)
+  [3]=>
+  int(4)
+}