summaryrefslogtreecommitdiffstats
path: root/lib/lz4hc.c
diff options
context:
space:
mode:
authorYann Collet <cyan@fb.com>2022-01-29 00:51:28 (GMT)
committerYann Collet <cyan@fb.com>2022-01-29 00:51:28 (GMT)
commite4f5a34d1613b3cce97124539c3a8b6b2ed42310 (patch)
tree9c3edb036664c78c426081f28a10cf5c4914fb0d /lib/lz4hc.c
parent5cc311893f1c94fe37e4151170d5a810c51c3330 (diff)
downloadlz4-e4f5a34d1613b3cce97124539c3a8b6b2ed42310.zip
lz4-e4f5a34d1613b3cce97124539c3a8b6b2ed42310.tar.gz
lz4-e4f5a34d1613b3cce97124539c3a8b6b2ed42310.tar.bz2
fixed bug in optimal parser
discovered by @yoniko.
Diffstat (limited to 'lib/lz4hc.c')
-rw-r--r--lib/lz4hc.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/lib/lz4hc.c b/lib/lz4hc.c
index e71ce94..ee6fc41 100644
--- a/lib/lz4hc.c
+++ b/lib/lz4hc.c
@@ -193,8 +193,7 @@ LZ4HC_countPattern(const BYTE* ip, const BYTE* const iEnd, U32 const pattern32)
BYTE const byte = (BYTE)(pattern >> bitOffset);
if (*ip != byte) break;
ip ++; bitOffset -= 8;
- }
- }
+ } }
return (unsigned)(ip - iStart);
}
@@ -234,18 +233,16 @@ typedef enum { favorCompressionRatio=0, favorDecompressionSpeed } HCfavor_e;
LZ4_FORCE_INLINE int
LZ4HC_InsertAndGetWiderMatch (
- LZ4HC_CCtx_internal* hc4,
- const BYTE* const ip,
- const BYTE* const iLowLimit,
- const BYTE* const iHighLimit,
- int longest,
- const BYTE** matchpos,
- const BYTE** startpos,
- const int maxNbAttempts,
- const int patternAnalysis,
- const int chainSwap,
- const dictCtx_directive dict,
- const HCfavor_e favorDecSpeed)
+ LZ4HC_CCtx_internal* const hc4,
+ const BYTE* const ip,
+ const BYTE* const iLowLimit, const BYTE* const iHighLimit,
+ int longest,
+ const BYTE** matchpos,
+ const BYTE** startpos,
+ const int maxNbAttempts,
+ const int patternAnalysis, const int chainSwap,
+ const dictCtx_directive dict,
+ const HCfavor_e favorDecSpeed)
{
U16* const chainTable = hc4->chainTable;
U32* const HashTable = hc4->hashTable;
@@ -254,7 +251,8 @@ LZ4HC_InsertAndGetWiderMatch (
const U32 dictLimit = hc4->dictLimit;
const BYTE* const lowPrefixPtr = base + dictLimit;
const U32 ipIndex = (U32)(ip - base);
- const U32 lowestMatchIndex = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
+ const int withinStartDistance = (hc4->lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex);
+ const U32 lowestMatchIndex = (withinStartDistance) ? hc4->lowLimit : ipIndex - LZ4_DISTANCE_MAX;
const BYTE* const dictBase = hc4->dictBase;
int const lookBackLength = (int)(ip-iLowLimit);
int nbAttempts = maxNbAttempts;
@@ -294,7 +292,8 @@ LZ4HC_InsertAndGetWiderMatch (
} } }
} else { /* lowestMatchIndex <= matchIndex < dictLimit */
const BYTE* const matchPtr = dictBase + matchIndex;
- if (LZ4_read32(matchPtr) == pattern) {
+ if ( likely(matchIndex <= dictLimit - 4)
+ && (LZ4_read32(matchPtr) == pattern) ) {
const BYTE* const dictStart = dictBase + hc4->lowLimit;
int back = 0;
const BYTE* vLimit = ip + (dictLimit - matchIndex);
@@ -310,7 +309,7 @@ LZ4HC_InsertAndGetWiderMatch (
*startpos = ip + back;
} } }
- if (chainSwap && matchLength==longest) { /* better match => select a better chain */
+ if (chainSwap && matchLength==longest) { /* better match => select a better chain */
assert(lookBackLength==0); /* search forward only */
if (matchIndex + (U32)longest <= ipIndex) {
int const kTrigger = 4;
@@ -326,8 +325,7 @@ LZ4HC_InsertAndGetWiderMatch (
distanceToNextMatch = candidateDist;
matchChainPos = (U32)pos;
accel = 1 << kTrigger;
- }
- }
+ } }
if (distanceToNextMatch > 1) {
if (distanceToNextMatch > matchIndex) break; /* avoid overflow */
matchIndex -= distanceToNextMatch;