From: Danielle Rozenblit Date: Mon, 23 Jan 2023 15:59:02 +0000 (-0800) Subject: fix nits and add new error code for invalid external sequences X-Git-Tag: v1.5.4^2~32^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1b65727e7451d6cff83b6a96364ffedfef251fb7;p=thirdparty%2Fzstd.git fix nits and add new error code for invalid external sequences --- diff --git a/lib/common/error_private.c b/lib/common/error_private.c index fb4d70596..a9f01069a 100644 --- a/lib/common/error_private.c +++ b/lib/common/error_private.c @@ -53,6 +53,7 @@ const char* ERR_getErrorString(ERR_enum code) case PREFIX(dstBuffer_wrong): return "Destination buffer is wrong"; case PREFIX(srcBuffer_wrong): return "Source buffer is wrong"; case PREFIX(externalMatchFinder_failed): return "External matchfinder returned an error code"; + case PREFIX(invalid_external_sequences): return "External sequences are not valid"; case PREFIX(maxCode): default: return notErrorCode; } diff --git a/lib/compress/zstd_compress.c b/lib/compress/zstd_compress.c index c7a573371..912cd11cd 100644 --- a/lib/compress/zstd_compress.c +++ b/lib/compress/zstd_compress.c @@ -6166,10 +6166,10 @@ ZSTD_validateSequence(U32 offCode, U32 matchLength, U32 minMatch, * window size. After output surpasses windowSize, we're limited to windowSize offsets again. */ size_t const offsetBound = posInSrc > windowSize ? (size_t)windowSize : posInSrc + (size_t)dictSize; - RETURN_ERROR_IF(offCode > OFFSET_TO_OFFBASE(offsetBound), corruption_detected, "Offset too large!"); - RETURN_ERROR_IF(matchLength < MINMATCH, corruption_detected, "Matchlength too small"); + size_t const matchLenLowerBound = (minMatch == 3 || useExternalMatchFinder) ? 3 : 4; + RETURN_ERROR_IF(offCode > OFFSET_TO_OFFBASE(offsetBound), invalid_external_sequences, "Offset too large!"); /* Validate maxNbSeq is large enough for the given matchLength and minMatch */ - RETURN_ERROR_IF(!useExternalMatchFinder && minMatch >= 4 && matchLength < 4, corruption_detected, "Matchlength too small for the minMatch"); + RETURN_ERROR_IF(matchLength < matchLenLowerBound, invalid_external_sequences, "Matchlength too small for the minMatch"); return 0; } @@ -6226,7 +6226,7 @@ ZSTD_copySequencesToSeqStoreExplicitBlockDelim(ZSTD_CCtx* cctx, cctx->appliedParams.cParams.windowLog, dictSize, cctx->appliedParams.useExternalMatchFinder), "Sequence validation failed"); } - RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, memory_allocation, + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, invalid_external_sequences, "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); ip += matchLength + litLength; @@ -6339,7 +6339,7 @@ ZSTD_copySequencesToSeqStoreNoBlockDelim(ZSTD_CCtx* cctx, ZSTD_sequencePosition* "Sequence validation failed"); } DEBUGLOG(6, "Storing sequence: (of: %u, ml: %u, ll: %u)", offBase, matchLength, litLength); - RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, memory_allocation, + RETURN_ERROR_IF(idx - seqPos->idx >= cctx->seqStore.maxNbSeq, invalid_external_sequences, "Not enough memory allocated. Try adjusting ZSTD_c_minMatch."); ZSTD_storeSeq(&cctx->seqStore, litLength, ip, iend, offBase, matchLength); ip += matchLength + litLength; diff --git a/lib/zstd_errors.h b/lib/zstd_errors.h index bd6dbee5f..759e61ce7 100644 --- a/lib/zstd_errors.h +++ b/lib/zstd_errors.h @@ -94,6 +94,7 @@ typedef enum { ZSTD_error_dstBuffer_wrong = 104, ZSTD_error_srcBuffer_wrong = 105, ZSTD_error_externalMatchFinder_failed = 106, + ZSTD_error_invalid_external_sequences = 107, ZSTD_error_maxCode = 120 /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */ } ZSTD_ErrorCode; diff --git a/tests/zstreamtest.c b/tests/zstreamtest.c index cb5f7fea7..22086051b 100644 --- a/tests/zstreamtest.c +++ b/tests/zstreamtest.c @@ -2097,6 +2097,7 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) src, srcSize); CHECK(!ZSTD_isError(cSize), "Should throw an error"); /* maxNbSeq is too small and an assert will fail */ + CHECK(ZSTD_getErrorCode(cSize) != ZSTD_error_invalid_external_sequences, "Wrong error code: %s", ZSTD_getErrorName(cSize)); /* fails sequence validation */ ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters); @@ -2110,6 +2111,7 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) src, srcSize); CHECK(!ZSTD_isError(cSize), "Should throw an error"); /* maxNbSeq is too small and an assert will fail */ + CHECK(ZSTD_getErrorCode(cSize) != ZSTD_error_invalid_external_sequences, "Wrong error code: %s", ZSTD_getErrorName(cSize)); /* fails sequence validation */ free(sequences); } @@ -2143,6 +2145,21 @@ static int basicUnitTests(U32 seed, double compressibility, int bigTests) src, srcSize); CHECK(!ZSTD_isError(cSize), "Should throw an error"); /* maxNbSeq is too small and an assert will fail */ + CHECK(ZSTD_getErrorCode(cSize) != ZSTD_error_invalid_external_sequences, "Wrong error code: %s", ZSTD_getErrorName(cSize)); /* fails sequence validation */ + + ZSTD_CCtx_reset(cctx, ZSTD_reset_session_and_parameters); + + /* Test without sequence validation */ + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_minMatch, 5)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters)); + CHECK_Z(ZSTD_CCtx_setParameter(cctx, ZSTD_c_validateSequences, 0)); + + cSize = ZSTD_compressSequences(cctx, dst, dstSize, + sequences, kNbSequences, + src, srcSize); + + CHECK(!ZSTD_isError(cSize), "Should throw an error"); /* maxNbSeq is too small and an assert will fail */ + CHECK(ZSTD_getErrorCode(cSize) != ZSTD_error_invalid_external_sequences, "Wrong error code: %s", ZSTD_getErrorName(cSize)); /* fails sequence validation */ free(sequences); }