diff options
Diffstat (limited to 'ext/zlib/zlib.c')
| -rw-r--r-- | ext/zlib/zlib.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index a067e43d36..8e1b80cb6e 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1115,7 +1115,7 @@ PHP_FUNCTION(deflate_add) { zend_string *out; char *in_buf; - size_t in_len, out_size; + size_t in_len, out_size, buffer_used; zval *res; z_stream *ctx; zend_long flush_type = Z_SYNC_FLUSH; @@ -1157,6 +1157,7 @@ PHP_FUNCTION(deflate_add) out_size = PHP_ZLIB_BUFFER_SIZE_GUESS(ctx->total_in + in_len); out_size = (ctx->total_out >= out_size) ? 16 : (out_size - ctx->total_out); out_size = (out_size < 16) ? 16 : out_size; + out_size += 64; out = zend_string_alloc(out_size, 0); ctx->next_in = (Bytef *) in_buf; @@ -1164,7 +1165,21 @@ PHP_FUNCTION(deflate_add) ctx->avail_in = in_len; ctx->avail_out = ZSTR_LEN(out); - status = deflate(ctx, flush_type); + buffer_used = 0; + + do { + if (ctx->avail_out == 0) { + /* more output buffer space needed; realloc and try again */ + /* adding 64 more bytes solved every issue I have seen */ + /* the + 1 is for the string terminator added below */ + out = zend_string_realloc(out, ZSTR_LEN(out) + 64 + 1, 0); + ctx->avail_out = 64; + ctx->next_out = (Bytef *) ZSTR_VAL(out) + buffer_used; + } + status = deflate(ctx, flush_type); + buffer_used = ZSTR_LEN(out) - ctx->avail_out; + } while (status == Z_OK && ctx->avail_out == 0); + switch (status) { case Z_OK: ZSTR_LEN(out) = (char *) ctx->next_out - ZSTR_VAL(out); |
