From ca61212ebf02f482f21bb54fec1f97a5b346b886 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 7 Jun 2021 15:57:25 +0200 Subject: [PATCH] Fix #81092: fflush before stream_filter_remove corrupts stream When doing a non finishing flush, BZ2_bzCompress() returns BZ_FLUSH_OK (not BZ_FINISH_OK) what requires us to do further flushes right away. We also refactor the while-loop as do-loop. --- ext/bz2/bz2_filter.c | 5 ++--- ext/bz2/tests/bug81092.phpt | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 ext/bz2/tests/bug81092.phpt diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index fb79cb5dc6c0d..8cbb3bacc6ed3 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -268,8 +268,7 @@ static php_stream_filter_status_t php_bz2_compress_filter( if (flags & PSFS_FLAG_FLUSH_CLOSE || ((flags & PSFS_FLAG_FLUSH_INC) && !data->is_flushed)) { /* Spit it out! */ - status = BZ_FINISH_OK; - while (status == BZ_FINISH_OK) { + do { status = BZ2_bzCompress(&(data->strm), (flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : BZ_FLUSH)); data->is_flushed = 1; if (data->strm.avail_out < data->outbuf_len) { @@ -281,7 +280,7 @@ static php_stream_filter_status_t php_bz2_compress_filter( data->strm.next_out = data->outbuf; exit_status = PSFS_PASS_ON; } - } + } while (status == (flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH_OK : BZ_FLUSH_OK)); } if (bytes_consumed) { diff --git a/ext/bz2/tests/bug81092.phpt b/ext/bz2/tests/bug81092.phpt new file mode 100644 index 0000000000000..9560d9ff45179 --- /dev/null +++ b/ext/bz2/tests/bug81092.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #81092 (fflush before stream_filter_remove corrupts stream) +--SKIPIF-- + +--FILE-- + 9, 'work' => 0]); +fwrite($stream, random_bytes(8192)); +fflush($stream); +stream_filter_remove($filter); + +var_dump(strlen(bzdecompress(file_get_contents(__DIR__ . "/81092.bz2")))); +?> +--CLEAN-- + +--EXPECT-- +int(8192)