From 5ac404eb64a89403041d4951ab986305435cbdad Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Mon, 26 Jan 2004 22:30:25 +0000 Subject: [PATCH] Fixed bug #27042 (SPL: SeekableIterator seek() broken). --- NEWS | 1 + ext/spl/spl_iterators.c | 3 + ext/spl/tests/limititerator.phpt | 173 +++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100755 ext/spl/tests/limititerator.phpt diff --git a/NEWS b/NEWS index 307f9d7bcac..122b4af4f6c 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 6a5075398d4..82b12a1ae9d 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 00000000000..518dc35cebf --- /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===