Fix buffer sizing for LZ4.
Fix exit condition checks in LZ4 decompression wrapper.
This commit is contained in:
parent
f9215b53fb
commit
2cbcb0c9e4
3 changed files with 50 additions and 10 deletions
|
@ -32,6 +32,8 @@
|
|||
#include <lz4hc.h>
|
||||
#include <allocator.h>
|
||||
|
||||
#define LZ4_MAX_CHUNK 2147450621L
|
||||
|
||||
struct lz4_params {
|
||||
int level;
|
||||
};
|
||||
|
@ -41,14 +43,23 @@ lz4_stats(int show)
|
|||
{
|
||||
}
|
||||
|
||||
int
|
||||
lz4_buf_extra(ssize_t buflen)
|
||||
{
|
||||
if (buflen > LZ4_MAX_CHUNK)
|
||||
buflen = LZ4_MAX_CHUNK;
|
||||
return (LZ4_compressBound(buflen) - buflen + sizeof(int));
|
||||
}
|
||||
|
||||
int
|
||||
lz4_init(void **data, int *level, ssize_t chunksize)
|
||||
{
|
||||
struct lz4_params *lzdat;
|
||||
int lev;
|
||||
|
||||
if (chunksize > INT_MAX) {
|
||||
fprintf(stderr, "Chunk size too big for LZ4.\n");
|
||||
if (chunksize > LZ4_MAX_CHUNK) {
|
||||
fprintf(stderr, "Max allowed chunk size for LZ4 is: %d \n",
|
||||
LZ4_MAX_CHUNK);
|
||||
return (1);
|
||||
}
|
||||
lzdat = slab_alloc(NULL, sizeof (struct lz4_params));
|
||||
|
@ -85,12 +96,13 @@ lz4_compress(void *src, size_t srclen, void *dst, size_t *dstlen,
|
|||
|
||||
if (lzdat->level == 1) {
|
||||
rv = LZ4_compress(src, dst, _srclen);
|
||||
|
||||
} else if (lzdat->level == 2) {
|
||||
rv = LZ4_compress(src, dst, _srclen);
|
||||
if (rv == 0) {
|
||||
if (rv == 0 || rv > *dstlen) {
|
||||
return (-1);
|
||||
}
|
||||
dst2 = slab_alloc(NULL, rv + sizeof (int));
|
||||
dst2 = slab_alloc(NULL, rv + sizeof (int) + LZ4_compressBound(rv));
|
||||
*((int *)dst2) = htonl(rv);
|
||||
rv = LZ4_compressHC(dst, dst2 + sizeof (int), rv);
|
||||
if (rv != 0) {
|
||||
|
@ -120,20 +132,23 @@ lz4_decompress(void *src, size_t srclen, void *dst, size_t *dstlen,
|
|||
|
||||
if (lzdat->level == 1 || lzdat->level == 3) {
|
||||
rv = LZ4_uncompress(src, dst, _dstlen);
|
||||
if (rv != srclen) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
} else if (lzdat->level == 2) {
|
||||
int sz1;
|
||||
|
||||
sz1 = ntohl(*((int *)src));
|
||||
rv = LZ4_uncompress(src + sizeof (int), dst, sz1);
|
||||
if (rv != sz1) {
|
||||
if (rv != srclen - sizeof (int)) {
|
||||
return (-1);
|
||||
}
|
||||
memcpy(src, dst, sz1);
|
||||
rv = LZ4_uncompress(src, dst, _dstlen);
|
||||
}
|
||||
if (rv != srclen) {
|
||||
return (-1);
|
||||
if (rv != sz1) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
28
main.c
28
main.c
|
@ -398,8 +398,20 @@ start_decompress(const char *filename, const char *to_filename)
|
|||
goto uncomp_done;
|
||||
}
|
||||
|
||||
compressed_chunksize = chunksize + (chunksize >> 6) + sizeof (uint64_t)
|
||||
+ sizeof (chunksize);
|
||||
compressed_chunksize = chunksize + sizeof (chunksize) +
|
||||
sizeof (uint64_t) + sizeof (chunksize) + zlib_buf_extra(chunksize);
|
||||
|
||||
/*
|
||||
* Adjust for LZ4 overflow size if LZ4 was selected.
|
||||
* TODO: A more generic way to handle this for various algos. I'm too
|
||||
* lazy to do this at present.
|
||||
*/
|
||||
if (strncmp(algo, "lz4", 3) == 0) {
|
||||
if (chunksize + lz4_buf_extra(chunksize) > compressed_chunksize) {
|
||||
compressed_chunksize += (chunksize + lz4_buf_extra(chunksize) -
|
||||
compressed_chunksize);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FLAG_DEDUP) {
|
||||
enable_rabin_scan = 1;
|
||||
|
@ -804,6 +816,18 @@ start_compress(const char *filename, uint64_t chunksize, int level)
|
|||
compressed_chunksize = chunksize + sizeof (chunksize) +
|
||||
sizeof (uint64_t) + sizeof (chunksize) + zlib_buf_extra(chunksize);
|
||||
|
||||
/*
|
||||
* Adjust for LZ4 overflow size if LZ4 was selected.
|
||||
* TODO: A more generic way to handle this for various algos. I'm too
|
||||
* lazy to do this at present.
|
||||
*/
|
||||
if (strncmp(algo, "lz4", 3) == 0) {
|
||||
if (chunksize + lz4_buf_extra(chunksize) > compressed_chunksize) {
|
||||
compressed_chunksize += (chunksize + lz4_buf_extra(chunksize) -
|
||||
compressed_chunksize);
|
||||
}
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
if (enable_rabin_scan) {
|
||||
flags |= FLAG_DEDUP;
|
||||
|
|
|
@ -56,6 +56,7 @@ extern uint64_t lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc);
|
|||
extern uint64_t lzma_crc64_8bchk(const uint8_t *buf, size_t size,
|
||||
uint64_t crc, uint64_t *cnt);
|
||||
extern uint32_t zlib_buf_extra(ssize_t buflen);
|
||||
extern int lz4_buf_extra(ssize_t buflen);
|
||||
|
||||
extern int zlib_compress(void *src, size_t srclen, void *dst,
|
||||
size_t *destlen, int level, uchar_t chdr, void *data);
|
||||
|
|
Loading…
Reference in a new issue