Merge pull request #2627 from terrelln/timeout-fix
[lib] Fix fuzzer timeouts by backing off overflow correction
This commit is contained in:
@@ -193,6 +193,10 @@ typedef struct {
|
|||||||
BYTE const* dictBase; /* extDict indexes relative to this position */
|
BYTE const* dictBase; /* extDict indexes relative to this position */
|
||||||
U32 dictLimit; /* below that point, need extDict */
|
U32 dictLimit; /* below that point, need extDict */
|
||||||
U32 lowLimit; /* below that point, no more valid data */
|
U32 lowLimit; /* below that point, no more valid data */
|
||||||
|
U32 nbOverflowCorrections; /* Number of times overflow correction has run since
|
||||||
|
* ZSTD_window_init(). Useful for debugging coredumps
|
||||||
|
* and for ZSTD_WINDOW_OVERFLOW_CORRECT_FREQUENTLY.
|
||||||
|
*/
|
||||||
} ZSTD_window_t;
|
} ZSTD_window_t;
|
||||||
|
|
||||||
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
|
typedef struct ZSTD_matchState_t ZSTD_matchState_t;
|
||||||
@@ -934,8 +938,22 @@ MEM_STATIC U32 ZSTD_window_canOverflowCorrect(ZSTD_window_t const window,
|
|||||||
U32 const cycleSize = 1u << cycleLog;
|
U32 const cycleSize = 1u << cycleLog;
|
||||||
U32 const curr = (U32)((BYTE const*)src - window.base);
|
U32 const curr = (U32)((BYTE const*)src - window.base);
|
||||||
U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
|
U32 const minIndexToOverflowCorrect = cycleSize + MAX(maxDist, cycleSize);
|
||||||
U32 const indexLargeEnough = curr > minIndexToOverflowCorrect;
|
|
||||||
|
/* Adjust the min index to backoff the overflow correction frequency,
|
||||||
|
* so we don't waste too much CPU in overflow correction. If this
|
||||||
|
* computation overflows we don't really care, we just need to make
|
||||||
|
* sure it is at least minIndexToOverflowCorrect.
|
||||||
|
*/
|
||||||
|
U32 const adjustment = window.nbOverflowCorrections + 1;
|
||||||
|
U32 const adjustedIndex = MAX(minIndexToOverflowCorrect * adjustment,
|
||||||
|
minIndexToOverflowCorrect);
|
||||||
|
U32 const indexLargeEnough = curr > adjustedIndex;
|
||||||
|
|
||||||
|
/* Only overflow correct early if the dictionary is invalidated already,
|
||||||
|
* so we don't hurt compression ratio.
|
||||||
|
*/
|
||||||
U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
|
U32 const dictionaryInvalidated = curr > maxDist + loadedDictEnd;
|
||||||
|
|
||||||
return indexLargeEnough && dictionaryInvalidated;
|
return indexLargeEnough && dictionaryInvalidated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,6 +1043,8 @@ MEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,
|
|||||||
assert(window->lowLimit <= newCurrent);
|
assert(window->lowLimit <= newCurrent);
|
||||||
assert(window->dictLimit <= newCurrent);
|
assert(window->dictLimit <= newCurrent);
|
||||||
|
|
||||||
|
++window->nbOverflowCorrections;
|
||||||
|
|
||||||
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
|
DEBUGLOG(4, "Correction of 0x%x bytes to lowLimit=0x%x", correction,
|
||||||
window->lowLimit);
|
window->lowLimit);
|
||||||
return correction;
|
return correction;
|
||||||
@@ -1134,6 +1154,7 @@ MEM_STATIC void ZSTD_window_init(ZSTD_window_t* window) {
|
|||||||
window->dictLimit = 1; /* start from 1, so that 1st position is valid */
|
window->dictLimit = 1; /* start from 1, so that 1st position is valid */
|
||||||
window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
window->lowLimit = 1; /* it ensures first and later CCtx usages compress the same */
|
||||||
window->nextSrc = window->base + 1; /* see issue #1241 */
|
window->nextSrc = window->base + 1; /* see issue #1241 */
|
||||||
|
window->nbOverflowCorrections = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user