extzstd 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/contrib/zstd/CHANGELOG +188 -1
  4. data/contrib/zstd/CONTRIBUTING.md +157 -74
  5. data/contrib/zstd/LICENSE +4 -4
  6. data/contrib/zstd/Makefile +81 -58
  7. data/contrib/zstd/Package.swift +36 -0
  8. data/contrib/zstd/README.md +59 -35
  9. data/contrib/zstd/TESTING.md +2 -3
  10. data/contrib/zstd/appveyor.yml +49 -136
  11. data/contrib/zstd/lib/BUCK +5 -7
  12. data/contrib/zstd/lib/Makefile +87 -181
  13. data/contrib/zstd/lib/README.md +23 -6
  14. data/contrib/zstd/lib/common/allocations.h +55 -0
  15. data/contrib/zstd/lib/common/bits.h +200 -0
  16. data/contrib/zstd/lib/common/bitstream.h +33 -59
  17. data/contrib/zstd/lib/common/compiler.h +115 -45
  18. data/contrib/zstd/lib/common/cpu.h +1 -1
  19. data/contrib/zstd/lib/common/debug.c +1 -1
  20. data/contrib/zstd/lib/common/debug.h +1 -1
  21. data/contrib/zstd/lib/common/entropy_common.c +15 -37
  22. data/contrib/zstd/lib/common/error_private.c +9 -2
  23. data/contrib/zstd/lib/common/error_private.h +82 -3
  24. data/contrib/zstd/lib/common/fse.h +9 -85
  25. data/contrib/zstd/lib/common/fse_decompress.c +29 -111
  26. data/contrib/zstd/lib/common/huf.h +84 -172
  27. data/contrib/zstd/lib/common/mem.h +58 -49
  28. data/contrib/zstd/lib/common/pool.c +37 -16
  29. data/contrib/zstd/lib/common/pool.h +9 -3
  30. data/contrib/zstd/lib/common/portability_macros.h +156 -0
  31. data/contrib/zstd/lib/common/threading.c +68 -14
  32. data/contrib/zstd/lib/common/threading.h +5 -10
  33. data/contrib/zstd/lib/common/xxhash.c +7 -809
  34. data/contrib/zstd/lib/common/xxhash.h +5568 -167
  35. data/contrib/zstd/lib/common/zstd_common.c +1 -36
  36. data/contrib/zstd/lib/common/zstd_deps.h +1 -1
  37. data/contrib/zstd/lib/common/zstd_internal.h +64 -150
  38. data/contrib/zstd/lib/common/zstd_trace.h +163 -0
  39. data/contrib/zstd/lib/compress/clevels.h +134 -0
  40. data/contrib/zstd/lib/compress/fse_compress.c +69 -150
  41. data/contrib/zstd/lib/compress/hist.c +1 -1
  42. data/contrib/zstd/lib/compress/hist.h +1 -1
  43. data/contrib/zstd/lib/compress/huf_compress.c +773 -251
  44. data/contrib/zstd/lib/compress/zstd_compress.c +2650 -826
  45. data/contrib/zstd/lib/compress/zstd_compress_internal.h +509 -180
  46. data/contrib/zstd/lib/compress/zstd_compress_literals.c +117 -40
  47. data/contrib/zstd/lib/compress/zstd_compress_literals.h +16 -6
  48. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +28 -19
  49. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +1 -1
  50. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +33 -305
  51. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +1 -1
  52. data/contrib/zstd/lib/compress/zstd_cwksp.h +266 -85
  53. data/contrib/zstd/lib/compress/zstd_double_fast.c +369 -132
  54. data/contrib/zstd/lib/compress/zstd_double_fast.h +3 -2
  55. data/contrib/zstd/lib/compress/zstd_fast.c +722 -258
  56. data/contrib/zstd/lib/compress/zstd_fast.h +3 -2
  57. data/contrib/zstd/lib/compress/zstd_lazy.c +1105 -360
  58. data/contrib/zstd/lib/compress/zstd_lazy.h +41 -1
  59. data/contrib/zstd/lib/compress/zstd_ldm.c +272 -208
  60. data/contrib/zstd/lib/compress/zstd_ldm.h +3 -2
  61. data/contrib/zstd/lib/compress/zstd_ldm_geartab.h +106 -0
  62. data/contrib/zstd/lib/compress/zstd_opt.c +324 -197
  63. data/contrib/zstd/lib/compress/zstd_opt.h +1 -1
  64. data/contrib/zstd/lib/compress/zstdmt_compress.c +109 -53
  65. data/contrib/zstd/lib/compress/zstdmt_compress.h +9 -6
  66. data/contrib/zstd/lib/decompress/huf_decompress.c +1071 -539
  67. data/contrib/zstd/lib/decompress/huf_decompress_amd64.S +576 -0
  68. data/contrib/zstd/lib/decompress/zstd_ddict.c +4 -4
  69. data/contrib/zstd/lib/decompress/zstd_ddict.h +1 -1
  70. data/contrib/zstd/lib/decompress/zstd_decompress.c +507 -82
  71. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +962 -310
  72. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +14 -3
  73. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +54 -6
  74. data/contrib/zstd/lib/deprecated/zbuff.h +1 -1
  75. data/contrib/zstd/lib/deprecated/zbuff_common.c +1 -1
  76. data/contrib/zstd/lib/deprecated/zbuff_compress.c +24 -4
  77. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +3 -1
  78. data/contrib/zstd/lib/dictBuilder/cover.c +44 -32
  79. data/contrib/zstd/lib/dictBuilder/cover.h +6 -5
  80. data/contrib/zstd/lib/dictBuilder/divsufsort.c +1 -1
  81. data/contrib/zstd/lib/dictBuilder/fastcover.c +24 -16
  82. data/contrib/zstd/lib/dictBuilder/zdict.c +88 -95
  83. data/contrib/zstd/lib/legacy/zstd_legacy.h +8 -1
  84. data/contrib/zstd/lib/legacy/zstd_v01.c +16 -53
  85. data/contrib/zstd/lib/legacy/zstd_v01.h +1 -1
  86. data/contrib/zstd/lib/legacy/zstd_v02.c +24 -69
  87. data/contrib/zstd/lib/legacy/zstd_v02.h +1 -1
  88. data/contrib/zstd/lib/legacy/zstd_v03.c +25 -72
  89. data/contrib/zstd/lib/legacy/zstd_v03.h +1 -1
  90. data/contrib/zstd/lib/legacy/zstd_v04.c +23 -69
  91. data/contrib/zstd/lib/legacy/zstd_v04.h +1 -1
  92. data/contrib/zstd/lib/legacy/zstd_v05.c +35 -85
  93. data/contrib/zstd/lib/legacy/zstd_v05.h +1 -1
  94. data/contrib/zstd/lib/legacy/zstd_v06.c +42 -87
  95. data/contrib/zstd/lib/legacy/zstd_v06.h +1 -1
  96. data/contrib/zstd/lib/legacy/zstd_v07.c +35 -82
  97. data/contrib/zstd/lib/legacy/zstd_v07.h +1 -1
  98. data/contrib/zstd/lib/libzstd.mk +214 -0
  99. data/contrib/zstd/lib/libzstd.pc.in +4 -3
  100. data/contrib/zstd/lib/module.modulemap +35 -0
  101. data/contrib/zstd/lib/{dictBuilder/zdict.h → zdict.h} +202 -33
  102. data/contrib/zstd/lib/zstd.h +922 -293
  103. data/contrib/zstd/lib/{common/zstd_errors.h → zstd_errors.h} +27 -8
  104. data/ext/extconf.rb +7 -6
  105. data/ext/extzstd.c +13 -10
  106. data/ext/libzstd_conf.h +0 -1
  107. data/ext/zstd_decompress_asm.S +1 -0
  108. metadata +16 -5
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -23,9 +23,13 @@
23
23
  /* Unix Large Files support (>4GB) */
24
24
  #define _FILE_OFFSET_BITS 64
25
25
  #if (defined(__sun__) && (!defined(__LP64__))) /* Sun Solaris 32-bits requires specific definitions */
26
+ # ifndef _LARGEFILE_SOURCE
26
27
  # define _LARGEFILE_SOURCE
28
+ # endif
27
29
  #elif ! defined(__LP64__) /* No point defining Large file for 64 bit */
30
+ # ifndef _LARGEFILE64_SOURCE
28
31
  # define _LARGEFILE64_SOURCE
32
+ # endif
29
33
  #endif
30
34
 
31
35
 
@@ -37,18 +41,19 @@
37
41
  #include <stdio.h> /* fprintf, fopen, ftello64 */
38
42
  #include <time.h> /* clock */
39
43
 
44
+ #ifndef ZDICT_STATIC_LINKING_ONLY
45
+ # define ZDICT_STATIC_LINKING_ONLY
46
+ #endif
47
+
40
48
  #include "../common/mem.h" /* read */
41
49
  #include "../common/fse.h" /* FSE_normalizeCount, FSE_writeNCount */
42
- #define HUF_STATIC_LINKING_ONLY
43
50
  #include "../common/huf.h" /* HUF_buildCTable, HUF_writeCTable */
44
51
  #include "../common/zstd_internal.h" /* includes zstd.h */
45
52
  #include "../common/xxhash.h" /* XXH64 */
46
- #include "divsufsort.h"
47
- #ifndef ZDICT_STATIC_LINKING_ONLY
48
- # define ZDICT_STATIC_LINKING_ONLY
49
- #endif
50
- #include "zdict.h"
51
53
  #include "../compress/zstd_compress_internal.h" /* ZSTD_loadCEntropy() */
54
+ #include "../zdict.h"
55
+ #include "divsufsort.h"
56
+ #include "../common/bits.h" /* ZSTD_NbCommonBytes */
52
57
 
53
58
 
54
59
  /*-*************************************
@@ -125,65 +130,6 @@ size_t ZDICT_getDictHeaderSize(const void* dictBuffer, size_t dictSize)
125
130
  /*-********************************************************
126
131
  * Dictionary training functions
127
132
  **********************************************************/
128
- static unsigned ZDICT_NbCommonBytes (size_t val)
129
- {
130
- if (MEM_isLittleEndian()) {
131
- if (MEM_64bits()) {
132
- # if defined(_MSC_VER) && defined(_WIN64)
133
- unsigned long r = 0;
134
- _BitScanForward64( &r, (U64)val );
135
- return (unsigned)(r>>3);
136
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
137
- return (__builtin_ctzll((U64)val) >> 3);
138
- # else
139
- static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
140
- return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
141
- # endif
142
- } else { /* 32 bits */
143
- # if defined(_MSC_VER)
144
- unsigned long r=0;
145
- _BitScanForward( &r, (U32)val );
146
- return (unsigned)(r>>3);
147
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
148
- return (__builtin_ctz((U32)val) >> 3);
149
- # else
150
- static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
151
- return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
152
- # endif
153
- }
154
- } else { /* Big Endian CPU */
155
- if (MEM_64bits()) {
156
- # if defined(_MSC_VER) && defined(_WIN64)
157
- unsigned long r = 0;
158
- _BitScanReverse64( &r, val );
159
- return (unsigned)(r>>3);
160
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
161
- return (__builtin_clzll(val) >> 3);
162
- # else
163
- unsigned r;
164
- const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
165
- if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
166
- if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
167
- r += (!val);
168
- return r;
169
- # endif
170
- } else { /* 32 bits */
171
- # if defined(_MSC_VER)
172
- unsigned long r = 0;
173
- _BitScanReverse( &r, (unsigned long)val );
174
- return (unsigned)(r>>3);
175
- # elif defined(__GNUC__) && (__GNUC__ >= 3)
176
- return (__builtin_clz((U32)val) >> 3);
177
- # else
178
- unsigned r;
179
- if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
180
- r += (!val);
181
- return r;
182
- # endif
183
- } }
184
- }
185
-
186
-
187
133
  /*! ZDICT_count() :
188
134
  Count the nb of common bytes between 2 pointers.
189
135
  Note : this function presumes end of buffer followed by noisy guard band.
@@ -198,7 +144,7 @@ static size_t ZDICT_count(const void* pIn, const void* pMatch)
198
144
  pMatch = (const char*)pMatch+sizeof(size_t);
199
145
  continue;
200
146
  }
201
- pIn = (const char*)pIn+ZDICT_NbCommonBytes(diff);
147
+ pIn = (const char*)pIn+ZSTD_NbCommonBytes(diff);
202
148
  return (size_t)((const char*)pIn - pStart);
203
149
  }
204
150
  }
@@ -230,7 +176,7 @@ static dictItem ZDICT_analyzePos(
230
176
  U32 savings[LLIMIT] = {0};
231
177
  const BYTE* b = (const BYTE*)buffer;
232
178
  size_t maxLength = LLIMIT;
233
- size_t pos = suffix[start];
179
+ size_t pos = (size_t)suffix[start];
234
180
  U32 end = start;
235
181
  dictItem solution;
236
182
 
@@ -364,7 +310,7 @@ static dictItem ZDICT_analyzePos(
364
310
  savings[i] = savings[i-1] + (lengthList[i] * (i-3));
365
311
 
366
312
  DISPLAYLEVEL(4, "Selected dict at position %u, of length %u : saves %u (ratio: %.2f) \n",
367
- (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / maxLength);
313
+ (unsigned)pos, (unsigned)maxLength, (unsigned)savings[maxLength], (double)savings[maxLength] / (double)maxLength);
368
314
 
369
315
  solution.pos = (U32)pos;
370
316
  solution.length = (U32)maxLength;
@@ -374,7 +320,7 @@ static dictItem ZDICT_analyzePos(
374
320
  { U32 id;
375
321
  for (id=start; id<end; id++) {
376
322
  U32 p, pEnd, length;
377
- U32 const testedPos = suffix[id];
323
+ U32 const testedPos = (U32)suffix[id];
378
324
  if (testedPos == pos)
379
325
  length = solution.length;
380
326
  else {
@@ -426,7 +372,7 @@ static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const
426
372
  elt = table[u];
427
373
  /* sort : improve rank */
428
374
  while ((u>1) && (table[u-1].savings < elt.savings))
429
- table[u] = table[u-1], u--;
375
+ table[u] = table[u-1], u--;
430
376
  table[u] = elt;
431
377
  return u;
432
378
  } }
@@ -437,7 +383,7 @@ static U32 ZDICT_tryMerge(dictItem* table, dictItem elt, U32 eltNbToSkip, const
437
383
 
438
384
  if ((table[u].pos + table[u].length >= elt.pos) && (table[u].pos < elt.pos)) { /* overlap, existing < new */
439
385
  /* append */
440
- int const addedLength = (int)eltEnd - (table[u].pos + table[u].length);
386
+ int const addedLength = (int)eltEnd - (int)(table[u].pos + table[u].length);
441
387
  table[u].savings += elt.length / 8; /* rough approx bonus */
442
388
  if (addedLength > 0) { /* otherwise, elt fully included into existing */
443
389
  table[u].length += addedLength;
@@ -577,7 +523,7 @@ static size_t ZDICT_trainBuffer_legacy(dictItem* dictList, U32 dictListSize,
577
523
  if (solution.length==0) { cursor++; continue; }
578
524
  ZDICT_insertDictItem(dictList, dictListSize, solution, buffer);
579
525
  cursor += solution.length;
580
- DISPLAYUPDATE(2, "\r%4.2f %% \r", (double)cursor / bufferSize * 100);
526
+ DISPLAYUPDATE(2, "\r%4.2f %% \r", (double)cursor / (double)bufferSize * 100.0);
581
527
  } }
582
528
 
583
529
  _cleanup:
@@ -620,11 +566,11 @@ static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters* params,
620
566
  size_t cSize;
621
567
 
622
568
  if (srcSize > blockSizeMax) srcSize = blockSizeMax; /* protection vs large samples */
623
- { size_t const errorCode = ZSTD_compressBegin_usingCDict(esr.zc, esr.dict);
569
+ { size_t const errorCode = ZSTD_compressBegin_usingCDict_deprecated(esr.zc, esr.dict);
624
570
  if (ZSTD_isError(errorCode)) { DISPLAYLEVEL(1, "warning : ZSTD_compressBegin_usingCDict failed \n"); return; }
625
571
 
626
572
  }
627
- cSize = ZSTD_compressBlock(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize);
573
+ cSize = ZSTD_compressBlock_deprecated(esr.zc, esr.workPlace, ZSTD_BLOCKSIZE_MAX, src, srcSize);
628
574
  if (ZSTD_isError(cSize)) { DISPLAYLEVEL(3, "warning : could not compress sample size %u \n", (unsigned)srcSize); return; }
629
575
 
630
576
  if (cSize) { /* if == 0; block is not compressible */
@@ -657,8 +603,8 @@ static void ZDICT_countEStats(EStats_ress_t esr, const ZSTD_parameters* params,
657
603
 
658
604
  if (nbSeq >= 2) { /* rep offsets */
659
605
  const seqDef* const seq = seqStorePtr->sequencesStart;
660
- U32 offset1 = seq[0].offset - 3;
661
- U32 offset2 = seq[1].offset - 3;
606
+ U32 offset1 = seq[0].offBase - ZSTD_REP_NUM;
607
+ U32 offset2 = seq[1].offBase - ZSTD_REP_NUM;
662
608
  if (offset1 >= MAXREPOFFSET) offset1 = 0;
663
609
  if (offset2 >= MAXREPOFFSET) offset2 = 0;
664
610
  repOffsets[offset1] += 3;
@@ -729,6 +675,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
729
675
  size_t const totalSrcSize = ZDICT_totalSampleSize(fileSizes, nbFiles);
730
676
  size_t const averageSampleSize = totalSrcSize / (nbFiles + !nbFiles);
731
677
  BYTE* dstPtr = (BYTE*)dstBuffer;
678
+ U32 wksp[HUF_CTABLE_WORKSPACE_SIZE_U32];
732
679
 
733
680
  /* init */
734
681
  DEBUGLOG(4, "ZDICT_analyzeEntropy");
@@ -761,8 +708,15 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
761
708
  pos += fileSizes[u];
762
709
  }
763
710
 
711
+ if (notificationLevel >= 4) {
712
+ /* writeStats */
713
+ DISPLAYLEVEL(4, "Offset Code Frequencies : \n");
714
+ for (u=0; u<=offcodeMax; u++) {
715
+ DISPLAYLEVEL(4, "%2u :%7u \n", u, offcodeCount[u]);
716
+ } }
717
+
764
718
  /* analyze, build stats, starting with literals */
765
- { size_t maxNbBits = HUF_buildCTable (hufTable, countLit, 255, huffLog);
719
+ { size_t maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp));
766
720
  if (HUF_isError(maxNbBits)) {
767
721
  eSize = maxNbBits;
768
722
  DISPLAYLEVEL(1, " HUF_buildCTable error \n");
@@ -771,7 +725,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
771
725
  if (maxNbBits==8) { /* not compressible : will fail on HUF_writeCTable() */
772
726
  DISPLAYLEVEL(2, "warning : pathological dataset : literals are not compressible : samples are noisy or too regular \n");
773
727
  ZDICT_flatLit(countLit); /* replace distribution by a fake "mostly flat but still compressible" distribution, that HUF_writeCTable() can encode */
774
- maxNbBits = HUF_buildCTable (hufTable, countLit, 255, huffLog);
728
+ maxNbBits = HUF_buildCTable_wksp(hufTable, countLit, 255, huffLog, wksp, sizeof(wksp));
775
729
  assert(maxNbBits==9);
776
730
  }
777
731
  huffLog = (U32)maxNbBits;
@@ -812,7 +766,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
812
766
  llLog = (U32)errorCode;
813
767
 
814
768
  /* write result to buffer */
815
- { size_t const hhSize = HUF_writeCTable(dstPtr, maxDstSize, hufTable, 255, huffLog);
769
+ { size_t const hhSize = HUF_writeCTable_wksp(dstPtr, maxDstSize, hufTable, 255, huffLog, wksp, sizeof(wksp));
816
770
  if (HUF_isError(hhSize)) {
817
771
  eSize = hhSize;
818
772
  DISPLAYLEVEL(1, "HUF_writeCTable error \n");
@@ -867,7 +821,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
867
821
  MEM_writeLE32(dstPtr+8, bestRepOffset[2].offset);
868
822
  #else
869
823
  /* at this stage, we don't use the result of "most common first offset",
870
- as the impact of statistics is not properly evaluated */
824
+ * as the impact of statistics is not properly evaluated */
871
825
  MEM_writeLE32(dstPtr+0, repStartValue[0]);
872
826
  MEM_writeLE32(dstPtr+4, repStartValue[1]);
873
827
  MEM_writeLE32(dstPtr+8, repStartValue[2]);
@@ -883,6 +837,17 @@ _cleanup:
883
837
  }
884
838
 
885
839
 
840
+ /**
841
+ * @returns the maximum repcode value
842
+ */
843
+ static U32 ZDICT_maxRep(U32 const reps[ZSTD_REP_NUM])
844
+ {
845
+ U32 maxRep = reps[0];
846
+ int r;
847
+ for (r = 1; r < ZSTD_REP_NUM; ++r)
848
+ maxRep = MAX(maxRep, reps[r]);
849
+ return maxRep;
850
+ }
886
851
 
887
852
  size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
888
853
  const void* customDictContent, size_t dictContentSize,
@@ -894,11 +859,13 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
894
859
  BYTE header[HBUFFSIZE];
895
860
  int const compressionLevel = (params.compressionLevel == 0) ? ZSTD_CLEVEL_DEFAULT : params.compressionLevel;
896
861
  U32 const notificationLevel = params.notificationLevel;
862
+ /* The final dictionary content must be at least as large as the largest repcode */
863
+ size_t const minContentSize = (size_t)ZDICT_maxRep(repStartValue);
864
+ size_t paddingSize;
897
865
 
898
866
  /* check conditions */
899
867
  DEBUGLOG(4, "ZDICT_finalizeDictionary");
900
868
  if (dictBufferCapacity < dictContentSize) return ERROR(dstSize_tooSmall);
901
- if (dictContentSize < ZDICT_CONTENTSIZE_MIN) return ERROR(srcSize_wrong);
902
869
  if (dictBufferCapacity < ZDICT_DICTSIZE_MIN) return ERROR(dstSize_tooSmall);
903
870
 
904
871
  /* dictionary header */
@@ -922,12 +889,43 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
922
889
  hSize += eSize;
923
890
  }
924
891
 
925
- /* copy elements in final buffer ; note : src and dst buffer can overlap */
926
- if (hSize + dictContentSize > dictBufferCapacity) dictContentSize = dictBufferCapacity - hSize;
927
- { size_t const dictSize = hSize + dictContentSize;
928
- char* dictEnd = (char*)dictBuffer + dictSize;
929
- memmove(dictEnd - dictContentSize, customDictContent, dictContentSize);
930
- memcpy(dictBuffer, header, hSize);
892
+ /* Shrink the content size if it doesn't fit in the buffer */
893
+ if (hSize + dictContentSize > dictBufferCapacity) {
894
+ dictContentSize = dictBufferCapacity - hSize;
895
+ }
896
+
897
+ /* Pad the dictionary content with zeros if it is too small */
898
+ if (dictContentSize < minContentSize) {
899
+ RETURN_ERROR_IF(hSize + minContentSize > dictBufferCapacity, dstSize_tooSmall,
900
+ "dictBufferCapacity too small to fit max repcode");
901
+ paddingSize = minContentSize - dictContentSize;
902
+ } else {
903
+ paddingSize = 0;
904
+ }
905
+
906
+ {
907
+ size_t const dictSize = hSize + paddingSize + dictContentSize;
908
+
909
+ /* The dictionary consists of the header, optional padding, and the content.
910
+ * The padding comes before the content because the "best" position in the
911
+ * dictionary is the last byte.
912
+ */
913
+ BYTE* const outDictHeader = (BYTE*)dictBuffer;
914
+ BYTE* const outDictPadding = outDictHeader + hSize;
915
+ BYTE* const outDictContent = outDictPadding + paddingSize;
916
+
917
+ assert(dictSize <= dictBufferCapacity);
918
+ assert(outDictContent + dictContentSize == (BYTE*)dictBuffer + dictSize);
919
+
920
+ /* First copy the customDictContent into its final location.
921
+ * `customDictContent` and `dictBuffer` may overlap, so we must
922
+ * do this before any other writes into the output buffer.
923
+ * Then copy the header & padding into the output buffer.
924
+ */
925
+ memmove(outDictContent, customDictContent, dictContentSize);
926
+ memcpy(outDictHeader, header, hSize);
927
+ memset(outDictPadding, 0, paddingSize);
928
+
931
929
  return dictSize;
932
930
  }
933
931
  }
@@ -967,16 +965,11 @@ static size_t ZDICT_addEntropyTablesFromBuffer_advanced(
967
965
  return MIN(dictBufferCapacity, hSize+dictContentSize);
968
966
  }
969
967
 
970
- /* Hidden declaration for dbio.c */
971
- size_t ZDICT_trainFromBuffer_unsafe_legacy(
972
- void* dictBuffer, size_t maxDictSize,
973
- const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
974
- ZDICT_legacy_params_t params);
975
968
  /*! ZDICT_trainFromBuffer_unsafe_legacy() :
976
- * Warning : `samplesBuffer` must be followed by noisy guard band.
969
+ * Warning : `samplesBuffer` must be followed by noisy guard band !!!
977
970
  * @return : size of dictionary, or an error code which can be tested with ZDICT_isError()
978
971
  */
979
- size_t ZDICT_trainFromBuffer_unsafe_legacy(
972
+ static size_t ZDICT_trainFromBuffer_unsafe_legacy(
980
973
  void* dictBuffer, size_t maxDictSize,
981
974
  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
982
975
  ZDICT_legacy_params_t params)
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -242,6 +242,13 @@ MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size
242
242
  frameSizeInfo.compressedSize = ERROR(srcSize_wrong);
243
243
  frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
244
244
  }
245
+ /* In all cases, decompressedBound == nbBlocks * ZSTD_BLOCKSIZE_MAX.
246
+ * So we can compute nbBlocks without having to change every function.
247
+ */
248
+ if (frameSizeInfo.decompressedBound != ZSTD_CONTENTSIZE_ERROR) {
249
+ assert((frameSizeInfo.decompressedBound & (ZSTD_BLOCKSIZE_MAX - 1)) == 0);
250
+ frameSizeInfo.nbBlocks = (size_t)(frameSizeInfo.decompressedBound / ZSTD_BLOCKSIZE_MAX);
251
+ }
245
252
  return frameSizeInfo;
246
253
  }
247
254
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -190,28 +190,6 @@ typedef signed long long S64;
190
190
  /****************************************************************
191
191
  * Memory I/O
192
192
  *****************************************************************/
193
- /* FSE_FORCE_MEMORY_ACCESS
194
- * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
195
- * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
196
- * The below switch allow to select different access method for improved performance.
197
- * Method 0 (default) : use `memcpy()`. Safe and portable.
198
- * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
199
- * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
200
- * Method 2 : direct access. This method is portable but violate C standard.
201
- * It can generate buggy code on targets generating assembly depending on alignment.
202
- * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
203
- * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
204
- * Prefer these methods in priority order (0 > 1 > 2)
205
- */
206
- #ifndef FSE_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
207
- # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
208
- # define FSE_FORCE_MEMORY_ACCESS 2
209
- # elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \
210
- (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
211
- # define FSE_FORCE_MEMORY_ACCESS 1
212
- # endif
213
- #endif
214
-
215
193
 
216
194
  static unsigned FSE_32bits(void)
217
195
  {
@@ -224,24 +202,6 @@ static unsigned FSE_isLittleEndian(void)
224
202
  return one.c[0];
225
203
  }
226
204
 
227
- #if defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==2)
228
-
229
- static U16 FSE_read16(const void* memPtr) { return *(const U16*) memPtr; }
230
- static U32 FSE_read32(const void* memPtr) { return *(const U32*) memPtr; }
231
- static U64 FSE_read64(const void* memPtr) { return *(const U64*) memPtr; }
232
-
233
- #elif defined(FSE_FORCE_MEMORY_ACCESS) && (FSE_FORCE_MEMORY_ACCESS==1)
234
-
235
- /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
236
- /* currently only defined for gcc and icc */
237
- typedef union { U16 u16; U32 u32; U64 u64; } __attribute__((packed)) unalign;
238
-
239
- static U16 FSE_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
240
- static U32 FSE_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
241
- static U64 FSE_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
242
-
243
- #else
244
-
245
205
  static U16 FSE_read16(const void* memPtr)
246
206
  {
247
207
  U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
@@ -257,8 +217,6 @@ static U64 FSE_read64(const void* memPtr)
257
217
  U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
258
218
  }
259
219
 
260
- #endif /* FSE_FORCE_MEMORY_ACCESS */
261
-
262
220
  static U16 FSE_readLE16(const void* memPtr)
263
221
  {
264
222
  if (FSE_isLittleEndian())
@@ -343,8 +301,7 @@ FORCE_INLINE unsigned FSE_highbit32 (U32 val)
343
301
  {
344
302
  # if defined(_MSC_VER) /* Visual */
345
303
  unsigned long r;
346
- _BitScanReverse ( &r, val );
347
- return (unsigned) r;
304
+ return _BitScanReverse(&r, val) ? (unsigned)r : 0;
348
305
  # elif defined(__GNUC__) && (GCC_VERSION >= 304) /* GCC Intrinsic */
349
306
  return __builtin_clz (val) ^ 31;
350
307
  # else /* Software version */
@@ -1194,7 +1151,7 @@ static size_t HUF_decompress (void* dst, size_t maxDstSize, const void* cSrc, si
1194
1151
  zstd - standard compression library
1195
1152
  Copyright (C) 2014-2015, Yann Collet.
1196
1153
 
1197
- BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
1154
+ BSD 2-Clause License (https://opensource.org/licenses/bsd-license.php)
1198
1155
 
1199
1156
  Redistribution and use in source and binary forms, with or without
1200
1157
  modification, are permitted provided that the following conditions are
@@ -1763,20 +1720,26 @@ static size_t ZSTD_execSequence(BYTE* op,
1763
1720
  static const int dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
1764
1721
  static const int dec64table[] = {8, 8, 8, 7, 8, 9,10,11}; /* subtracted */
1765
1722
  const BYTE* const ostart = op;
1723
+ BYTE* const oLitEnd = op + sequence.litLength;
1766
1724
  const size_t litLength = sequence.litLength;
1767
1725
  BYTE* const endMatch = op + litLength + sequence.matchLength; /* risk : address space overflow (32-bits) */
1768
1726
  const BYTE* const litEnd = *litPtr + litLength;
1769
1727
 
1770
- /* check */
1728
+ /* checks */
1729
+ size_t const seqLength = sequence.litLength + sequence.matchLength;
1730
+
1731
+ if (seqLength > (size_t)(oend - op)) return ERROR(dstSize_tooSmall);
1732
+ if (sequence.litLength > (size_t)(litLimit - *litPtr)) return ERROR(corruption_detected);
1733
+ /* Now we know there are no overflow in literal nor match lengths, can use pointer checks */
1734
+ if (sequence.offset > (U32)(oLitEnd - base)) return ERROR(corruption_detected);
1735
+
1771
1736
  if (endMatch > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
1772
- if (litEnd > litLimit) return ERROR(corruption_detected);
1773
- if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */
1737
+ if (litEnd > litLimit) return ERROR(corruption_detected); /* overRead beyond lit buffer */
1738
+ if (sequence.matchLength > (size_t)(*litPtr-op)) return ERROR(dstSize_tooSmall); /* overwrite literal segment */
1774
1739
 
1775
1740
  /* copy Literals */
1776
- if (((size_t)(*litPtr - op) < 8) || ((size_t)(oend-litEnd) < 8) || (op+litLength > oend-8))
1777
- memmove(op, *litPtr, litLength); /* overwrite risk */
1778
- else
1779
- ZSTD_wildcopy(op, *litPtr, litLength);
1741
+ ZSTD_memmove(op, *litPtr, sequence.litLength); /* note : v0.1 seems to allow scenarios where output or input are close to end of buffer */
1742
+
1780
1743
  op += litLength;
1781
1744
  *litPtr = litEnd; /* update for next sequence */
1782
1745
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Yann Collet, Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the