diff --git a/lib/icu_compress/cmp_icu.c b/lib/icu_compress/cmp_icu.c index c8a74309ae2f3da0c33550c7df90fb556f32abb0..45791ee565469c3c47d3e8f5032a9d69dcf63292 100644 --- a/lib/icu_compress/cmp_icu.c +++ b/lib/icu_compress/cmp_icu.c @@ -1755,23 +1755,23 @@ static uint32_t cmp_collection(const uint8_t *col, cfg->updated_model_buf = updated_model + COLLECTION_HDR_SIZE; /* is enough capacity in the dst buffer to store the data uncompressed */ - if ((!dst || dst_capacity >= dst_size + col_data_length) && + if ((dst == NULL || dst_capacity >= dst_size + col_data_length) && cfg->cmp_mode != CMP_MODE_RAW) { /* we set the compressed buffer size to the data size -1 to provoke * a CMP_ERROR_SMALL_BUF_ error if the data are not compressible */ cfg->stream_size = dst_size + col_data_length - 1; - dst_size_bits = compress_data_internal(cfg, dst_size<<3); + dst_size_bits = compress_data_internal(cfg, dst_size << 3); if (cmp_get_error_code(dst_size_bits) == CMP_ERROR_SMALL_BUF_ || - (!dst && cmp_bit_to_byte(dst_size_bits)-dst_size > col_data_length)) { /* if dst == NULL compress_data_internal will not return a CMP_ERROR_SMALL_BUF */ + (!dst && dst_size_bits > cmp_stream_size_to_bits(cfg->stream_size))) { /* if dst == NULL compress_data_internal will not return a CMP_ERROR_SMALL_BUF */ /* can not compress the data with the given parameters; * put them uncompressed (raw) into the dst buffer */ enum cmp_mode cmp_mode_cpy = cfg->cmp_mode; cfg->stream_size = dst_size + col_data_length; cfg->cmp_mode = CMP_MODE_RAW; - dst_size_bits = compress_data_internal(cfg, dst_size<<3); + dst_size_bits = compress_data_internal(cfg, dst_size << 3); cfg->cmp_mode = cmp_mode_cpy; /* updated model is in this case a copy of the data to compress */ if (model_mode_is_used(cfg->cmp_mode) && cfg->updated_model_buf) @@ -1779,7 +1779,7 @@ static uint32_t cmp_collection(const uint8_t *col, } } else { cfg->stream_size = dst_capacity; - dst_size_bits = compress_data_internal(cfg, dst_size<<3); + dst_size_bits = compress_data_internal(cfg, dst_size << 3); } FORWARD_IF_ERROR(dst_size_bits, "compression failed"); diff --git a/test/fuzz/fuzz_compression.c b/test/fuzz/fuzz_compression.c index 8be34ff2db2cddbc43ac90534e4b900556ce55c2..bde54b3930fb61d89697c8cae7978d0a8135dde2 100644 --- a/test/fuzz/fuzz_compression.c +++ b/test/fuzz/fuzz_compression.c @@ -133,6 +133,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size) default: FUZZ_ASSERT(0); } + if (!cmp_is_error(return_value) && model != up_model){ + uint32_t return_value2; + + return_value2 = compress_chunk(src, (uint32_t)size, model, up_model, + NULL, cmp_data_capacity, cmp_par_ptr); + FUZZ_ASSERT(return_value == return_value2); + } free(cmp_data); free(up_model); diff --git a/test/test_common/chunk_round_trip.c b/test/test_common/chunk_round_trip.c index b51bc48b3bfa59a55439f00b79d3b2ae1d9439ad..f23fcea1575426da7500d1e5c12d3e89ac84c0fe 100644 --- a/test/test_common/chunk_round_trip.c +++ b/test/test_common/chunk_round_trip.c @@ -89,6 +89,21 @@ uint32_t chunk_round_trip(const void *chunk, uint32_t chunk_size, cmp_size = compress_chunk(chunk, chunk_size, chunk_model, updated_chunk_model, dst, dst_capacity, cmp_par); + if (!cmp_is_error(cmp_size)) { /* secound run wich dst = NULL */ + uint32_t cmp_size2; + /* reset model if in-place update was used */ + if (chunk_model && updated_chunk_model == chunk_model) { + memcpy(updated_chunk_model, model_cpy, chunk_size); + } + cmp_size2 = compress_chunk(chunk, chunk_size, chunk_model, updated_chunk_model, + NULL, dst_capacity, cmp_par); + if (cmp_get_error_code(cmp_size) == CMP_ERROR_SMALL_BUF_) { + TEST_ASSERT(!cmp_is_error(cmp_size)); + } else { + TEST_ASSERT(cmp_size == cmp_size2); + } + } + /* decompress the data if the compression was successful */ if (!cmp_is_error(cmp_size) && dst) {