diff options
author | Ingela Anderton Andin <[email protected]> | 2017-11-10 15:38:03 +0100 |
---|---|---|
committer | Ingela Anderton Andin <[email protected]> | 2017-11-10 15:38:03 +0100 |
commit | 3fb3067d953f8be9fe66d3a6687a86be2e8d2f3f (patch) | |
tree | 33825e3233f32dc1916aaf1504b6cdcca0cf33ca /erts/emulator/nifs | |
parent | cca58959662d473bb329e41a84b5b260bf96a26b (diff) | |
parent | 84f29ab803e8f36ef058a47f4c2b224f4dd58220 (diff) | |
download | otp-3fb3067d953f8be9fe66d3a6687a86be2e8d2f3f.tar.gz otp-3fb3067d953f8be9fe66d3a6687a86be2e8d2f3f.tar.bz2 otp-3fb3067d953f8be9fe66d3a6687a86be2e8d2f3f.zip |
Merge branch 'maint-20' into maint
* maint-20:
Updated OTP version
Update release notes
Update version numbers
inets: Prepare for release
inets: Add missing guard
Avoid WindowBits=8 as per the manual
Fix deflateParams on zlib 1.2.11
Ignore empty binaries in enif_inspect_iovec
Emasculate writable binaries on entering an iovec
Only apply EOS behaviors if there's pending data
Stop assuming that all schedulers are managed when updating msacc
Diffstat (limited to 'erts/emulator/nifs')
-rw-r--r-- | erts/emulator/nifs/common/zlib_nif.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c index fa29b4fb71..b709ed5a6f 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); } @@ -929,7 +946,7 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar return enif_raise_exception(env, am_not_initialized); } - if(d->eos_seen) { + if(d->eos_seen && enif_ioq_size(d->input_queue) > 0) { int res; switch(d->eos_behavior) { @@ -943,11 +960,10 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar } d->eos_seen = 0; + break; case EOS_BEHAVIOR_CUT: zlib_reset_input(d); - - return enif_make_tuple2(env, am_finished, enif_make_list(env, 0)); } } |