1
0
mirror of https://github.com/facebook/zstd.git synced 2025-08-08 17:22:10 +03:00

Fix offset overflow bug

This commit is contained in:
Stella Lau
2017-07-07 14:14:01 -07:00
parent f791fc27e3
commit 7945f9ee47
2 changed files with 23 additions and 14 deletions

View File

@@ -11,7 +11,7 @@
#define LDM_HASHTABLESIZE_U32 ((LDM_HASHTABLESIZE) >> 2) #define LDM_HASHTABLESIZE_U32 ((LDM_HASHTABLESIZE) >> 2)
#define LDM_HASH_SIZE_U32 (1 << (LDM_HASHLOG)) #define LDM_HASH_SIZE_U32 (1 << (LDM_HASHLOG))
#define WINDOW_SIZE (1 << 20) #define WINDOW_SIZE (1 << 15)
#define HASH_SIZE 4 #define HASH_SIZE 4
#define MINMATCH 4 #define MINMATCH 4
@@ -144,7 +144,7 @@ static unsigned LDM_count(const BYTE *pIn, const BYTE *pMatch,
void LDM_read_header(void const *source, size_t *compressed_size, void LDM_read_header(void const *source, size_t *compressed_size,
size_t *decompressed_size) { size_t *decompressed_size) {
U32 *ip = (U32 *)source; const U32 *ip = (const U32 *)source;
*compressed_size = *ip++; *compressed_size = *ip++;
*decompressed_size = *ip; *decompressed_size = *ip;
} }
@@ -156,6 +156,7 @@ size_t LDM_compress(void const *source, void *dest, size_t source_size,
const BYTE * const iend = istart + source_size; const BYTE * const iend = istart + source_size;
const BYTE *ilimit = iend - HASH_SIZE; const BYTE *ilimit = iend - HASH_SIZE;
const BYTE * const matchlimit = iend - HASH_SIZE; const BYTE * const matchlimit = iend - HASH_SIZE;
const BYTE * const mflimit = iend - MINMATCH;
BYTE *op = (BYTE*) dest; BYTE *op = (BYTE*) dest;
U32 hashTable[LDM_HASHTABLESIZE_U32]; U32 hashTable[LDM_HASHTABLESIZE_U32];
memset(hashTable, 0, sizeof(hashTable)); memset(hashTable, 0, sizeof(hashTable));
@@ -172,6 +173,7 @@ size_t LDM_compress(void const *source, void *dest, size_t source_size,
ip++; ip++;
forwardH = LDM_hash_position(ip); forwardH = LDM_hash_position(ip);
//TODO Loop terminates before ip>=ilimit.
while (ip < ilimit) { while (ip < ilimit) {
const BYTE *match; const BYTE *match;
BYTE *token; BYTE *token;
@@ -186,6 +188,10 @@ size_t LDM_compress(void const *source, void *dest, size_t source_size,
ip = forwardIp; ip = forwardIp;
forwardIp += step; forwardIp += step;
if (forwardIp > mflimit) {
goto _last_literals;
}
match = LDM_get_position_on_hash(h, hashTable, istart); match = LDM_get_position_on_hash(h, hashTable, istart);
forwardH = LDM_hash_position(forwardIp); forwardH = LDM_hash_position(forwardIp);
@@ -194,6 +200,12 @@ size_t LDM_compress(void const *source, void *dest, size_t source_size,
LDM_read32(match) != LDM_read32(ip)); LDM_read32(match) != LDM_read32(ip));
} }
// TODO catchup
while (ip > anchor && match > istart && ip[-1] == match[-1]) {
ip--;
match--;
}
/* Encode literals */ /* Encode literals */
{ {
unsigned const litLength = (unsigned)(ip - anchor); unsigned const litLength = (unsigned)(ip - anchor);
@@ -223,7 +235,8 @@ size_t LDM_compress(void const *source, void *dest, size_t source_size,
fwrite(anchor, litLength, 1, stdout); fwrite(anchor, litLength, 1, stdout);
printf("\n"); printf("\n");
#endif #endif
LDM_wild_copy(op, anchor, op + litLength); memcpy(op, anchor, litLength);
//LDM_wild_copy(op, anchor, op + litLength);
op += litLength; op += litLength;
} }
_next_match: _next_match:
@@ -268,29 +281,22 @@ _next_match:
LDM_put_position(ip, hashTable, istart); LDM_put_position(ip, hashTable, istart);
forwardH = LDM_hash_position(++ip); forwardH = LDM_hash_position(++ip);
} }
_last_literals:
/* Encode last literals */ /* Encode last literals */
{ {
/*
size_t const lastRun = (size_t)(iend - anchor); size_t const lastRun = (size_t)(iend - anchor);
printf("last run length: %zu, %zu %zu %zu %zu\n", lastRun, iend-istart,
anchor-istart, ip-istart, ilimit-istart);
if (lastRun >= RUN_MASK) { if (lastRun >= RUN_MASK) {
size_t accumulator = lastRun - RUN_MASK; size_t accumulator = lastRun - RUN_MASK;
*op++ = RUN_MASK << ML_BITS; *op++ = RUN_MASK << ML_BITS;
for(; accumulator >= 255; accumulator -= 255) { for(; accumulator >= 255; accumulator -= 255) {
*op++ = 255; *op++ = 255;
} }
*op++ = (BYTE) accumulator; *op++ = (BYTE)accumulator;
} else { } else {
*op++ = (BYTE)(lastRun << ML_BITS); *op++ = (BYTE)(lastRun << ML_BITS);
} }
fwrite(anchor, lastRun, 1, stdout);
printf("^last run\n");
memcpy(op, anchor, lastRun); memcpy(op, anchor, lastRun);
op += lastRun; op += lastRun;
// memcpy(dest + (ip - istart), ip, 1);
// */
} }
return (op - (BYTE *)dest); return (op - (BYTE *)dest);
} }
@@ -328,7 +334,8 @@ size_t LDM_decompress(void const *source, void *dest, size_t compressed_size,
fwrite(ip, length, 1, stdout); fwrite(ip, length, 1, stdout);
printf("\n"); printf("\n");
#endif #endif
LDM_wild_copy(op, ip, cpy); memcpy(op, ip, length);
// LDM_wild_copy(op, ip, cpy);
ip += length; ip += length;
op = cpy; op = cpy;
@@ -358,12 +365,13 @@ size_t LDM_decompress(void const *source, void *dest, size_t compressed_size,
/* copy match */ /* copy match */
cpy = op + length; cpy = op + length;
// printf("TMP_PREV: %zu\n", op - (BYTE *)dest);
// Inefficient for now // Inefficient for now
while (match < cpy - offset && op < oend) { while (match < cpy - offset && op < oend) {
*op++ = *match++; *op++ = *match++;
} }
// printf("TMP: %zu\n", op - (BYTE *)dest);
} }
// memcpy(dest, source, compressed_size); // memcpy(dest, source, compressed_size);
return op - (BYTE *)dest; return op - (BYTE *)dest;
} }

View File

@@ -280,6 +280,7 @@ static size_t decompress(const char *fname, const char *oname) {
size_t size_out = LDM_decompress(src + LDM_HEADER_SIZE, dst, size_t size_out = LDM_decompress(src + LDM_HEADER_SIZE, dst,
statbuf.st_size - LDM_HEADER_SIZE, statbuf.st_size - LDM_HEADER_SIZE,
decompressed_size); decompressed_size);
printf("Ret size out: %zu\n", size_out);
#endif #endif
ftruncate(fdout, size_out); ftruncate(fdout, size_out);