zstd-ruby 1.3.4.0 → 1.3.5.0

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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/Makefile +56 -10
  4. data/ext/zstdruby/libzstd/README.md +4 -0
  5. data/ext/zstdruby/libzstd/common/bitstream.h +6 -19
  6. data/ext/zstdruby/libzstd/common/compiler.h +3 -3
  7. data/ext/zstdruby/libzstd/common/cpu.h +1 -2
  8. data/ext/zstdruby/libzstd/common/debug.c +44 -0
  9. data/ext/zstdruby/libzstd/common/debug.h +123 -0
  10. data/ext/zstdruby/libzstd/common/entropy_common.c +16 -1
  11. data/ext/zstdruby/libzstd/common/fse.h +45 -41
  12. data/ext/zstdruby/libzstd/common/fse_decompress.c +1 -1
  13. data/ext/zstdruby/libzstd/common/huf.h +34 -27
  14. data/ext/zstdruby/libzstd/common/pool.c +89 -32
  15. data/ext/zstdruby/libzstd/common/pool.h +29 -19
  16. data/ext/zstdruby/libzstd/common/zstd_common.c +0 -5
  17. data/ext/zstdruby/libzstd/common/zstd_internal.h +3 -37
  18. data/ext/zstdruby/libzstd/compress/fse_compress.c +28 -163
  19. data/ext/zstdruby/libzstd/compress/hist.c +195 -0
  20. data/ext/zstdruby/libzstd/compress/hist.h +92 -0
  21. data/ext/zstdruby/libzstd/compress/huf_compress.c +14 -6
  22. data/ext/zstdruby/libzstd/compress/zstd_compress.c +798 -350
  23. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +120 -34
  24. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +247 -87
  25. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +4 -1
  26. data/ext/zstdruby/libzstd/compress/zstd_fast.c +177 -56
  27. data/ext/zstdruby/libzstd/compress/zstd_fast.h +4 -1
  28. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +331 -65
  29. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +13 -0
  30. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +15 -20
  31. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +1 -2
  32. data/ext/zstdruby/libzstd/compress/zstd_opt.c +503 -300
  33. data/ext/zstdruby/libzstd/compress/zstd_opt.h +7 -0
  34. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +122 -47
  35. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +5 -5
  36. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +325 -325
  37. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +80 -43
  38. data/ext/zstdruby/libzstd/dictBuilder/cover.c +9 -2
  39. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +5 -5
  40. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +12 -61
  41. data/ext/zstdruby/libzstd/zstd.h +137 -69
  42. data/lib/zstd-ruby/version.rb +1 -1
  43. metadata +7 -3
@@ -41,6 +41,17 @@
41
41
  #endif
42
42
 
43
43
 
44
+ /*!
45
+ * NO_FORWARD_PROGRESS_MAX :
46
+ * maximum allowed nb of calls to ZSTD_decompressStream() and ZSTD_decompress_generic()
47
+ * without any forward progress
48
+ * (defined as: no byte read from input, and no byte flushed to output)
49
+ * before triggering an error.
50
+ */
51
+ #ifndef ZSTD_NO_FORWARD_PROGRESS_MAX
52
+ # define ZSTD_NO_FORWARD_PROGRESS_MAX 16
53
+ #endif
54
+
44
55
  /*-*******************************************************
45
56
  * Dependencies
46
57
  *********************************************************/
@@ -115,8 +126,8 @@ struct ZSTD_DCtx_s
115
126
  const HUF_DTable* HUFptr;
116
127
  ZSTD_entropyDTables_t entropy;
117
128
  const void* previousDstEnd; /* detect continuity */
118
- const void* base; /* start of current segment */
119
- const void* vBase; /* virtual start of previous segment if it was just before current one */
129
+ const void* prefixStart; /* start of current segment */
130
+ const void* virtualStart; /* virtual start of previous segment if it was just before current one */
120
131
  const void* dictEnd; /* end of previous segment */
121
132
  size_t expected;
122
133
  ZSTD_frameHeader fParams;
@@ -153,6 +164,7 @@ struct ZSTD_DCtx_s
153
164
  U32 previousLegacyVersion;
154
165
  U32 legacyVersion;
155
166
  U32 hostageByte;
167
+ int noForwardProgress;
156
168
 
157
169
  /* workspace */
158
170
  BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
@@ -192,6 +204,9 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
192
204
  dctx->inBuffSize = 0;
193
205
  dctx->outBuffSize = 0;
194
206
  dctx->streamStage = zdss_init;
207
+ dctx->legacyContext = NULL;
208
+ dctx->previousLegacyVersion = 0;
209
+ dctx->noForwardProgress = 0;
195
210
  dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
196
211
  }
197
212
 
@@ -215,8 +230,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
215
230
  { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
216
231
  if (!dctx) return NULL;
217
232
  dctx->customMem = customMem;
218
- dctx->legacyContext = NULL;
219
- dctx->previousLegacyVersion = 0;
220
233
  ZSTD_initDCtx_internal(dctx);
221
234
  return dctx;
222
235
  }
@@ -298,20 +311,21 @@ static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZST
298
311
 
299
312
  /** ZSTD_frameHeaderSize() :
300
313
  * srcSize must be >= ZSTD_frameHeaderSize_prefix.
301
- * @return : size of the Frame Header */
314
+ * @return : size of the Frame Header,
315
+ * or an error code (if srcSize is too small) */
302
316
  size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
303
317
  {
304
318
  return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
305
319
  }
306
320
 
307
321
 
308
- /** ZSTD_getFrameHeader_internal() :
322
+ /** ZSTD_getFrameHeader_advanced() :
309
323
  * decode Frame Header, or require larger `srcSize`.
310
324
  * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
311
325
  * @return : 0, `zfhPtr` is correctly filled,
312
326
  * >0, `srcSize` is too small, value is wanted `srcSize` amount,
313
327
  * or an error code, which can be tested using ZSTD_isError() */
314
- static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
328
+ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
315
329
  {
316
330
  const BYTE* ip = (const BYTE*)src;
317
331
  size_t const minInputSize = ZSTD_startingInputLength(format);
@@ -394,7 +408,7 @@ static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void*
394
408
  * or an error code, which can be tested using ZSTD_isError() */
395
409
  size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
396
410
  {
397
- return ZSTD_getFrameHeader_internal(zfhPtr, src, srcSize, ZSTD_f_zstd1);
411
+ return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
398
412
  }
399
413
 
400
414
 
@@ -491,7 +505,7 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
491
505
  * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
492
506
  static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
493
507
  {
494
- size_t const result = ZSTD_getFrameHeader_internal(&(dctx->fParams), src, headerSize, dctx->format);
508
+ size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
495
509
  if (ZSTD_isError(result)) return result; /* invalid header */
496
510
  if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
497
511
  if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
@@ -594,7 +608,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
594
608
  HUF_decompress1X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) :
595
609
  HUF_decompress4X_usingDTable_bmi2(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr, dctx->bmi2) ) :
596
610
  ( singleStream ?
597
- HUF_decompress1X2_DCtx_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize,
611
+ HUF_decompress1X1_DCtx_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize,
598
612
  dctx->entropy.workspace, sizeof(dctx->entropy.workspace), dctx->bmi2) :
599
613
  HUF_decompress4X_hufOnly_wksp_bmi2(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize,
600
614
  dctx->entropy.workspace, sizeof(dctx->entropy.workspace), dctx->bmi2))))
@@ -1075,7 +1089,7 @@ HINT_INLINE
1075
1089
  size_t ZSTD_execSequence(BYTE* op,
1076
1090
  BYTE* const oend, seq_t sequence,
1077
1091
  const BYTE** litPtr, const BYTE* const litLimit,
1078
- const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
1092
+ const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)
1079
1093
  {
1080
1094
  BYTE* const oLitEnd = op + sequence.litLength;
1081
1095
  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
@@ -1087,7 +1101,7 @@ size_t ZSTD_execSequence(BYTE* op,
1087
1101
  /* check */
1088
1102
  if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1089
1103
  if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
1090
- if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1104
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);
1091
1105
 
1092
1106
  /* copy Literals */
1093
1107
  ZSTD_copy8(op, *litPtr);
@@ -1097,11 +1111,11 @@ size_t ZSTD_execSequence(BYTE* op,
1097
1111
  *litPtr = iLitEnd; /* update for next sequence */
1098
1112
 
1099
1113
  /* copy Match */
1100
- if (sequence.offset > (size_t)(oLitEnd - base)) {
1114
+ if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
1101
1115
  /* offset beyond prefix -> go into extDict */
1102
- if (sequence.offset > (size_t)(oLitEnd - vBase))
1116
+ if (sequence.offset > (size_t)(oLitEnd - virtualStart))
1103
1117
  return ERROR(corruption_detected);
1104
- match = dictEnd + (match - base);
1118
+ match = dictEnd + (match - prefixStart);
1105
1119
  if (match + sequence.matchLength <= dictEnd) {
1106
1120
  memmove(oLitEnd, match, sequence.matchLength);
1107
1121
  return sequenceLength;
@@ -1111,7 +1125,7 @@ size_t ZSTD_execSequence(BYTE* op,
1111
1125
  memmove(oLitEnd, match, length1);
1112
1126
  op = oLitEnd + length1;
1113
1127
  sequence.matchLength -= length1;
1114
- match = base;
1128
+ match = prefixStart;
1115
1129
  if (op > oend_w || sequence.matchLength < MINMATCH) {
1116
1130
  U32 i;
1117
1131
  for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
@@ -1354,10 +1368,10 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
1354
1368
  BYTE* op = ostart;
1355
1369
  const BYTE* litPtr = dctx->litPtr;
1356
1370
  const BYTE* const litEnd = litPtr + dctx->litSize;
1357
- const BYTE* const base = (const BYTE*) (dctx->base);
1358
- const BYTE* const vBase = (const BYTE*) (dctx->vBase);
1371
+ const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1372
+ const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
1359
1373
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1360
- DEBUGLOG(5, "ZSTD_decompressSequences");
1374
+ DEBUGLOG(5, "ZSTD_decompressSequences_body");
1361
1375
 
1362
1376
  /* Regen sequences */
1363
1377
  if (nbSeq) {
@@ -1372,14 +1386,14 @@ ZSTD_decompressSequences_body( ZSTD_DCtx* dctx,
1372
1386
  for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
1373
1387
  nbSeq--;
1374
1388
  { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1375
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
1389
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
1376
1390
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1377
1391
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1378
1392
  op += oneSeqSize;
1379
1393
  } }
1380
1394
 
1381
1395
  /* check if reached exact end */
1382
- DEBUGLOG(5, "ZSTD_decompressSequences: after decode loop, remaining nbSeq : %i", nbSeq);
1396
+ DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
1383
1397
  if (nbSeq) return ERROR(corruption_detected);
1384
1398
  /* save reps for next block */
1385
1399
  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
@@ -1498,8 +1512,8 @@ ZSTD_decompressSequencesLong_body(
1498
1512
  BYTE* op = ostart;
1499
1513
  const BYTE* litPtr = dctx->litPtr;
1500
1514
  const BYTE* const litEnd = litPtr + dctx->litSize;
1501
- const BYTE* const prefixStart = (const BYTE*) (dctx->base);
1502
- const BYTE* const dictStart = (const BYTE*) (dctx->vBase);
1515
+ const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1516
+ const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
1503
1517
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1504
1518
 
1505
1519
  /* Regen sequences */
@@ -1701,8 +1715,8 @@ static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
1701
1715
  {
1702
1716
  if (dst != dctx->previousDstEnd) { /* not contiguous */
1703
1717
  dctx->dictEnd = dctx->previousDstEnd;
1704
- dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1705
- dctx->base = dst;
1718
+ dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
1719
+ dctx->prefixStart = dst;
1706
1720
  dctx->previousDstEnd = dst;
1707
1721
  }
1708
1722
  }
@@ -1881,6 +1895,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1881
1895
  const ZSTD_DDict* ddict)
1882
1896
  {
1883
1897
  void* const dststart = dst;
1898
+ int moreThan1Frame = 0;
1884
1899
  assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */
1885
1900
 
1886
1901
  if (ddict) {
@@ -1889,7 +1904,6 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1889
1904
  }
1890
1905
 
1891
1906
  while (srcSize >= ZSTD_frameHeaderSize_prefix) {
1892
- U32 magicNumber;
1893
1907
 
1894
1908
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1895
1909
  if (ZSTD_isLegacy(src, srcSize)) {
@@ -1911,10 +1925,9 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1911
1925
  }
1912
1926
  #endif
1913
1927
 
1914
- magicNumber = MEM_readLE32(src);
1915
- DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1916
- (U32)magicNumber, (U32)ZSTD_MAGICNUMBER);
1917
- if (magicNumber != ZSTD_MAGICNUMBER) {
1928
+ { U32 const magicNumber = MEM_readLE32(src);
1929
+ DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1930
+ (U32)magicNumber, (U32)ZSTD_MAGICNUMBER);
1918
1931
  if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1919
1932
  size_t skippableSize;
1920
1933
  if (srcSize < ZSTD_skippableHeaderSize)
@@ -1926,9 +1939,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1926
1939
  src = (const BYTE *)src + skippableSize;
1927
1940
  srcSize -= skippableSize;
1928
1941
  continue;
1929
- }
1930
- return ERROR(prefix_unknown);
1931
- }
1942
+ } }
1932
1943
 
1933
1944
  if (ddict) {
1934
1945
  /* we were called from ZSTD_decompress_usingDDict */
@@ -1942,11 +1953,25 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1942
1953
 
1943
1954
  { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
1944
1955
  &src, &srcSize);
1956
+ if ( (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
1957
+ && (moreThan1Frame==1) ) {
1958
+ /* at least one frame successfully completed,
1959
+ * but following bytes are garbage :
1960
+ * it's more likely to be a srcSize error,
1961
+ * specifying more bytes than compressed size of frame(s).
1962
+ * This error message replaces ERROR(prefix_unknown),
1963
+ * which would be confusing, as the first header is actually correct.
1964
+ * Note that one could be unlucky, it might be a corruption error instead,
1965
+ * happening right at the place where we expect zstd magic bytes.
1966
+ * But this is _much_ less likely than a srcSize field error. */
1967
+ return ERROR(srcSize_wrong);
1968
+ }
1945
1969
  if (ZSTD_isError(res)) return res;
1946
1970
  /* no need to bound check, ZSTD_decompressFrame already has */
1947
1971
  dst = (BYTE*)dst + res;
1948
1972
  dstCapacity -= res;
1949
1973
  }
1974
+ moreThan1Frame = 1;
1950
1975
  } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
1951
1976
 
1952
1977
  if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */
@@ -1980,6 +2005,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
1980
2005
  return regenSize;
1981
2006
  #else /* stack mode */
1982
2007
  ZSTD_DCtx dctx;
2008
+ ZSTD_initDCtx_internal(&dctx);
1983
2009
  return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
1984
2010
  #endif
1985
2011
  }
@@ -2159,8 +2185,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
2159
2185
  static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
2160
2186
  {
2161
2187
  dctx->dictEnd = dctx->previousDstEnd;
2162
- dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
2163
- dctx->base = dict;
2188
+ dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
2189
+ dctx->prefixStart = dict;
2164
2190
  dctx->previousDstEnd = (const char*)dict + dictSize;
2165
2191
  return 0;
2166
2192
  }
@@ -2177,7 +2203,7 @@ static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const
2177
2203
  dictPtr += 8; /* skip header = magic + dictID */
2178
2204
 
2179
2205
 
2180
- { size_t const hSize = HUF_readDTableX4_wksp(
2206
+ { size_t const hSize = HUF_readDTableX2_wksp(
2181
2207
  entropy->hufTable, dictPtr, dictEnd - dictPtr,
2182
2208
  entropy->workspace, sizeof(entropy->workspace));
2183
2209
  if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
@@ -2264,8 +2290,8 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
2264
2290
  dctx->stage = ZSTDds_getFrameHeaderSize;
2265
2291
  dctx->decodedSize = 0;
2266
2292
  dctx->previousDstEnd = NULL;
2267
- dctx->base = NULL;
2268
- dctx->vBase = NULL;
2293
+ dctx->prefixStart = NULL;
2294
+ dctx->virtualStart = NULL;
2269
2295
  dctx->dictEnd = NULL;
2270
2296
  dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
2271
2297
  dctx->litEntropy = dctx->fseEntropy = 0;
@@ -2315,8 +2341,8 @@ size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddi
2315
2341
  CHECK_F( ZSTD_decompressBegin(dstDCtx) );
2316
2342
  if (ddict) { /* support begin on NULL */
2317
2343
  dstDCtx->dictID = ddict->dictID;
2318
- dstDCtx->base = ddict->dictContent;
2319
- dstDCtx->vBase = ddict->dictContent;
2344
+ dstDCtx->prefixStart = ddict->dictContent;
2345
+ dstDCtx->virtualStart = ddict->dictContent;
2320
2346
  dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
2321
2347
  dstDCtx->previousDstEnd = dstDCtx->dictEnd;
2322
2348
  if (ddict->entropyPresent) {
@@ -2607,6 +2633,7 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
2607
2633
  {
2608
2634
  DEBUGLOG(4, "ZSTD_initDStream_usingDict");
2609
2635
  zds->streamStage = zdss_init;
2636
+ zds->noForwardProgress = 0;
2610
2637
  CHECK_F( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );
2611
2638
  return ZSTD_frameHeaderSize_prefix;
2612
2639
  }
@@ -2767,7 +2794,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2767
2794
  return hint;
2768
2795
  } }
2769
2796
  #endif
2770
- { size_t const hSize = ZSTD_getFrameHeader_internal(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
2797
+ { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
2771
2798
  DEBUGLOG(5, "header size : %u", (U32)hSize);
2772
2799
  if (ZSTD_isError(hSize)) {
2773
2800
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
@@ -2947,8 +2974,18 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2947
2974
  } }
2948
2975
 
2949
2976
  /* result */
2950
- input->pos += (size_t)(ip-istart);
2951
- output->pos += (size_t)(op-ostart);
2977
+ input->pos = (size_t)(ip - (const char*)(input->src));
2978
+ output->pos = (size_t)(op - (char*)(output->dst));
2979
+ if ((ip==istart) && (op==ostart)) { /* no forward progress */
2980
+ zds->noForwardProgress ++;
2981
+ if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
2982
+ if (op==oend) return ERROR(dstSize_tooSmall);
2983
+ if (ip==iend) return ERROR(srcSize_wrong);
2984
+ assert(0);
2985
+ }
2986
+ } else {
2987
+ zds->noForwardProgress = 0;
2988
+ }
2952
2989
  { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
2953
2990
  if (!nextSrcSizeHint) { /* frame fully decoded */
2954
2991
  if (zds->outEnd == zds->outStart) { /* output fully flushed */
@@ -581,10 +581,17 @@ static int COVER_ctx_init(COVER_ctx_t *ctx, const void *samplesBuffer,
581
581
  for (i = 0; i < ctx->suffixSize; ++i) {
582
582
  ctx->suffix[i] = i;
583
583
  }
584
- /* qsort doesn't take an opaque pointer, so pass as a global */
584
+ /* qsort doesn't take an opaque pointer, so pass as a global.
585
+ * On OpenBSD qsort() is not guaranteed to be stable, their mergesort() is.
586
+ */
585
587
  g_ctx = ctx;
588
+ #if defined(__OpenBSD__)
589
+ mergesort(ctx->suffix, ctx->suffixSize, sizeof(U32),
590
+ (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
591
+ #else
586
592
  qsort(ctx->suffix, ctx->suffixSize, sizeof(U32),
587
593
  (ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp));
594
+ #endif
588
595
  }
589
596
  DISPLAYLEVEL(2, "Computing frequencies\n");
590
597
  /* For each dmer group (group of positions with the same first d bytes):
@@ -613,7 +620,7 @@ static size_t COVER_buildDictionary(const COVER_ctx_t *ctx, U32 *freqs,
613
620
  /* Divide the data up into epochs of equal size.
614
621
  * We will select at least one segment from each epoch.
615
622
  */
616
- const U32 epochs = (U32)(dictBufferCapacity / parameters.k);
623
+ const U32 epochs = MAX(1, (U32)(dictBufferCapacity / parameters.k / 4));
617
624
  const U32 epochSize = (U32)(ctx->suffixSize / epochs);
618
625
  size_t epoch;
619
626
  DISPLAYLEVEL(2, "Breaking content into %u epochs of size %u\n", epochs,
@@ -724,7 +724,7 @@ static size_t ZDICT_analyzeEntropy(void* dstBuffer, size_t maxDstSize,
724
724
  memset(repOffset, 0, sizeof(repOffset));
725
725
  repOffset[1] = repOffset[4] = repOffset[8] = 1;
726
726
  memset(bestRepOffset, 0, sizeof(bestRepOffset));
727
- if (compressionLevel<=0) compressionLevel = g_compressionLevel_default;
727
+ if (compressionLevel==0) compressionLevel = g_compressionLevel_default;
728
728
  params = ZSTD_getParams(compressionLevel, averageSampleSize, dictBufferSize);
729
729
  { size_t const beginResult = ZSTD_compressBegin_advanced(esr.ref, dictBuffer, dictBufferSize, params, 0);
730
730
  if (ZSTD_isError(beginResult)) {
@@ -873,7 +873,7 @@ size_t ZDICT_finalizeDictionary(void* dictBuffer, size_t dictBufferCapacity,
873
873
  size_t hSize;
874
874
  #define HBUFFSIZE 256 /* should prove large enough for all entropy headers */
875
875
  BYTE header[HBUFFSIZE];
876
- int const compressionLevel = (params.compressionLevel <= 0) ? g_compressionLevel_default : params.compressionLevel;
876
+ int const compressionLevel = (params.compressionLevel == 0) ? g_compressionLevel_default : params.compressionLevel;
877
877
  U32 const notificationLevel = params.notificationLevel;
878
878
 
879
879
  /* check conditions */
@@ -918,7 +918,7 @@ size_t ZDICT_addEntropyTablesFromBuffer_advanced(void* dictBuffer, size_t dictCo
918
918
  const void* samplesBuffer, const size_t* samplesSizes, unsigned nbSamples,
919
919
  ZDICT_params_t params)
920
920
  {
921
- int const compressionLevel = (params.compressionLevel <= 0) ? g_compressionLevel_default : params.compressionLevel;
921
+ int const compressionLevel = (params.compressionLevel == 0) ? g_compressionLevel_default : params.compressionLevel;
922
922
  U32 const notificationLevel = params.notificationLevel;
923
923
  size_t hSize = 8;
924
924
 
@@ -1089,8 +1089,8 @@ size_t ZDICT_trainFromBuffer(void* dictBuffer, size_t dictBufferCapacity,
1089
1089
  params.steps = 4;
1090
1090
  /* Default to level 6 since no compression level information is available */
1091
1091
  params.zParams.compressionLevel = 6;
1092
- #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
1093
- params.zParams.notificationLevel = ZSTD_DEBUG;
1092
+ #if defined(DEBUGLEVEL) && (DEBUGLEVEL>=1)
1093
+ params.zParams.notificationLevel = DEBUGLEVEL;
1094
1094
  #endif
1095
1095
  return ZDICT_optimizeTrainFromBuffer_cover(dictBuffer, dictBufferCapacity,
1096
1096
  samplesBuffer, samplesSizes, nbSamples,
@@ -9,14 +9,19 @@
9
9
  */
10
10
 
11
11
 
12
- /*- Dependencies -*/
12
+ /******************************************
13
+ * Includes
14
+ ******************************************/
15
+ #include <stddef.h> /* size_t, ptrdiff_t */
16
+ #include <string.h> /* memcpy */
17
+
13
18
  #include "zstd_v04.h"
14
19
  #include "error_private.h"
15
20
 
16
21
 
17
22
  /* ******************************************************************
18
- mem.h
19
- ****************************************************************** */
23
+ * mem.h
24
+ *******************************************************************/
20
25
  #ifndef MEM_H_MODULE
21
26
  #define MEM_H_MODULE
22
27
 
@@ -24,12 +29,6 @@
24
29
  extern "C" {
25
30
  #endif
26
31
 
27
- /******************************************
28
- * Includes
29
- ******************************************/
30
- #include <stddef.h> /* size_t, ptrdiff_t */
31
- #include <string.h> /* memcpy */
32
-
33
32
 
34
33
  /******************************************
35
34
  * Compiler-specific
@@ -75,38 +74,9 @@ extern "C" {
75
74
  /*-*************************************
76
75
  * Debug
77
76
  ***************************************/
78
- #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
79
- # include <assert.h>
80
- #else
81
- # ifndef assert
82
- # define assert(condition) ((void)0)
83
- # endif
84
- #endif
85
-
86
- #define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
87
-
88
- #if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
89
- # include <stdio.h>
90
- extern int g_debuglog_enable;
91
- /* recommended values for ZSTD_DEBUG display levels :
92
- * 1 : no display, enables assert() only
93
- * 2 : reserved for currently active debug path
94
- * 3 : events once per object lifetime (CCtx, CDict, etc.)
95
- * 4 : events once per frame
96
- * 5 : events once per block
97
- * 6 : events once per sequence (*very* verbose) */
98
- # define RAWLOG(l, ...) { \
99
- if ((g_debuglog_enable) & (l<=ZSTD_DEBUG)) { \
100
- fprintf(stderr, __VA_ARGS__); \
101
- } }
102
- # define DEBUGLOG(l, ...) { \
103
- if ((g_debuglog_enable) & (l<=ZSTD_DEBUG)) { \
104
- fprintf(stderr, __FILE__ ": " __VA_ARGS__); \
105
- fprintf(stderr, " \n"); \
106
- } }
107
- #else
108
- # define RAWLOG(l, ...) {} /* disabled */
109
- # define DEBUGLOG(l, ...) {} /* disabled */
77
+ #include "debug.h"
78
+ #ifndef assert
79
+ # define assert(condition) ((void)0)
110
80
  #endif
111
81
 
112
82
 
@@ -266,14 +236,6 @@ MEM_STATIC size_t MEM_readLEST(const void* memPtr)
266
236
  #ifndef ZSTD_STATIC_H
267
237
  #define ZSTD_STATIC_H
268
238
 
269
- /* The objects defined into this file shall be considered experimental.
270
- * They are not considered stable, as their prototype may change in the future.
271
- * You can use them for tests, provide feedback, or if you can endure risks of future changes.
272
- */
273
-
274
- #if defined (__cplusplus)
275
- extern "C" {
276
- #endif
277
239
 
278
240
  /* *************************************
279
241
  * Types
@@ -360,9 +322,6 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstS
360
322
  */
361
323
 
362
324
 
363
- #if defined (__cplusplus)
364
- }
365
- #endif
366
325
 
367
326
 
368
327
  #endif /* ZSTD_STATIC_H */
@@ -375,10 +334,6 @@ static size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t maxDstS
375
334
  #ifndef ZSTD_CCOMMON_H_MODULE
376
335
  #define ZSTD_CCOMMON_H_MODULE
377
336
 
378
- #if defined (__cplusplus)
379
- extern "C" {
380
- #endif
381
-
382
337
  /* *************************************
383
338
  * Common macros
384
339
  ***************************************/
@@ -450,10 +405,6 @@ static void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
450
405
  }
451
406
 
452
407
 
453
- #if defined (__cplusplus)
454
- }
455
- #endif
456
-
457
408
 
458
409
  /* ******************************************************************
459
410
  FSE : Finite State Entropy coder
@@ -2991,7 +2942,7 @@ static size_t ZSTD_execSequence(BYTE* op,
2991
2942
  }
2992
2943
  else
2993
2944
  {
2994
- ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
2945
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8, but must be signed */
2995
2946
  }
2996
2947
  return sequenceLength;
2997
2948
  }