Add function libdeflate_zlib_decompress_ex

Additionally, libdeflate_zlib_decompress now returns successfully in
case there are additional trailing bytes in the input buffer after the
compressed stream.
This commit is contained in:
Izumi Raine 2020-04-12 00:01:34 +02:00
parent b255565de2
commit 5ed95f48d4
No known key found for this signature in database
GPG Key ID: 8F2C635521BC1EBB
2 changed files with 37 additions and 7 deletions

View File

@ -33,14 +33,16 @@
#include "libdeflate.h"
LIBDEFLATEEXPORT enum libdeflate_result LIBDEFLATEAPI
libdeflate_zlib_decompress(struct libdeflate_decompressor *d,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_out_nbytes_ret)
libdeflate_zlib_decompress_ex(struct libdeflate_decompressor *d,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_in_nbytes_ret,
size_t *actual_out_nbytes_ret)
{
const u8 *in_next = in;
const u8 * const in_end = in_next + in_nbytes;
u16 hdr;
size_t actual_in_nbytes;
size_t actual_out_nbytes;
enum libdeflate_result result;
@ -68,10 +70,10 @@ libdeflate_zlib_decompress(struct libdeflate_decompressor *d,
return LIBDEFLATE_BAD_DATA;
/* Compressed data */
result = libdeflate_deflate_decompress(d, in_next,
result = libdeflate_deflate_decompress_ex(d, in_next,
in_end - ZLIB_FOOTER_SIZE - in_next,
out, out_nbytes_avail,
actual_out_nbytes_ret);
&actual_in_nbytes, actual_out_nbytes_ret);
if (result != LIBDEFLATE_SUCCESS)
return result;
@ -80,12 +82,27 @@ libdeflate_zlib_decompress(struct libdeflate_decompressor *d,
else
actual_out_nbytes = out_nbytes_avail;
in_next = in_end - ZLIB_FOOTER_SIZE;
in_next += actual_in_nbytes;
/* ADLER32 */
if (libdeflate_adler32(1, out, actual_out_nbytes) !=
get_unaligned_be32(in_next))
return LIBDEFLATE_BAD_DATA;
in_next += 4;
if (actual_in_nbytes_ret)
*actual_in_nbytes_ret = in_next - (u8 *)in;
return LIBDEFLATE_SUCCESS;
}
LIBDEFLATEEXPORT enum libdeflate_result LIBDEFLATEAPI
libdeflate_zlib_decompress(struct libdeflate_decompressor *d,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_out_nbytes_ret)
{
return libdeflate_zlib_decompress_ex(d, in, in_nbytes,
out, out_nbytes_avail,
NULL, actual_out_nbytes_ret);
}

View File

@ -262,6 +262,19 @@ libdeflate_zlib_decompress(struct libdeflate_decompressor *decompressor,
void *out, size_t out_nbytes_avail,
size_t *actual_out_nbytes_ret);
/*
* Like libdeflate_zlib_decompress(), but adds the 'actual_in_nbytes_ret'
* argument. If 'actual_in_nbytes_ret' is not NULL and the decompression
* succeeds, then the actual number of input bytes consumed is written to
* actual_in_nbytes_ret.
*/
LIBDEFLATEEXPORT enum libdeflate_result LIBDEFLATEAPI
libdeflate_zlib_decompress_ex(struct libdeflate_decompressor *decompressor,
const void *in, size_t in_nbytes,
void *out, size_t out_nbytes_avail,
size_t *actual_in_nbytes_ret,
size_t *actual_out_nbytes_ret);
/*
* Like libdeflate_deflate_decompress(), but assumes the gzip wrapper format
* instead of raw DEFLATE.