From: Adam Harvey Date: Thu, 29 May 2014 17:49:32 +0000 (+0000) Subject: Check for zero-length keys in spl_array_skip_protected and don't skip them. X-Git-Tag: php-5.4.30RC1~35 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b5d9983ff4373793621ee4b21d4964b30c5d21c8;p=php Check for zero-length keys in spl_array_skip_protected and don't skip them. Fixes bug #67360 (Missing element after ArrayObject::getIterator). --- diff --git a/NEWS b/NEWS index 8b5acf310a..354a796af2 100644 --- 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: diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 68727d1367..34f3a3818d 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -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 index 0000000000..552c02ad74 --- /dev/null +++ b/ext/spl/tests/bug67360.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #67360 (Missing element after ArrayObject::getIterator) +--FILE-- + 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) +}