diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/zlib.xml | 8 | ||||
-rw-r--r-- | erts/emulator/nifs/common/zlib_nif.c | 255 | ||||
-rw-r--r-- | erts/preloaded/ebin/zlib.beam | bin | 8104 -> 19120 bytes | |||
-rw-r--r-- | erts/preloaded/src/zlib.erl | 14 |
4 files changed, 152 insertions, 125 deletions
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml index 9c3e97d814..f5cc1b1e64 100644 --- a/erts/doc/src/zlib.xml +++ b/erts/doc/src/zlib.xml @@ -65,13 +65,17 @@ list_to_binary([Compressed|Last])</pre> <tag><c>badarg</c></tag> <item>Bad argument. </item> + <tag><c>not_initialized</c></tag> + <item>The stream hasn't been initialized, eg. if + <seealso marker="#inflateInit/1"><c>inflateInit/1</c></seealso> wasn't + called prior to a call to + <seealso marker="#inflate/2"><c>inflate/2</c></seealso>. + </item> <tag><c>data_error</c></tag> <item>The data contains errors. </item> <tag><c>stream_error</c></tag> <item>Inconsistent stream state.</item> - <tag><c>einval</c></tag> - <item>Bad value or wrong function called.</item> <tag><c>{need_dictionary,Adler32}</c></tag> <item>See <seealso marker="#inflate/2"><c>inflate/2</c></seealso>. </item> diff --git a/erts/emulator/nifs/common/zlib_nif.c b/erts/emulator/nifs/common/zlib_nif.c index cffb3f3f63..b7f3adaffe 100644 --- a/erts/emulator/nifs/common/zlib_nif.c +++ b/erts/emulator/nifs/common/zlib_nif.c @@ -48,13 +48,22 @@ static void unload(ErlNifEnv *env, void* priv_data); static ErlNifResourceType *rtype_zlib; +static ERL_NIF_TERM am_not_on_controlling_process; + +static ERL_NIF_TERM am_not_initialized; +static ERL_NIF_TERM am_already_initialized; + static ERL_NIF_TERM am_ok; static ERL_NIF_TERM am_error; + static ERL_NIF_TERM am_continue; static ERL_NIF_TERM am_finished; -static ERL_NIF_TERM am_empty; + static ERL_NIF_TERM am_not_supported; static ERL_NIF_TERM am_need_dictionary; + +static ERL_NIF_TERM am_empty; + static ERL_NIF_TERM am_stream_end; static ERL_NIF_TERM am_stream_error; static ERL_NIF_TERM am_data_error; @@ -173,13 +182,23 @@ static void gc_zlib(ErlNifEnv *env, void* data); static int load(ErlNifEnv *env, void** priv_data, ERL_NIF_TERM load_info) { + am_not_on_controlling_process = + enif_make_atom(env, "not_on_controlling_process"); + + am_not_initialized = enif_make_atom(env, "not_initialized"); + am_already_initialized = enif_make_atom(env, "already_initialized"); + am_ok = enif_make_atom(env, "ok"); am_error = enif_make_atom(env, "error"); - am_empty = enif_make_atom(env, "empty"); + am_continue = enif_make_atom(env, "continue"); am_finished = enif_make_atom(env, "finished"); - am_need_dictionary = enif_make_atom(env, "need_dictionary"); + am_not_supported = enif_make_atom(env, "not_supported"); + am_need_dictionary = enif_make_atom(env, "need_dictionary"); + + am_empty = enif_make_atom(env, "empty"); + am_stream_end = enif_make_atom(env, "stream_end"); am_stream_error = enif_make_atom(env, "stream_error"); am_data_error = enif_make_atom(env, "data_error"); @@ -235,14 +254,11 @@ static ERL_NIF_TERM zlib_return(ErlNifEnv *env, int code) { break; case Z_ERRNO: reason = enif_make_int(env, errno); - //enif_make_tuple2(env, enif_make_int(env, err), reason); break; case Z_STREAM_ERROR: - //reason = am_stream_error; reason = enif_raise_exception(env, am_stream_error); break; case Z_DATA_ERROR: - //reason = am_data_error; reason = enif_raise_exception(env, am_data_error); break; case Z_MEM_ERROR: @@ -281,6 +297,19 @@ static void gc_zlib(ErlNifEnv *env, void* data) { } } +static int get_zlib_data(ErlNifEnv *env, ERL_NIF_TERM opaque, zlib_data_t **d) { + return enif_get_resource(env, opaque, rtype_zlib, (void **)d); +} + +static int zlib_process_check(ErlNifEnv *env, zlib_data_t *d) { + ErlNifPid current_process; + + enif_self(env, ¤t_process); + + return enif_is_identical(enif_make_pid(env, ¤t_process), + enif_make_pid(env, &d->controlling_process)); +} + static void zlib_reset_input(zlib_data_t *d) { enif_ioq_destroy(d->input_queue); d->input_queue = enif_ioq_create(ERL_NIF_IOQ_NORMAL); @@ -292,19 +321,6 @@ static void zlib_reset_input(zlib_data_t *d) { } } -static int get_zlib_data(ErlNifEnv* env, ERL_NIF_TERM opaque, zlib_data_t **d) { - ErlNifPid current_process; - - if(!enif_get_resource(env, opaque, rtype_zlib, (void **)d)) { - return 0; - } - - enif_self(env, ¤t_process); - - return enif_is_identical(enif_make_pid(env, ¤t_process), - enif_make_pid(env, &(*d)->controlling_process)); -} - static int zlib_flush_queue(int (*codec)(z_stream*, int), ErlNifEnv *env, zlib_data_t *d, size_t input_limit, ErlNifBinary *output_buffer, int flush, size_t *bytes_produced, size_t *bytes_consumed, size_t *bytes_remaining) { @@ -438,6 +454,8 @@ static ERL_NIF_TERM zlib_getStash(ErlNifEnv *env, int argc, const ERL_NIF_TERM a if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); } if(d->stash_env == NULL) { @@ -452,10 +470,10 @@ static ERL_NIF_TERM zlib_clearStash(ErlNifEnv *env, int argc, const ERL_NIF_TERM if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->stash_env == NULL) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->stash_env == NULL) { + return enif_raise_exception(env, am_error); } enif_free_env(d->stash_env); @@ -470,10 +488,10 @@ static ERL_NIF_TERM zlib_setStash(ErlNifEnv *env, int argc, const ERL_NIF_TERM a if(argc != 2 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->stash_env != NULL) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->stash_env != NULL) { + return enif_raise_exception(env, am_error); } d->stash_env = enif_alloc_env(); @@ -526,10 +544,10 @@ static ERL_NIF_TERM zlib_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv /* strictly speaking not needed since the gc will handle this */ if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state == ST_CLOSED) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state == ST_CLOSED) { + return enif_raise_exception(env, am_not_initialized); } gc_zlib(env, d); @@ -546,10 +564,10 @@ static ERL_NIF_TERM zlib_deflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TER if(argc != 2 || !get_zlib_data(env, argv[0], &d) || !enif_get_int(env, argv[1], &level)) { return enif_make_badarg(env); - } - - if(d->state != ST_NONE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_NONE) { + return enif_raise_exception(env, am_already_initialized); } res = deflateInit(&d->s, level); @@ -586,10 +604,10 @@ static ERL_NIF_TERM zlib_deflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TE || !enif_get_int(env, argv[4], &memLevel) || !enif_get_int(env, argv[5], &strategy)) { return enif_make_badarg(env); - } - - if(d->state != ST_NONE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_NONE) { + return enif_raise_exception(env, am_already_initialized); } res = deflateInit2(&d->s, level, method, windowBits, memLevel, strategy); @@ -618,10 +636,10 @@ static ERL_NIF_TERM zlib_deflateSetDictionary(ErlNifEnv *env, int argc, const ER if(argc != 2 || !get_zlib_data(env, argv[0], &d) || !enif_inspect_iolist_as_binary(env, argv[1], &bin)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE) { + return enif_raise_exception(env, am_not_initialized); } if((res = deflateSetDictionary(&d->s, bin.data, bin.size)) == Z_OK) { @@ -645,10 +663,10 @@ static ERL_NIF_TERM zlib_deflateReset(ErlNifEnv *env, int argc, const ERL_NIF_TE if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE) { + return enif_raise_exception(env, am_not_initialized); } res = deflateReset(&d->s); @@ -667,10 +685,10 @@ static ERL_NIF_TERM zlib_deflateEnd(ErlNifEnv *env, int argc, const ERL_NIF_TERM if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE) { + return enif_raise_exception(env, am_not_initialized); } res = deflateEnd(&d->s); @@ -693,10 +711,10 @@ static ERL_NIF_TERM zlib_deflateParams(ErlNifEnv *env, int argc, const ERL_NIF_T || !enif_get_int(env, argv[1], &level) || !enif_get_int(env, argv[2], &strategy)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE) { + return enif_raise_exception(env, am_not_initialized); } /* deflateParams will flush everything currently in the stream, corrupting @@ -718,10 +736,10 @@ static ERL_NIF_TERM zlib_deflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar || !enif_get_int(env, argv[2], &output_chunk_size) || !enif_get_int(env, argv[3], &flush)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE) { + return enif_raise_exception(env, am_not_initialized); } return zlib_codec(&deflate, env, d, input_chunk_size, output_chunk_size, flush); @@ -735,10 +753,10 @@ static ERL_NIF_TERM zlib_inflateInit(ErlNifEnv *env, int argc, const ERL_NIF_TER if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_NONE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_NONE) { + return enif_raise_exception(env, am_already_initialized); } res = inflateInit(&d->s); @@ -765,10 +783,10 @@ static ERL_NIF_TERM zlib_inflateInit2(ErlNifEnv *env, int argc, const ERL_NIF_TE if(argc != 2 || !get_zlib_data(env, argv[0], &d) || !enif_get_int(env, argv[1], &windowBits)) { return enif_make_badarg(env); - } - - if(d->state != ST_NONE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_NONE) { + return enif_raise_exception(env, am_already_initialized); } res = inflateInit2(&d->s, windowBits); @@ -797,10 +815,10 @@ static ERL_NIF_TERM zlib_inflateSetDictionary(ErlNifEnv *env, int argc, const ER if(argc != 2 || !get_zlib_data(env, argv[0], &d) || !enif_inspect_iolist_as_binary(env, argv[1], &bin)) { return enif_make_badarg(env); - } - - if(d->state != ST_INFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } res = inflateSetDictionary(&d->s, bin.data, bin.size); @@ -827,55 +845,51 @@ static int zlib_supports_inflateGetDictionary(void) { return supportsGetDictionary; } +#endif static ERL_NIF_TERM zlib_inflateGetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { zlib_data_t *d; - ErlNifBinary obin; - uInt len; - int res; if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } - if(d->state != ST_INFLATE) { - return enif_make_badarg(env); - } +#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY + if(zlib_supports_inflateGetDictionary()) { + ErlNifBinary obin; + uInt len; + int res; - if(!zlib_supports_inflateGetDictionary()) { - return enif_make_badarg(env); - } + enif_alloc_binary(INFL_DICT_SZ, &obin); + len = 0; - enif_alloc_binary(INFL_DICT_SZ, &obin); + if((res = inflateGetDictionary(&d->s, obin.data, &len)) < 0) { + enif_release_binary(&obin); + return zlib_return(env, res); + } - len = 0; - if((res = inflateGetDictionary(&d->s, obin.data, &len)) < 0) { - enif_release_binary(&obin); - return zlib_return(env, res); + enif_realloc_binary(&obin, (size_t)len); + return enif_make_binary(env, &obin); } +#endif - enif_realloc_binary(&obin, (size_t)len); - return enif_make_binary(env, &obin); -} - -#else /* !HAVE_ZLIB_INFLATEGETDICTIONARY */ - -static ERL_NIF_TERM zlib_inflateGetDictionary(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { - return enif_make_badarg(env); + return enif_raise_exception(env, am_not_supported); } -#endif - static ERL_NIF_TERM zlib_inflateReset(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { zlib_data_t *d; int res; if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_INFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } res = inflateReset(&d->s); @@ -894,10 +908,10 @@ static ERL_NIF_TERM zlib_inflateEnd(ErlNifEnv *env, int argc, const ERL_NIF_TERM if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_INFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } res = inflateEnd(&d->s); @@ -922,10 +936,10 @@ static ERL_NIF_TERM zlib_inflate(ErlNifEnv *env, int argc, const ERL_NIF_TERM ar || !enif_get_int(env, argv[2], &output_chunk_size) || !enif_get_int(env, argv[3], &flush)) { return enif_make_badarg(env); - } - - if(d->state != ST_INFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } return zlib_codec(&inflate, env, d, input_chunk_size, output_chunk_size, flush); @@ -936,6 +950,8 @@ static ERL_NIF_TERM zlib_crc32(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); } if(d->state == ST_DEFLATE) { @@ -944,7 +960,7 @@ static ERL_NIF_TERM zlib_crc32(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv return enif_make_ulong(env, d->output_crc); } - return enif_make_badarg(env); + return enif_raise_exception(env, am_not_initialized); } static ERL_NIF_TERM zlib_getBufSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { @@ -952,6 +968,8 @@ static ERL_NIF_TERM zlib_getBufSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM if(argc != 1 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); } return enif_make_int(env, d->inflateChunk_buffer_size); @@ -960,8 +978,13 @@ static ERL_NIF_TERM zlib_getBufSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM static ERL_NIF_TERM zlib_setBufSize(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { zlib_data_t *d; - if(argc != 2 || !get_zlib_data(env, argv[0], &d) - || !enif_get_int(env, argv[1], &d->inflateChunk_buffer_size)) { + if(argc != 2 || !get_zlib_data(env, argv[0], &d)) { + return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } + + if(!enif_get_int(env, argv[1], &d->inflateChunk_buffer_size)) { return enif_make_badarg(env); } @@ -976,17 +999,15 @@ static ERL_NIF_TERM zlib_enqueue_input(ErlNifEnv *env, int argc, const ERL_NIF_T if(argc != 2 || !get_zlib_data(env, argv[0], &d)) { return enif_make_badarg(env); - } - - if(d->state != ST_DEFLATE && d->state != ST_INFLATE) { - return enif_make_badarg(env); + } else if(!zlib_process_check(env, d)) { + return enif_raise_exception(env, am_not_on_controlling_process); + } else if(d->state != ST_DEFLATE && d->state != ST_INFLATE) { + return enif_raise_exception(env, am_not_initialized); } if(!enif_inspect_iovec(env, 256, argv[1], &tail, &iovec)) { return enif_make_badarg(env); - } - - if(!enif_ioq_enqv(d->input_queue, iovec, 0)) { + } else if(!enif_ioq_enqv(d->input_queue, iovec, 0)) { return enif_make_badarg(env); } diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam Binary files differindex 173020b00d..267b5cb0a8 100644 --- a/erts/preloaded/ebin/zlib.beam +++ b/erts/preloaded/ebin/zlib.beam diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl index 2731dddcb5..dca5a42779 100644 --- a/erts/preloaded/src/zlib.erl +++ b/erts/preloaded/src/zlib.erl @@ -634,34 +634,34 @@ arg_flush(none) -> ?Z_NO_FLUSH; arg_flush(sync) -> ?Z_SYNC_FLUSH; arg_flush(full) -> ?Z_FULL_FLUSH; arg_flush(finish) -> ?Z_FINISH; -arg_flush(_) -> erlang:error(badarg). +arg_flush(_) -> erlang:error(bad_flush_mode). arg_level(none) -> ?Z_NO_COMPRESSION; arg_level(best_speed) -> ?Z_BEST_SPEED; arg_level(best_compression) -> ?Z_BEST_COMPRESSION; arg_level(default) -> ?Z_DEFAULT_COMPRESSION; arg_level(Level) when is_integer(Level), Level >= 0, Level =< 9 -> Level; -arg_level(_) -> erlang:error(badarg). +arg_level(_) -> erlang:error(bad_compression_level). arg_strategy(filtered) -> ?Z_FILTERED; arg_strategy(huffman_only) -> ?Z_HUFFMAN_ONLY; arg_strategy(rle) -> ?Z_RLE; arg_strategy(default) -> ?Z_DEFAULT_STRATEGY; -arg_strategy(_) -> erlang:error(badarg). +arg_strategy(_) -> erlang:error(bad_compression_strategy). arg_method(deflated) -> ?Z_DEFLATED; -arg_method(_) -> erlang:error(badarg). +arg_method(_) -> erlang:error(bad_compression_method). -spec arg_bitsz(zwindowbits()) -> zwindowbits(). arg_bitsz(Bits) when is_integer(Bits) andalso ((8 =< Bits andalso Bits < 48) orelse (-15 =< Bits andalso Bits =< -8)) -> Bits; -arg_bitsz(_) -> erlang:error(badarg). +arg_bitsz(_) -> erlang:error(bad_windowbits). -spec arg_mem(zmemlevel()) -> zmemlevel(). arg_mem(Level) when is_integer(Level), 1 =< Level, Level =< 9 -> Level; -arg_mem(_) -> erlang:error(badarg). +arg_mem(_) -> erlang:error(bad_memlevel). -spec enqueue_input(Z, IOData) -> ok when Z :: zstream(), @@ -669,6 +669,8 @@ arg_mem(_) -> erlang:error(badarg). enqueue_input(Z, IOData) -> enqueue_input_1(Z, erlang:iolist_to_iovec(IOData)). +enqueue_input_1(_Z, []) -> + ok; enqueue_input_1(Z, IOVec) -> case enqueue_nif(Z, IOVec) of {continue, Remainder} -> enqueue_input_1(Z, Remainder); |