extzstd 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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