Skip to content

Commit fb4bc0f

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix #48725: Support for flushing in zlib stream
2 parents d6ae0f0 + 20e7532 commit fb4bc0f

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ PHP NEWS
6565
- XML:
6666
. XmlParser opaque object renamed to XMLParser for consistency with other XML objects. (girgias)
6767

68+
- Zlib:
69+
. Fixed #48725 (Support for flushing in zlib stream). (cmb)
70+
6871
26 Nov 2020, PHP 8.0.0
6972

7073
- BZ2:

ext/zlib/tests/bug48725.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Bug #48725 (Support for flushing in zlib stream)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('zlib')) die('skip zip extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
$text = str_repeat('0123456789abcdef', 1000);
10+
11+
$temp = fopen('php://temp', 'r+');
12+
stream_filter_append($temp, 'zlib.deflate', STREAM_FILTER_WRITE);
13+
fwrite($temp, $text);
14+
15+
rewind($temp);
16+
17+
var_dump(bin2hex(stream_get_contents($temp)));
18+
var_dump(ftell($temp));
19+
20+
fclose($temp);
21+
?>
22+
--EXPECT--
23+
string(138) "ecc7c901c0100000b09594bac641d97f840e22f9253c31bdb9d4d6c75cdf3ec1ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddaffc0f0000ffff"
24+
int(69)

ext/zlib/zlib_filter.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ typedef struct _php_zlib_filter_data {
2727
unsigned char *outbuf;
2828
size_t outbuf_len;
2929
int persistent;
30-
zend_bool finished;
30+
zend_bool finished; /* for zlib.deflate: signals that no flush is pending */
3131
} php_zlib_filter_data;
3232

3333
/* }}} */
@@ -195,14 +195,18 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
195195
bucket = php_stream_bucket_make_writeable(bucket);
196196

197197
while (bin < (unsigned int) bucket->buflen) {
198+
int flush_mode;
199+
198200
desired = bucket->buflen - bin;
199201
if (desired > data->inbuf_len) {
200202
desired = data->inbuf_len;
201203
}
202204
memcpy(data->strm.next_in, bucket->buf + bin, desired);
203205
data->strm.avail_in = desired;
204206

205-
status = deflate(&(data->strm), flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FULL_FLUSH : (flags & PSFS_FLAG_FLUSH_INC ? Z_SYNC_FLUSH : Z_NO_FLUSH));
207+
flush_mode = flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FULL_FLUSH : (flags & PSFS_FLAG_FLUSH_INC ? Z_SYNC_FLUSH : Z_NO_FLUSH);
208+
data->finished = flush_mode != Z_NO_FLUSH;
209+
status = deflate(&(data->strm), flush_mode);
206210
if (status != Z_OK) {
207211
/* Something bad happened */
208212
php_stream_bucket_delref(bucket);
@@ -229,11 +233,12 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
229233
php_stream_bucket_delref(bucket);
230234
}
231235

232-
if (flags & PSFS_FLAG_FLUSH_CLOSE) {
236+
if (flags & PSFS_FLAG_FLUSH_CLOSE || ((flags & PSFS_FLAG_FLUSH_INC) && !data->finished)) {
233237
/* Spit it out! */
234238
status = Z_OK;
235239
while (status == Z_OK) {
236-
status = deflate(&(data->strm), Z_FINISH);
240+
status = deflate(&(data->strm), (flags & PSFS_FLAG_FLUSH_CLOSE ? Z_FINISH : Z_SYNC_FLUSH));
241+
data->finished = 1;
237242
if (data->strm.avail_out < data->outbuf_len) {
238243
size_t bucketlen = data->outbuf_len - data->strm.avail_out;
239244

@@ -394,6 +399,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
394399
}
395400
}
396401
status = deflateInit2(&(data->strm), level, Z_DEFLATED, windowBits, memLevel, 0);
402+
data->finished = 1;
397403
fops = &php_zlib_deflate_ops;
398404
} else {
399405
status = Z_DATA_ERROR;

0 commit comments

Comments
 (0)