]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
fix nits and add new error code for invalid external sequences
authorDanielle Rozenblit <drozenblit@fb.com>
Mon, 23 Jan 2023 15:59:02 +0000 (07:59 -0800)
committerDanielle Rozenblit <drozenblit@fb.com>
Mon, 23 Jan 2023 15:59:02 +0000 (07:59 -0800)
lib/common/error_private.c
lib/compress/zstd_compress.c
lib/zstd_errors.h
tests/zstreamtest.c

index fb4d70596216c51c45400887dea82b12076ef0f6..a9f01069adb539a678ca1e79e296695fffff52b3 100644 (file)
@@ -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;
     }
index c7a57337125e6aac0d82930c715a76238af4d409..912cd11cd560c69f236f472ca47ebcdf4609bc0c 100644 (file)
@@ -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;
index bd6dbee5ff849ec5a9239dfd6b9a6500f440b9d9..759e61ce788604ed16d7df2e4830f5d11bbe7cd1 100644 (file)
@@ -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;
 
index cb5f7fea7dcb8f9ca57c8f8e82113bc93500e131..22086051b42b7909e34be35b30dbc05f010e839c 100644 (file)
@@ -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);
         }