From e68d7dcf22d26300e6ce97395e52bcaabc28536f Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Wed, 10 Dec 2014 17:58:15 +0100 Subject: Fixed : LZ4_compress_limitedOutput() bug, as reported by Christopher Speller --- lib/lz4.c | 4 ++-- programs/fullbench.c | 8 +++++--- programs/fuzzer.c | 29 ++++++++++++++--------------- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/lz4.c b/lib/lz4.c index 017d8ae..2ed686b 100644 --- a/lib/lz4.c +++ b/lib/lz4.c @@ -642,10 +642,10 @@ _next_match: ip += MINMATCH + matchLength; } + if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) + return 0; /* Check output limit */ if (matchLength>=ML_MASK) { - if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) - return 0; /* Check output limit */ *token += ML_MASK; matchLength -= ML_MASK; for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } diff --git a/programs/fullbench.c b/programs/fullbench.c index 647a458..b785924 100644 --- a/programs/fullbench.c +++ b/programs/fullbench.c @@ -1,6 +1,7 @@ /* bench.c - Demo program to benchmark open-source compression algorithm - Copyright (C) Yann Collet 2012-2014 + Copyright (C) Yann Collet 2012-2015 + GPL v2 License This program is free software; you can redistribute it and/or modify @@ -18,8 +19,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - - LZ4 source repository : http://code.google.com/p/lz4/ + - LZ4 source repository : http://code.google.com/p/lz4 + - LZ4 source mirror : https://github.com/Cyan4973/lz4 + - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ //************************************** diff --git a/programs/fuzzer.c b/programs/fuzzer.c index ee5b2cd..6d3b077 100644 --- a/programs/fuzzer.c +++ b/programs/fuzzer.c @@ -486,31 +486,30 @@ static int FUZ_test(U32 seed, const U32 nbCycles, const U32 startCycle, const do ret = LZ4_compressHC_limitedOutput_withStateHC(stateLZ4HC, block, compressedBuffer, blockSize, HCcompressedSize); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput_withStateHC() failed despite sufficient space"); - /* Test compression with just one missing byte into output buffer => must fail */ - FUZ_DISPLAYTEST; - compressedBuffer[compressedSize-1] = 0; - ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize-1); - FUZ_CHECKTEST(ret, "LZ4_compress_limitedOutput should have failed (output buffer too small by 1 byte)"); - FUZ_CHECKTEST(compressedBuffer[compressedSize-1], "LZ4_compress_limitedOutput overran output buffer") - - /* Test HC compression with just one missing byte into output buffer => must fail */ - FUZ_DISPLAYTEST; - compressedBuffer[HCcompressedSize-1] = 0; - ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize-1); - FUZ_CHECKTEST(ret, "LZ4_compressHC_limitedOutput should have failed (output buffer too small by 1 byte)"); - FUZ_CHECKTEST(compressedBuffer[HCcompressedSize-1], "LZ4_compressHC_limitedOutput overran output buffer") - - /* Test compression with just multiple missing byte into output buffer => must fail */ + /* Test compression with missing bytes into output buffer => must fail */ FUZ_DISPLAYTEST; { int missingBytes = (FUZ_rand(&randState) % 0x3F) + 1; if (missingBytes >= compressedSize) missingBytes = compressedSize-1; + missingBytes += !missingBytes; /* avoid special case missingBytes==0 */ compressedBuffer[compressedSize-missingBytes] = 0; ret = LZ4_compress_limitedOutput(block, compressedBuffer, blockSize, compressedSize-missingBytes); FUZ_CHECKTEST(ret, "LZ4_compress_limitedOutput should have failed (output buffer too small by %i byte)", missingBytes); FUZ_CHECKTEST(compressedBuffer[compressedSize-missingBytes], "LZ4_compress_limitedOutput overran output buffer ! (%i missingBytes)", missingBytes) } + /* Test HC compression with missing bytes into output buffer => must fail */ + FUZ_DISPLAYTEST; + { + int missingBytes = (FUZ_rand(&randState) % 0x3F) + 1; + if (missingBytes >= HCcompressedSize) missingBytes = HCcompressedSize-1; + missingBytes += !missingBytes; /* avoid special case missingBytes==0 */ + compressedBuffer[HCcompressedSize-missingBytes] = 0; + ret = LZ4_compressHC_limitedOutput(block, compressedBuffer, blockSize, HCcompressedSize-missingBytes); + FUZ_CHECKTEST(ret, "LZ4_compressHC_limitedOutput should have failed (output buffer too small by %i byte)", missingBytes); + FUZ_CHECKTEST(compressedBuffer[HCcompressedSize-missingBytes], "LZ4_compressHC_limitedOutput overran output buffer ! (%i missingBytes)", missingBytes) + } + /********************/ /* Dictionary tests */ -- cgit v0.12