summaryrefslogtreecommitdiff
path: root/ext/bz2/bz2_filter.c
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2021-02-22 15:31:49 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2021-02-22 15:32:17 +0100
commitb418fe266dd3ab56358469ed8290187959bad1a7 (patch)
treee178ca08896c572e1df488e1f44a65dc3c67d236 /ext/bz2/bz2_filter.c
parent1d2bbce532a4383210e97ce6b00e210ef2cbaae7 (diff)
parent963e50c8c48ecfbe7444445e5ca8e33530d630d0 (diff)
downloadphp-git-b418fe266dd3ab56358469ed8290187959bad1a7.tar.gz
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix #75776: Flushing streams with compression filter is broken
Diffstat (limited to 'ext/bz2/bz2_filter.c')
-rw-r--r--ext/bz2/bz2_filter.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c
index 0cb1729e00..24cb909b18 100644
--- a/ext/bz2/bz2_filter.c
+++ b/ext/bz2/bz2_filter.c
@@ -39,6 +39,7 @@ typedef struct _php_bz2_filter_data {
enum strm_status status; /* Decompress option */
unsigned int small_footprint : 1; /* Decompress option */
unsigned int expect_concatenated : 1; /* Decompress option */
+ unsigned int is_flushed : 1; /* only for compression */
int persistent;
} php_bz2_filter_data;
@@ -227,6 +228,8 @@ static php_stream_filter_status_t php_bz2_compress_filter(
bucket = php_stream_bucket_make_writeable(buckets_in->head);
while (bin < bucket->buflen) {
+ int flush_mode;
+
desired = bucket->buflen - bin;
if (desired > data->inbuf_len) {
desired = data->inbuf_len;
@@ -234,7 +237,9 @@ static php_stream_filter_status_t php_bz2_compress_filter(
memcpy(data->strm.next_in, bucket->buf + bin, desired);
data->strm.avail_in = desired;
- status = BZ2_bzCompress(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN));
+ flush_mode = flags & PSFS_FLAG_FLUSH_CLOSE ? BZ_FINISH : (flags & PSFS_FLAG_FLUSH_INC ? BZ_FLUSH : BZ_RUN);
+ data->is_flushed = flush_mode != BZ_RUN;
+ status = BZ2_bzCompress(&(data->strm), flush_mode);
if (status != BZ_RUN_OK && status != BZ_FLUSH_OK && status != BZ_FINISH_OK) {
/* Something bad happened */
php_stream_bucket_delref(bucket);
@@ -260,11 +265,12 @@ static php_stream_filter_status_t php_bz2_compress_filter(
php_stream_bucket_delref(bucket);
}
- if (flags & PSFS_FLAG_FLUSH_CLOSE) {
+ 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) {
- status = BZ2_bzCompress(&(data->strm), BZ_FINISH);
+ 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) {
size_t bucketlen = data->outbuf_len - data->strm.avail_out;
@@ -380,6 +386,7 @@ static php_stream_filter *php_bz2_filter_create(const char *filtername, zval *fi
}
status = BZ2_bzCompressInit(&(data->strm), blockSize100k, 0, workFactor);
+ data->is_flushed = 1;
fops = &php_bz2_compress_ops;
} else {
status = BZ_DATA_ERROR;