Skip to content

Commit

Permalink
Fix #81092: fflush before stream_filter_remove corrupts stream
Browse files Browse the repository at this point in the history
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.

Closes GH-7113.
  • Loading branch information
cmb69 committed Jun 8, 2021
1 parent d8165c2 commit a1738d8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ PHP NEWS
. Fixed bug #81070 (Integer underflow in memory limit comparison).
(Peter van Dommelen)

- Bzip2:
. Fixed bug #81092 (fflush before stream_filter_remove corrupts stream).
(cmb)

- OpenSSL:
. Fixed bug #76694 (native Windows cert verification uses CN as sever name).
(cmb)
Expand Down
5 changes: 2 additions & 3 deletions ext/bz2/bz2_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
22 changes: 22 additions & 0 deletions ext/bz2/tests/bug81092.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
Bug #81092 (fflush before stream_filter_remove corrupts stream)
--SKIPIF--
<?php
if (!extension_loaded('bz2')) die('skip bz2 extension not available');
?>
--FILE--
<?php
$stream = fopen(__DIR__ . "/81092.bz2", 'wb+');
$filter = stream_filter_append($stream, 'bzip2.compress', STREAM_FILTER_WRITE, ['blocks' => 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--
<?php
@unlink(__DIR__ . "/81092.bz2");
?>
--EXPECT--
int(8192)

0 comments on commit a1738d8

Please sign in to comment.