]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
fixed overlapping count & workspace special case 2253/head
authorYann Collet <cyan@fb.com>
Mon, 27 Jul 2020 05:40:21 +0000 (22:40 -0700)
committerYann Collet <cyan@fb.com>
Mon, 27 Jul 2020 05:40:21 +0000 (22:40 -0700)
lib/compress/hist.c

index 1d6364b782960e0ed206e8d20c9cfbbed89677d9..c8b2ebb7522fba5a049c195bbd747b519c9dd025 100644 (file)
@@ -71,20 +71,21 @@ static size_t HIST_count_parallel_wksp(
 {
     const BYTE* ip = (const BYTE*)source;
     const BYTE* const iend = ip+sourceSize;
+    size_t const countSize = (*maxSymbolValuePtr + 1) * sizeof(*count);
     unsigned max=0;
     U32* const Counting1 = workSpace;
     U32* const Counting2 = Counting1 + 256;
     U32* const Counting3 = Counting2 + 256;
     U32* const Counting4 = Counting3 + 256;
 
-    memset(workSpace, 0, 4*256*sizeof(unsigned));
-
     /* safety checks */
+    assert(*maxSymbolValuePtr <= 255);
     if (!sourceSize) {
-        memset(count, 0, (*maxSymbolValuePtr + 1) * 4);
+        memset(count, 0, countSize);
         *maxSymbolValuePtr = 0;
         return 0;
     }
+    memset(workSpace, 0, 4*256*sizeof(unsigned));
 
     /* by stripes of 16 bytes */
     {   U32 cached = MEM_read32(ip); ip += 4;
@@ -126,7 +127,7 @@ static size_t HIST_count_parallel_wksp(
         while (!Counting1[maxSymbolValue]) maxSymbolValue--;
         if (check && maxSymbolValue > *maxSymbolValuePtr) return ERROR(maxSymbolValue_tooSmall);
         *maxSymbolValuePtr = maxSymbolValue;
-        memcpy(count, Counting1, (maxSymbolValue+1) * 4);
+        memmove(count, Counting1, countSize);   /* in case count & Counting1 are overlapping */
     }
     return (size_t)max;
 }