diff options
Diffstat (limited to 'src/Common/libzip/zip_algorithm_deflate.c')
-rw-r--r-- | src/Common/libzip/zip_algorithm_deflate.c | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/src/Common/libzip/zip_algorithm_deflate.c b/src/Common/libzip/zip_algorithm_deflate.c index d28a1ac5..03250ef9 100644 --- a/src/Common/libzip/zip_algorithm_deflate.c +++ b/src/Common/libzip/zip_algorithm_deflate.c @@ -1,9 +1,9 @@ /* zip_algorithm_deflate.c -- deflate (de)compression routines - Copyright (C) 2017-2019 Dieter Baron and Thomas Klausner + Copyright (C) 2017-2021 Dieter Baron and Thomas Klausner This file is part of libzip, a library to manipulate ZIP archives. - The authors can be contacted at <libzip@nih.at> + The authors can be contacted at <info@libzip.org> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -46,20 +46,33 @@ struct ctx { }; +static zip_uint64_t +maximum_compressed_size(zip_uint64_t uncompressed_size) { + /* max deflate size increase: size + ceil(size/16k)*5+6 */ + + zip_uint64_t compressed_size = uncompressed_size + (uncompressed_size + 16383) / 16384 * 5 + 6; + + if (compressed_size < uncompressed_size) { + return ZIP_UINT64_MAX; + } + return compressed_size; +} + + static void * allocate(bool compress, int compression_flags, zip_error_t *error) { struct ctx *ctx; if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) { - zip_error_set(error, ZIP_ET_SYS, errno); - return NULL; + zip_error_set(error, ZIP_ET_SYS, errno); + return NULL; } ctx->error = error; ctx->compress = compress; ctx->compression_flags = compression_flags; if (ctx->compression_flags < 1 || ctx->compression_flags > 9) { - ctx->compression_flags = Z_BEST_COMPRESSION; + ctx->compression_flags = Z_BEST_COMPRESSION; } ctx->end_of_input = false; @@ -96,21 +109,21 @@ general_purpose_bit_flags(void *ud) { struct ctx *ctx = (struct ctx *)ud; if (!ctx->compress) { - return 0; + return 0; } if (ctx->compression_flags < 3) { - return 2 << 1; + return 2 << 1; } else if (ctx->compression_flags > 7) { - return 1 << 1; + return 1 << 1; } return 0; } static bool -start(void *ud) { +start(void *ud, zip_stat_t *st, zip_file_attributes_t *attributes) { struct ctx *ctx = (struct ctx *)ud; int ret; @@ -120,16 +133,16 @@ start(void *ud) { ctx->zstr.next_out = NULL; if (ctx->compress) { - /* negative value to tell zlib not to write a header */ - ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); + /* negative value to tell zlib not to write a header */ + ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY); } else { - ret = inflateInit2(&ctx->zstr, -MAX_WBITS); + ret = inflateInit2(&ctx->zstr, -MAX_WBITS); } if (ret != Z_OK) { - zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); - return false; + zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); + return false; } @@ -143,15 +156,15 @@ end(void *ud) { int err; if (ctx->compress) { - err = deflateEnd(&ctx->zstr); + err = deflateEnd(&ctx->zstr); } else { - err = inflateEnd(&ctx->zstr); + err = inflateEnd(&ctx->zstr); } if (err != Z_OK) { - zip_error_set(ctx->error, ZIP_ER_ZLIB, err); - return false; + zip_error_set(ctx->error, ZIP_ER_ZLIB, err); + return false; } return true; @@ -163,8 +176,8 @@ input(void *ud, zip_uint8_t *data, zip_uint64_t length) { struct ctx *ctx = (struct ctx *)ud; if (length > UINT_MAX || ctx->zstr.avail_in > 0) { - zip_error_set(ctx->error, ZIP_ER_INVAL, 0); - return false; + zip_error_set(ctx->error, ZIP_ER_INVAL, 0); + return false; } ctx->zstr.avail_in = (uInt)length; @@ -192,37 +205,38 @@ process(void *ud, zip_uint8_t *data, zip_uint64_t *length) { ctx->zstr.next_out = (Bytef *)data; if (ctx->compress) { - ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0); + ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0); } else { - ret = inflate(&ctx->zstr, Z_SYNC_FLUSH); + ret = inflate(&ctx->zstr, Z_SYNC_FLUSH); } *length = *length - ctx->zstr.avail_out; switch (ret) { case Z_OK: - return ZIP_COMPRESSION_OK; + return ZIP_COMPRESSION_OK; case Z_STREAM_END: - return ZIP_COMPRESSION_END; + return ZIP_COMPRESSION_END; case Z_BUF_ERROR: - if (ctx->zstr.avail_in == 0) { - return ZIP_COMPRESSION_NEED_DATA; - } + if (ctx->zstr.avail_in == 0) { + return ZIP_COMPRESSION_NEED_DATA; + } - /* fallthrough */ + /* fallthrough */ default: - zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); - return ZIP_COMPRESSION_ERROR; + zip_error_set(ctx->error, ZIP_ER_ZLIB, ret); + return ZIP_COMPRESSION_ERROR; } } /* clang-format off */ zip_compression_algorithm_t zip_algorithm_deflate_compress = { + maximum_compressed_size, compress_allocate, deallocate, general_purpose_bit_flags, @@ -236,6 +250,7 @@ zip_compression_algorithm_t zip_algorithm_deflate_compress = { zip_compression_algorithm_t zip_algorithm_deflate_decompress = { + maximum_compressed_size, decompress_allocate, deallocate, general_purpose_bit_flags, |