diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 8e89b860487..bfeb7f18532 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1865,11 +1865,10 @@ static int spl_filesystem_object_cast(zend_object *readobj, zval *writeobj, int } /* }}} */ -static zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool silent) /* {{{ */ +static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bool silent, zend_long line_add) /* {{{ */ { char *buf; size_t line_len = 0; - zend_long line_add = (intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)) ? 1 : 0; spl_filesystem_file_free_line(intern); @@ -1914,6 +1913,12 @@ static zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool return SUCCESS; } /* }}} */ +static inline zend_result spl_filesystem_file_read(spl_filesystem_object *intern, bool silent) +{ + zend_long line_add = (intern->u.file.current_line) ? 1 : 0; + return spl_filesystem_file_read_ex(intern, silent, line_add); +} + static zend_result spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value) /* {{{ */ { do { @@ -2183,7 +2188,7 @@ PHP_METHOD(SplFileObject, fgets) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - if (spl_filesystem_file_read(intern, 0) == FAILURE) { + if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1) == FAILURE) { RETURN_THROWS(); } RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len); @@ -2221,8 +2226,8 @@ PHP_METHOD(SplFileObject, key) RETURN_THROWS(); } -/* Do not read the next line to support correct counting with fgetc() - if (!intern->current_line) { + /* Do not read the next line to support correct counting with fgetc() + if (!intern->u.file.current_line) { spl_filesystem_file_read_line(ZEND_THIS, intern, 1); } */ RETURN_LONG(intern->u.file.current_line_num); diff --git a/ext/spl/tests/SplFileObject_key_fgets_and seek.phpt b/ext/spl/tests/SplFileObject_key_fgets_and seek.phpt new file mode 100644 index 00000000000..eef6c37745d --- /dev/null +++ b/ext/spl/tests/SplFileObject_key_fgets_and seek.phpt @@ -0,0 +1,39 @@ +--TEST-- +SplFileObject verify interactions between seeking, getting the key and fgets +--FILE-- +fwrite("Foo $i\n"); +} + +$file->seek(50); + +var_dump( + ['line' => $file->key(), 'contents' => trim($file->fgets())], + ['line' => $file->key(), 'contents' => trim($file->fgets())], + ['line' => $file->key(), 'contents' => trim($file->fgets())], +); + +?> +--EXPECT-- +array(2) { + ["line"]=> + int(50) + ["contents"]=> + string(6) "Foo 50" +} +array(2) { + ["line"]=> + int(51) + ["contents"]=> + string(6) "Foo 51" +} +array(2) { + ["line"]=> + int(52) + ["contents"]=> + string(6) "Foo 52" +} diff --git a/ext/spl/tests/gh8273.phpt b/ext/spl/tests/gh8273.phpt new file mode 100644 index 00000000000..87931541653 --- /dev/null +++ b/ext/spl/tests/gh8273.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-8273 (SplFileObject: key() returns wrong value) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +// read from file +$file->rewind(); +while ($file->valid()) { + echo $file->key(), ': ', $file->fgets(); +} +?> +--EXPECT-- +0: line 0 +1: line 1 +2: line 2 +3: line 3 +4: line 4