From: Marcus Boerger Date: Mon, 26 Jan 2004 22:30:25 +0000 (+0000) Subject: Fixed bug #27042 (SPL: SeekableIterator seek() broken). X-Git-Tag: php-5.0.0b4RC1~288 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5ac404eb64a89403041d4951ab986305435cbdad;p=php Fixed bug #27042 (SPL: SeekableIterator seek() broken). --- diff --git a/NEWS b/NEWS index 307f9d7bca..122b4af4f6 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS (Derick) - Fixed problems with longlong values in mysqli. (Georg) - Fixed class name case preserving of user defined classes. (Marcus) +- Fixed bug #27042 (SPL: SeekableIterator seek() broken). (Marcus) - Fixed bug #27008 (Every class method can be called as static). (Marcus) - Fixed bug #26938 (exec() has problems reading long lines). (Ilia, runekl[at]opoint[dot]com diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 6a5075398d..82b12a1ae9 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -880,6 +880,9 @@ static INLINE void spl_limit_it_seek(spl_dual_it_object *intern, long pos TSRMLS INIT_PZVAL(&zpos); ZVAL_LONG(&zpos, pos); zend_call_method_with_1_params(&intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, &zpos); + spl_dual_it_free(intern TSRMLS_CC); + zend_user_it_free_current(intern->inner.iterator TSRMLS_CC); + spl_dual_it_fetch(intern, 1 TSRMLS_CC); intern->current.pos = pos; } else { /* emulate the forward seek, by next() calls */ diff --git a/ext/spl/tests/limititerator.phpt b/ext/spl/tests/limititerator.phpt new file mode 100755 index 0000000000..518dc35ceb --- /dev/null +++ b/ext/spl/tests/limititerator.phpt @@ -0,0 +1,173 @@ +--TEST-- +SPL: SeekableIterator +--SKIPIF-- + +--FILE-- +a = $a; + } + + public function rewind() + { + echo __METHOD__ . "\n"; + $this->i = 0; + } + + public function hasMore() + { + echo __METHOD__ . "\n"; + return $this->i < count($this->a); + } + + public function key() + { + echo __METHOD__ . "\n"; + return $this->i; + } + + public function current() + { + echo __METHOD__ . "\n"; + return $this->a[$this->i]; + } + + public function next() + { + echo __METHOD__ . "\n"; + $this->i++; + } +} + +class SeekableNumericArrayIterator extends NumericArrayIterator implements SeekableIterator +{ + public function seek($index) + { + if ($index < count($this->a)) { + $this->i = $index; + } + echo __METHOD__ . '(' . $index . ")\n"; + } +} + +$a = array(1, 2, 3, 4, 5); +foreach (new LimitIterator(new NumericArrayIterator($a)) as $v) +{ + print "$v\n"; +} + +echo "===SEEKABLE===\n"; +$a = array(1, 2, 3, 4, 5); +foreach(new LimitIterator(new SeekableNumericArrayIterator($a)) as $v) +{ + print "$v\n"; +} + +echo "===SEEKING===\n"; +$a = array(1, 2, 3, 4, 5); +$l = new LimitIterator(new SeekableNumericArrayIterator($a)); +for($i = 0; $i < 5; $i++) +{ + $l->seek($i); + print $l->current() . "\n"; +} + +?> +===DONE=== + +--EXPECT-- +NumericArrayIterator::__construct +NumericArrayIterator::rewind +NumericArrayIterator::hasMore +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +1 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +2 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +3 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +4 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +5 +NumericArrayIterator::next +NumericArrayIterator::hasMore +===SEEKABLE=== +NumericArrayIterator::__construct +NumericArrayIterator::rewind +SeekableNumericArrayIterator::seek(0) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +1 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +2 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +3 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +4 +NumericArrayIterator::next +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +5 +NumericArrayIterator::next +NumericArrayIterator::hasMore +===SEEKING=== +NumericArrayIterator::__construct +SeekableNumericArrayIterator::seek(0) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +1 +SeekableNumericArrayIterator::seek(1) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +2 +SeekableNumericArrayIterator::seek(2) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +3 +SeekableNumericArrayIterator::seek(3) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +4 +SeekableNumericArrayIterator::seek(4) +NumericArrayIterator::hasMore +NumericArrayIterator::current +NumericArrayIterator::key +5 +===DONE===