Preserve file-position when php://temp switches to temporary file

Closes GH-8333.
This commit is contained in:
Bernd Holzmüller 2022-04-09 17:49:47 +02:00 committed by Christoph M. Becker
parent 3aaf2f6f89
commit 84c18f9f04
No known key found for this signature in database
GPG key ID: D66C9593118BCCB6
3 changed files with 30 additions and 4 deletions

4
NEWS
View file

@ -10,6 +10,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.0.18
- Core:

View file

@ -0,0 +1,20 @@
--TEST--
BUG: php://temp does not preserve file-pointer once it switches from memory to temporary file
--FILE--
<?php
$f = fopen('php://temp/maxmemory:1024', 'r+');
fwrite($f, str_repeat("1", 738));
fseek($f, 0, SEEK_SET);
fwrite($f, str_repeat("2", 512));
fseek($f, 0, SEEK_SET);
var_dump(fread($f, 16));
fseek($f, 0, SEEK_END);
var_dump(ftell($f));
?>
--EXPECT--
string(16) "2222222222222222"
int(738)

View file

@ -375,10 +375,11 @@ 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)) {
size_t memsize;
char *membuf = php_stream_memory_get_buffer(ts->innerstream, &memsize);
if (memsize + count >= ts->smax) {
zend_off_t pos = php_stream_tell(ts->innerstream);
if (pos + count >= ts->smax) {
size_t memsize;
char *membuf = php_stream_memory_get_buffer(ts->innerstream, &memsize);
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.");
@ -388,6 +389,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);