]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
Avoid Reducing Indices to Reserved Values
authorW. Felix Handte <w@felixhandte.com>
Tue, 9 Nov 2021 01:03:52 +0000 (20:03 -0500)
committerW. Felix Handte <w@felixhandte.com>
Tue, 9 Nov 2021 01:03:52 +0000 (20:03 -0500)
Previously, if an index was equal to `reducerValue + 1`, it would get remapped
during index reduction to 1 i.e. `ZSTD_DUBT_UNSORTED_MARK`. This can affect the
parsing of the input slightly, by causing tree nodes to be nullified when they
otherwise wouldn't be. This hardly matters from a correctness or efficiency
perspective, but it does impact determinism.

So this commit changes index reduction to avoid mapping indices to collide with
`ZSTD_DUBT_UNSORTED_MARK`.

lib/compress/zstd_compress.c

index f870bad636b9c1fb2d7a2533812dfe94634516a1..59a21691839ff0df70c8fc3932ba173908d78c04 100644 (file)
@@ -2311,6 +2311,8 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
     int const nbRows = (int)size / ZSTD_ROWSIZE;
     int cellNb = 0;
     int rowNb;
+    /* Protect special index values < ZSTD_WINDOW_START_INDEX. */
+    U32 const reducerThreshold = reducerValue + ZSTD_WINDOW_START_INDEX;
     assert((size & (ZSTD_ROWSIZE-1)) == 0);  /* multiple of ZSTD_ROWSIZE */
     assert(size < (1U<<31));   /* can be casted to int */
 
@@ -2330,12 +2332,12 @@ ZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerVa
     for (rowNb=0 ; rowNb < nbRows ; rowNb++) {
         int column;
         for (column=0; column<ZSTD_ROWSIZE; column++) {
-            if (preserveMark) {
-                U32 const adder = (table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) ? reducerValue : 0;
-                table[cellNb] += adder;
+            if (preserveMark && table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) {
+            } else if (table[cellNb] < reducerThreshold) {
+                table[cellNb] = 0;
+            } else {
+                table[cellNb] -= reducerValue;
             }
-            if (table[cellNb] < reducerValue) table[cellNb] = 0;
-            else table[cellNb] -= reducerValue;
             cellNb++;
     }   }
 }