Skip to content

Commit c4c3bed

Browse files
committed
Fix GH-8562: SplFileObject::current() returns wrong value after next()
SplFileObject::next() without READ_AHEAD cleared the cached line and incremented current_line_num but didn't advance the stream. When called without a preceding current() (e.g. rewind() then next()), the stream position stayed put, so the subsequent current() read stale data. Read a line to advance the stream when next() is called with no cached line. Closes GH-8562
1 parent 0f3e741 commit c4c3bed

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

ext/spl/spl_directory.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2142,6 +2142,10 @@ PHP_METHOD(SplFileObject, next)
21422142

21432143
ZEND_PARSE_PARAMETERS_NONE();
21442144

2145+
if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) {
2146+
spl_filesystem_file_read_line(ZEND_THIS, intern, true);
2147+
}
2148+
21452149
spl_filesystem_file_free_line(intern);
21462150
if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
21472151
spl_filesystem_file_read_line(ZEND_THIS, intern, true);

ext/spl/tests/gh8562.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-8562 (SplFileObject::current() returns wrong result after call to next())
3+
--FILE--
4+
<?php
5+
$file = new SplTempFileObject();
6+
for ($i = 0; $i < 5; $i++) {
7+
$file->fwrite("line {$i}" . PHP_EOL);
8+
}
9+
10+
$file->rewind();
11+
$file->next();
12+
echo "After rewind+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n";
13+
14+
$file->rewind();
15+
$file->next();
16+
$file->next();
17+
echo "After rewind+next+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n";
18+
19+
$file->rewind();
20+
$file->current();
21+
$file->next();
22+
echo "After current+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n";
23+
?>
24+
--EXPECT--
25+
After rewind+next: key=1 current=line 1
26+
After rewind+next+next: key=2 current=line 2
27+
After current+next: key=1 current=line 1

0 commit comments

Comments
 (0)