Skip to content

Commit 6186ecd

Browse files
committed
Fix GH-8273: SplFileObject: key() returns wrong value
1 parent 4d6965d commit 6186ecd

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ PHP NEWS
2222
- SPL:
2323
. Fixed bug GH-8366 (ArrayIterator may leak when calling __construct()).
2424
(cmb)
25+
. Fixed bug GH-8273 (SplFileObject: key() returns wrong value). (Girgias)
2526

2627
- Streams:
2728
. Fixed php://temp does not preserve file-position when switched to temporary
@@ -95,7 +96,7 @@ PHP NEWS
9596
- Reflection:
9697
. Fixed bug GH-8080 (ReflectionClass::getConstants() depends on def. order).
9798
(cmb)
98-
. Fixed bug GH-8421 (Closures should accept attributes with
99+
. Fixed bug GH-8421 (Closures should accept attributes with
99100
Attribute::TARGET_FUNCTION). (ollieread)
100101

101102
- Zlib:

ext/spl/spl_directory.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,11 +1856,10 @@ static int spl_filesystem_object_cast(zend_object *readobj, zval *writeobj, int
18561856
}
18571857
/* }}} */
18581858

1859-
static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) /* {{{ */
1859+
static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bool silent, zend_long line_add) /* {{{ */
18601860
{
18611861
char *buf;
18621862
size_t line_len = 0;
1863-
zend_long line_add = (intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)) ? 1 : 0;
18641863

18651864
spl_filesystem_file_free_line(intern);
18661865

@@ -1905,7 +1904,13 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) /
19051904
return SUCCESS;
19061905
} /* }}} */
19071906

1908-
static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value) /* {{{ */
1907+
static inline zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool silent)
1908+
{
1909+
zend_long line_add = (intern->u.file.current_line) ? 1 : 0;
1910+
return spl_filesystem_file_read_ex(intern, silent, line_add);
1911+
}
1912+
1913+
static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value) /* {{{ */
19091914
{
19101915
int ret = SUCCESS;
19111916
zval *value;
@@ -2185,7 +2190,7 @@ PHP_METHOD(SplFileObject, fgets)
21852190

21862191
CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern);
21872192

2188-
if (spl_filesystem_file_read(intern, 0) == FAILURE) {
2193+
if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1) == FAILURE) {
21892194
RETURN_THROWS();
21902195
}
21912196
RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
@@ -2225,8 +2230,8 @@ PHP_METHOD(SplFileObject, key)
22252230
RETURN_THROWS();
22262231
}
22272232

2228-
/* Do not read the next line to support correct counting with fgetc()
2229-
if (!intern->current_line) {
2233+
/* Do not read the next line to support correct counting with fgetc()
2234+
if (!intern->u.file.current_line) {
22302235
spl_filesystem_file_read_line(ZEND_THIS, intern, 1);
22312236
} */
22322237
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)