diff options
author | Erlang/OTP <[email protected]> | 2017-11-09 16:15:40 +0100 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2017-11-09 16:15:40 +0100 |
commit | edfbdc2ab46b44d83da7e3de2ae601055a3bcc2f (patch) | |
tree | 6fd54f81f11f9335eb69026d3b3e8632ce17fb73 /erts/emulator/nifs/common/zlib_nif.c | |
parent | 3e8c1ff94c0a73df71daadd4eb782c21c49f22d9 (diff) | |
parent | e96969083dbfebfaaa600d2ba6c2cf6d5a690cbe (diff) | |
download | otp-edfbdc2ab46b44d83da7e3de2ae601055a3bcc2f.tar.gz otp-edfbdc2ab46b44d83da7e3de2ae601055a3bcc2f.tar.bz2 otp-edfbdc2ab46b44d83da7e3de2ae601055a3bcc2f.zip |
Merge branch 'john/erts/zlib-1.2.11-fixes/OTP-14751' into maint-20
* john/erts/zlib-1.2.11-fixes/OTP-14751:
Avoid WindowBits=8 as per the manual
Fix deflateParams on zlib 1.2.11
Diffstat (limited to 'erts/emulator/nifs/common/zlib_nif.c')
-rw-r--r-- | erts/emulator/nifs/common/zlib_nif.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c index fa29b4fb71..9565a5a059 100644 --- a/erts/emulator/nifs/common/zlib_nif.c +++ b/erts/emulator/nifs/common/zlib_nif.c @@ -717,7 +717,9 @@ static ERL_NIF_TERM zlib_deflateEnd(ErlNifEnv *env, int argc, const ERL_NIF_TERM static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { zlib_data_t *d; + int res, level, strategy; + Bytef dummy_buffer; if(argc != 3 || !get_zlib_data(env, argv[0], &d) || !enif_get_int(env, argv[1], &level) @@ -729,12 +731,27 @@ static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_T return enif_raise_exception(env, am_not_initialized); } - /* deflateParams will flush everything currently in the stream, corrupting - * the heap unless it's empty. We therefore pretend to have a full output - * buffer, forcing a Z_BUF_ERROR if there's anything left to be flushed. */ - d->s.avail_out = 0; + /* This is a bit of a hack; deflateParams flushes with Z_BLOCK which won't + * stop at a byte boundary, so we can't split this operation up, and we + * can't allocate a buffer large enough to fit it in one go since we have + * to support zlib versions that lack deflatePending. + * + * We therefore flush everything prior to this call to ensure that we are + * stopped on a byte boundary and have no pending data. We then hand it a + * dummy buffer to detect when this assumption doesn't hold (Hopefully + * never), and to smooth over an issue with zlib 1.2.11 which always + * returns Z_BUF_ERROR when d->s.avail_out is 0, regardless of whether + * there's any pending data or not. */ + + d->s.next_out = &dummy_buffer; + d->s.avail_out = 1; + res = deflateParams(&d->s, level, strategy); + if(d->s.avail_out == 0) { + return zlib_return(env, Z_STREAM_ERROR); + } + return zlib_return(env, res); } |