diff --git a/NEWS b/NEWS index d4e46558a45..2b9f8d76624 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,10 @@ PHP NEWS . Fixed bug GH-8267 (MySQLi uses unsupported format specifier on Windows). (cmb) +- Streams: + . Fixed php://temp does not preserve file-position when switched to temporary + file. (Bernd Holzmüller) + 14 Apr 2022, PHP 8.1.5 - Core: diff --git a/ext/standard/tests/streams/temp_stream_seek.phpt b/ext/standard/tests/streams/temp_stream_seek.phpt new file mode 100644 index 00000000000..821c6b2784d --- /dev/null +++ b/ext/standard/tests/streams/temp_stream_seek.phpt @@ -0,0 +1,20 @@ +--TEST-- +BUG: php://temp does not preserve file-pointer once it switches from memory to temporary file +--FILE-- + +--EXPECT-- +string(16) "2222222222222222" +int(738) diff --git a/main/streams/memory.c b/main/streams/memory.c index 0784f1617cf..284ec4e190a 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -346,9 +346,10 @@ static ssize_t php_stream_temp_write(php_stream *stream, const char *buf, size_t return -1; } if (php_stream_is(ts->innerstream, PHP_STREAM_IS_MEMORY)) { - zend_string *membuf = php_stream_memory_get_buffer(ts->innerstream); - - if (ZSTR_LEN(membuf) + count >= ts->smax) { + zend_off_t pos = php_stream_tell(ts->innerstream); + + if (pos + count >= ts->smax) { + zend_string *membuf = php_stream_memory_get_buffer(ts->innerstream); php_stream *file = php_stream_fopen_temporary_file(ts->tmpdir, "php", NULL); if (file == NULL) { php_error_docref(NULL, E_WARNING, "Unable to create temporary file, Check permissions in temporary files directory."); @@ -358,6 +359,7 @@ static ssize_t php_stream_temp_write(php_stream *stream, const char *buf, size_t php_stream_free_enclosed(ts->innerstream, PHP_STREAM_FREE_CLOSE); ts->innerstream = file; php_stream_encloses(stream, ts->innerstream); + php_stream_seek(ts->innerstream, pos, SEEK_SET); } } return php_stream_write(ts->innerstream, buf, count);