Skip to content

Commit 660ef91

Browse files
committed
Fix GH-8273: SplFileObject: key() returns wrong value
1 parent bfad99f commit 660ef91

File tree

4 files changed

+75
-6
lines changed

4 files changed

+75
-6
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ PHP NEWS
3636
- SPL:
3737
. Fixed bug GH-8366 (ArrayIterator may leak when calling __construct()).
3838
(cmb)
39+
. Fixed bug GH-8273 (SplFileObject: key() returns wrong value). (Girgias)
3940

4041
- Streams:
4142
. Fixed php://temp does not preserve file-position when switched to temporary

ext/spl/spl_directory.c

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

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

18731872
spl_filesystem_file_free_line(intern);
18741873

@@ -1913,7 +1912,13 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) /
19131912
return SUCCESS;
19141913
} /* }}} */
19151914

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

21772182
CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
21782183

2179-
if (spl_filesystem_file_read(intern, 0) == FAILURE) {
2184+
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1) == FAILURE) {
21802185
RETURN_THROWS();
21812186
}
21822187
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
@@ -2214,8 +2219,8 @@ PHP_METHOD(SplFileObject, key)
22142219
RETURN_THROWS();
22152220
}
22162221

2217-
/* Do not read the next line to support correct counting with fgetc()
2218-
if (!intern->current_line) {
2222+
/* Do not read the next line to support correct counting with fgetc()
2223+
if (!intern->u.file.current_line) {
22192224
spl_filesystem_file_read_line(ZEND_THIS, intern, 1);
22202225
} */
22212226
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)