Skip to content

Commit cf51d8f

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: Fix GH-8273: SplFileObject: key() returns wrong value
2 parents fa6d97d + 660ef91 commit cf51d8f

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

ext/spl/spl_directory.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,11 +1865,10 @@ static int spl_filesystem_object_cast(zend_object *readobj, zval *writeobj, int
18651865
}
18661866
/* }}} */
18671867

1868-
static zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool silent) /* {{{ */
1868+
static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bool silent, zend_long line_add) /* {{{ */
18691869
{
18701870
char *buf;
18711871
size_t line_len = 0;
1872-
zend_long line_add = (intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)) ? 1 : 0;
18731872

18741873
spl_filesystem_file_free_line(intern);
18751874

@@ -1914,6 +1913,12 @@ static zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool
19141913
return SUCCESS;
19151914
} /* }}} */
19161915

1916+
static inline zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool silent)
1917+
{
1918+
zend_long line_add = (intern->u.file.current_line) ? 1 : 0;
1919+
return spl_filesystem_file_read_ex(intern, silent, line_add);
1920+
}
1921+
19171922
static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value) /* {{{ */
19181923
{
19191924
do {
@@ -2183,7 +2188,7 @@ PHP_METHOD(SplFileObject, fgets)
21832188

21842189
CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
21852190

2186-
if (spl_filesystem_file_read(intern, 0) == FAILURE) {
2191+
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1) == FAILURE) {
21872192
RETURN_THROWS();
21882193
}
21892194
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
@@ -2221,8 +2226,8 @@ PHP_METHOD(SplFileObject, key)
22212226
RETURN_THROWS();
22222227
}
22232228

2224-
/* Do not read the next line to support correct counting with fgetc()
2225-
if (!intern->current_line) {
2229+
/* Do not read the next line to support correct counting with fgetc()
2230+
if (!intern->u.file.current_line) {
22262231
spl_filesystem_file_read_line(ZEND_THIS, intern, 1);
22272232
} */
22282233
RETURN_LONG(intern->u.file.current_line_num);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
SplFileObject verify interactions between seeking, getting the key and fgets
3+
--FILE--
4+
<?php
5+
6+
$file = new SplTempFileObject();
7+
8+
for ($i = 0; $i < 100; $i++) {
9+
$file->fwrite("Foo $i\n");
10+
}
11+
12+
$file->seek(50);
13+
14+
var_dump(
15+
['line' => $file->key(), 'contents' => trim($file->fgets())],
16+
['line' => $file->key(), 'contents' => trim($file->fgets())],
17+
['line' => $file->key(), 'contents' => trim($file->fgets())],
18+
);
19+
20+
?>
21+
--EXPECT--
22+
array(2) {
23+
["line"]=>
24+
int(50)
25+
["contents"]=>
26+
string(6) "Foo 50"
27+
}
28+
array(2) {
29+
["line"]=>
30+
int(51)
31+
["contents"]=>
32+
string(6) "Foo 51"
33+
}
34+
array(2) {
35+
["line"]=>
36+
int(52)
37+
["contents"]=>
38+
string(6) "Foo 52"
39+
}

ext/spl/tests/gh8273.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-8273 (SplFileObject: key() returns wrong value)
3+
--FILE--
4+
<?php
5+
6+
$file = new SplTempFileObject();
7+
8+
// write to file
9+
for ($i = 0; $i < 5; $i++) {
10+
$file->fwrite("line {$i}" . PHP_EOL);
11+
}
12+
13+
// read from file
14+
$file->rewind();
15+
while ($file->valid()) {
16+
echo $file->key(), ': ', $file->fgets();
17+
}
18+
?>
19+
--EXPECT--
20+
0: line 0
21+
1: line 1
22+
2: line 2
23+
3: line 3
24+
4: line 4

0 commit comments

Comments
 (0)