mirror of
https://github.com/facebook/zstd.git
synced 2025-12-04 00:04:23 -05:00
decompressBound() tests
fixed an overflow in an intermediate result on 32-bit platform. Checked that the new test catch this bug in 32-bit mode.
This commit is contained in:
parent
51355e1f70
commit
ea24b88667
@ -785,7 +785,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
|
||||
frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
|
||||
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
|
||||
? zfh.frameContentSize
|
||||
: nbBlocks * zfh.blockSizeMax;
|
||||
: (unsigned long long)nbBlocks * zfh.blockSizeMax;
|
||||
return frameSizeInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,6 +485,61 @@ static void test_compressBound(int tnb)
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
}
|
||||
|
||||
static void test_decompressBound(int tnb)
|
||||
{
|
||||
DISPLAYLEVEL(3, "test%3i : decompressBound : ", tnb);
|
||||
|
||||
// Simple compression, with size : should provide size;
|
||||
{ const char example[] = "abcd";
|
||||
char cBuffer[ZSTD_COMPRESSBOUND(sizeof(example))];
|
||||
size_t const cSize = ZSTD_compress(cBuffer, sizeof(cBuffer), example, sizeof(example), 0);
|
||||
CHECK_Z(cSize);
|
||||
{ size_t const dbSize = ZSTD_decompressBound(cBuffer, cSize);
|
||||
CHECK_Z(dbSize);
|
||||
CHECK_EQ(dbSize, sizeof(example));
|
||||
} }
|
||||
|
||||
// Simple small compression without size : should provide 1 block size
|
||||
{ char cBuffer[ZSTD_COMPRESSBOUND(0)];
|
||||
ZSTD_outBuffer out = { cBuffer, sizeof(cBuffer), 0 };
|
||||
ZSTD_inBuffer in = { NULL, 0, 0 };
|
||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||
assert(cctx);
|
||||
CHECK_Z( ZSTD_initCStream(cctx, 0) );
|
||||
CHECK_Z( ZSTD_compressStream(cctx, &out, &in) );
|
||||
CHECK_EQ( ZSTD_endStream(cctx, &out), 0 );
|
||||
CHECK_EQ( ZSTD_decompressBound(cBuffer, out.pos), ZSTD_BLOCKSIZE_MAX );
|
||||
ZSTD_freeCCtx(cctx);
|
||||
}
|
||||
|
||||
// Attempt to overflow 32-bit intermediate multiplication result
|
||||
// This requires dBound >= 4 GB, aka 2^32.
|
||||
// This requires 2^32 / 2^17 = 2^15 blocks
|
||||
// => create 2^15 blocks (can be empty, or just 1 byte).
|
||||
{ const char input[] = "a";
|
||||
size_t const nbBlocks = (1 << 15) + 1;
|
||||
size_t blockNb;
|
||||
size_t const outCapacity = 1 << 18; // large margin
|
||||
char* const outBuffer = malloc (outCapacity);
|
||||
ZSTD_outBuffer out = { outBuffer, outCapacity, 0 };
|
||||
ZSTD_CCtx* const cctx = ZSTD_createCCtx();
|
||||
assert(cctx);
|
||||
assert(outBuffer);
|
||||
CHECK_Z( ZSTD_initCStream(cctx, 0) );
|
||||
for (blockNb=0; blockNb<nbBlocks; blockNb++) {
|
||||
ZSTD_inBuffer in = { input, sizeof(input), 0 };
|
||||
CHECK_Z( ZSTD_compressStream(cctx, &out, &in) );
|
||||
CHECK_EQ( ZSTD_flushStream(cctx, &out), 0 );
|
||||
}
|
||||
CHECK_EQ( ZSTD_endStream(cctx, &out), 0 );
|
||||
CHECK( ZSTD_decompressBound(outBuffer, out.pos) > 0x100000000LLU /* 4 GB */ );
|
||||
ZSTD_freeCCtx(cctx);
|
||||
free(outBuffer);
|
||||
}
|
||||
|
||||
DISPLAYLEVEL(3, "OK \n");
|
||||
}
|
||||
|
||||
static int basicUnitTests(U32 const seed, double compressibility)
|
||||
{
|
||||
size_t const CNBuffSize = 5 MB;
|
||||
@ -533,6 +588,8 @@ static int basicUnitTests(U32 const seed, double compressibility)
|
||||
|
||||
test_compressBound(testNb++);
|
||||
|
||||
test_decompressBound(testNb++);
|
||||
|
||||
DISPLAYLEVEL(3, "test%3u : ZSTD_adjustCParams : ", testNb++);
|
||||
{
|
||||
ZSTD_compressionParameters params;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user