diff --git a/ext/standard/tests/streams/stream_filter_flush_partial_read.phpt b/ext/standard/tests/streams/stream_filter_flush_partial_read.phpt new file mode 100644 index 000000000000..b8abc9f4b3de --- /dev/null +++ b/ext/standard/tests/streams/stream_filter_flush_partial_read.phpt @@ -0,0 +1,33 @@ +--TEST-- +Flushing a read filter on a partially-read stream must not duplicate buffered bytes +--FILE-- +datalen; + stream_bucket_append($out, $bucket); + } + if ($closing) { + stream_bucket_append($out, stream_bucket_new($this->stream, "")); + } + return PSFS_PASS_ON; + } +} + +stream_filter_register("flushemit", "FlushEmitFilter"); + +$fp = fopen("php://memory", "r+"); +fwrite($fp, "ABCDEFGHIJKLMNOP"); +rewind($fp); + +$filter = stream_filter_append($fp, "flushemit", STREAM_FILTER_READ); +var_dump(fread($fp, 5)); +stream_filter_remove($filter); +var_dump(fread($fp, 100)); +?> +--EXPECT-- +string(5) "ABCDE" +string(18) "FGHIJKLMNOP" diff --git a/main/streams/filter.c b/main/streams/filter.c index 967be5d7f724..edf0a01e46fc 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -459,9 +459,9 @@ PHPAPI int _php_stream_filter_flush(php_stream_filter *filter, int finish) /* Dump any newly flushed data to the read buffer */ if (stream->readpos > 0) { /* Back the buffer up */ - memcpy(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos); - stream->readpos = 0; + memmove(stream->readbuf, stream->readbuf + stream->readpos, stream->writepos - stream->readpos); stream->writepos -= stream->readpos; + stream->readpos = 0; } if (flushed_size > (stream->readbuflen - stream->writepos)) { /* Grow the buffer */