zstd-ruby 1.3.1.1 → 1.3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/.gitignore +1 -0
  4. data/ext/zstdruby/libzstd/Makefile +40 -26
  5. data/ext/zstdruby/libzstd/README.md +68 -45
  6. data/ext/zstdruby/libzstd/common/bitstream.h +35 -23
  7. data/ext/zstdruby/libzstd/common/compiler.h +1 -0
  8. data/ext/zstdruby/libzstd/common/error_private.c +4 -2
  9. data/ext/zstdruby/libzstd/common/error_private.h +4 -4
  10. data/ext/zstdruby/libzstd/common/fse.h +1 -1
  11. data/ext/zstdruby/libzstd/common/huf.h +1 -1
  12. data/ext/zstdruby/libzstd/common/mem.h +1 -0
  13. data/ext/zstdruby/libzstd/common/pool.c +61 -46
  14. data/ext/zstdruby/libzstd/common/pool.h +4 -0
  15. data/ext/zstdruby/libzstd/common/threading.c +11 -15
  16. data/ext/zstdruby/libzstd/common/threading.h +52 -32
  17. data/ext/zstdruby/libzstd/common/zstd_common.c +2 -2
  18. data/ext/zstdruby/libzstd/common/zstd_errors.h +3 -1
  19. data/ext/zstdruby/libzstd/common/zstd_internal.h +95 -21
  20. data/ext/zstdruby/libzstd/compress/fse_compress.c +3 -1
  21. data/ext/zstdruby/libzstd/compress/huf_compress.c +4 -3
  22. data/ext/zstdruby/libzstd/compress/zstd_compress.c +922 -2102
  23. data/ext/zstdruby/libzstd/compress/zstd_compress.h +307 -0
  24. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +308 -0
  25. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +28 -0
  26. data/ext/zstdruby/libzstd/compress/zstd_fast.c +242 -0
  27. data/ext/zstdruby/libzstd/compress/zstd_fast.h +30 -0
  28. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +749 -0
  29. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +38 -0
  30. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +707 -0
  31. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +67 -0
  32. data/ext/zstdruby/libzstd/compress/zstd_opt.c +957 -0
  33. data/ext/zstdruby/libzstd/compress/zstd_opt.h +14 -922
  34. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +210 -133
  35. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +20 -3
  36. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +373 -196
  37. data/ext/zstdruby/libzstd/deprecated/zbuff.h +1 -0
  38. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +1 -0
  39. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -0
  40. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -0
  41. data/ext/zstdruby/libzstd/dictBuilder/cover.c +33 -22
  42. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +8 -5
  43. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +1 -0
  44. data/ext/zstdruby/libzstd/dll/example/Makefile +5 -5
  45. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +1 -0
  46. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +1 -0
  47. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +1 -0
  48. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +1 -0
  49. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +1 -0
  50. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +1 -0
  51. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +1 -0
  52. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +1 -0
  53. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +1 -0
  54. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +1 -0
  55. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +1 -0
  56. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +1 -0
  57. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +1 -0
  58. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +1 -0
  59. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +1 -0
  60. data/ext/zstdruby/libzstd/zstd.h +366 -118
  61. data/lib/zstd-ruby/version.rb +1 -1
  62. metadata +11 -1
@@ -5,6 +5,7 @@
5
5
  * This source code is licensed under both the BSD-style license (found in the
6
6
  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
7
  * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
8
9
  */
9
10
 
10
11
  #ifndef ZSTDMT_COMPRESS_H
@@ -80,19 +81,19 @@ ZSTDLIB_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,
80
81
  ZSTD_frameParameters fparams,
81
82
  unsigned long long pledgedSrcSize); /* note : zero means empty */
82
83
 
83
- /* ZSDTMT_parameter :
84
+ /* ZSTDMT_parameter :
84
85
  * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
85
86
  typedef enum {
86
87
  ZSTDMT_p_sectionSize, /* size of input "section". Each section is compressed in parallel. 0 means default, which is dynamically determined within compression functions */
87
88
  ZSTDMT_p_overlapSectionLog /* Log of overlapped section; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window */
88
- } ZSDTMT_parameter;
89
+ } ZSTDMT_parameter;
89
90
 
90
91
  /* ZSTDMT_setMTCtxParameter() :
91
92
  * allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
92
93
  * The function must be called typically after ZSTD_createCCtx().
93
94
  * Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
94
95
  * @return : 0, or an error code (which can be tested using ZSTD_isError()) */
95
- ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value);
96
+ ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, unsigned value);
96
97
 
97
98
 
98
99
  /*! ZSTDMT_compressStream_generic() :
@@ -107,6 +108,22 @@ ZSTDLIB_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,
107
108
  ZSTD_EndDirective endOp);
108
109
 
109
110
 
111
+ /* === Private definitions; never ever use directly === */
112
+
113
+ size_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, unsigned value);
114
+
115
+ size_t ZSTDMT_initializeCCtxParameters(ZSTD_CCtx_params* params, unsigned nbThreads);
116
+
117
+ /*! ZSTDMT_initCStream_internal() :
118
+ * Private use only. Init streaming operation.
119
+ * expects params to be valid.
120
+ * must receive dict, or cdict, or none, but not both.
121
+ * @return : 0, or an error code */
122
+ size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
123
+ const void* dict, size_t dictSize, ZSTD_dictMode_e dictMode,
124
+ const ZSTD_CDict* cdict,
125
+ ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);
126
+
110
127
 
111
128
  #if defined (__cplusplus)
112
129
  }
@@ -5,6 +5,7 @@
5
5
  * This source code is licensed under both the BSD-style license (found in the
6
6
  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
7
  * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
8
9
  */
9
10
 
10
11
 
@@ -34,7 +35,7 @@
34
35
  * Frames requiring more memory will be rejected.
35
36
  */
36
37
  #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
37
- # define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
38
+ # define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_DEFAULTMAX) + 1)
38
39
  #endif
39
40
 
40
41
 
@@ -101,13 +102,15 @@ struct ZSTD_DCtx_s
101
102
  const void* dictEnd; /* end of previous segment */
102
103
  size_t expected;
103
104
  ZSTD_frameHeader fParams;
104
- blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
105
+ U64 decodedSize;
106
+ blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
105
107
  ZSTD_dStage stage;
106
108
  U32 litEntropy;
107
109
  U32 fseEntropy;
108
110
  XXH64_state_t xxhState;
109
111
  size_t headerSize;
110
112
  U32 dictID;
113
+ ZSTD_format_e format;
111
114
  const BYTE* litPtr;
112
115
  ZSTD_customMem customMem;
113
116
  size_t litSize;
@@ -126,7 +129,6 @@ struct ZSTD_DCtx_s
126
129
  size_t outBuffSize;
127
130
  size_t outStart;
128
131
  size_t outEnd;
129
- size_t blockSize;
130
132
  size_t lhSize;
131
133
  void* legacyContext;
132
134
  U32 previousLegacyVersion;
@@ -148,39 +150,44 @@ size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
148
150
 
149
151
  size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
150
152
 
151
- size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
153
+
154
+ static size_t ZSTD_startingInputLength(ZSTD_format_e format)
152
155
  {
153
- dctx->expected = ZSTD_frameHeaderSize_prefix;
154
- dctx->stage = ZSTDds_getFrameHeaderSize;
155
- dctx->previousDstEnd = NULL;
156
- dctx->base = NULL;
157
- dctx->vBase = NULL;
158
- dctx->dictEnd = NULL;
159
- dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
160
- dctx->litEntropy = dctx->fseEntropy = 0;
161
- dctx->dictID = 0;
162
- MEM_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
163
- memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
164
- dctx->LLTptr = dctx->entropy.LLTable;
165
- dctx->MLTptr = dctx->entropy.MLTable;
166
- dctx->OFTptr = dctx->entropy.OFTable;
167
- dctx->HUFptr = dctx->entropy.hufTable;
168
- return 0;
156
+ size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ?
157
+ ZSTD_frameHeaderSize_prefix - ZSTD_frameIdSize :
158
+ ZSTD_frameHeaderSize_prefix;
159
+ ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE);
160
+ /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
161
+ assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
162
+ return startingInputLength;
169
163
  }
170
164
 
171
165
  static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
172
166
  {
173
- ZSTD_decompressBegin(dctx); /* cannot fail */
174
- dctx->staticSize = 0;
167
+ dctx->format = ZSTD_f_zstd1; /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */
168
+ dctx->staticSize = 0;
175
169
  dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
176
- dctx->ddict = NULL;
177
- dctx->ddictLocal = NULL;
178
- dctx->inBuff = NULL;
179
- dctx->inBuffSize = 0;
180
- dctx->outBuffSize= 0;
170
+ dctx->ddict = NULL;
171
+ dctx->ddictLocal = NULL;
172
+ dctx->inBuff = NULL;
173
+ dctx->inBuffSize = 0;
174
+ dctx->outBuffSize = 0;
181
175
  dctx->streamStage = zdss_init;
182
176
  }
183
177
 
178
+ ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
179
+ {
180
+ ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;
181
+
182
+ if ((size_t)workspace & 7) return NULL; /* 8-aligned */
183
+ if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
184
+
185
+ ZSTD_initDCtx_internal(dctx);
186
+ dctx->staticSize = workspaceSize;
187
+ dctx->inBuff = (char*)(dctx+1);
188
+ return dctx;
189
+ }
190
+
184
191
  ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
185
192
  {
186
193
  if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
@@ -195,19 +202,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
195
202
  }
196
203
  }
197
204
 
198
- ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
199
- {
200
- ZSTD_DCtx* dctx = (ZSTD_DCtx*) workspace;
201
-
202
- if ((size_t)workspace & 7) return NULL; /* 8-aligned */
203
- if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL; /* minimum size */
204
-
205
- ZSTD_initDCtx_internal(dctx);
206
- dctx->staticSize = workspaceSize;
207
- dctx->inBuff = (char*)(dctx+1);
208
- return dctx;
209
- }
210
-
211
205
  ZSTD_DCtx* ZSTD_createDCtx(void)
212
206
  {
213
207
  return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
@@ -250,7 +244,7 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
250
244
  * Note 3 : Skippable Frame Identifiers are considered valid. */
251
245
  unsigned ZSTD_isFrame(const void* buffer, size_t size)
252
246
  {
253
- if (size < 4) return 0;
247
+ if (size < ZSTD_frameIdSize) return 0;
254
248
  { U32 const magic = MEM_readLE32(buffer);
255
249
  if (magic == ZSTD_MAGICNUMBER) return 1;
256
250
  if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
@@ -261,55 +255,70 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
261
255
  return 0;
262
256
  }
263
257
 
264
-
265
- /** ZSTD_frameHeaderSize() :
266
- * srcSize must be >= ZSTD_frameHeaderSize_prefix.
267
- * @return : size of the Frame Header */
268
- size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
258
+ /** ZSTD_frameHeaderSize_internal() :
259
+ * srcSize must be large enough to reach header size fields.
260
+ * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
261
+ * @return : size of the Frame Header
262
+ * or an error code, which can be tested with ZSTD_isError() */
263
+ static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
269
264
  {
270
- if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
271
- { BYTE const fhd = ((const BYTE*)src)[4];
265
+ size_t const minInputSize = ZSTD_startingInputLength(format);
266
+ if (srcSize < minInputSize) return ERROR(srcSize_wrong);
267
+
268
+ { BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
272
269
  U32 const dictID= fhd & 3;
273
270
  U32 const singleSegment = (fhd >> 5) & 1;
274
271
  U32 const fcsId = fhd >> 6;
275
- return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
276
- + (singleSegment && !fcsId);
272
+ return minInputSize + !singleSegment
273
+ + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
274
+ + (singleSegment && !fcsId);
277
275
  }
278
276
  }
279
277
 
278
+ /** ZSTD_frameHeaderSize() :
279
+ * srcSize must be >= ZSTD_frameHeaderSize_prefix.
280
+ * @return : size of the Frame Header */
281
+ size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
282
+ {
283
+ return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
284
+ }
280
285
 
281
- /** ZSTD_getFrameHeader() :
282
- * decode Frame Header, or require larger `srcSize`.
283
- * @return : 0, `zfhPtr` is correctly filled,
284
- * >0, `srcSize` is too small, result is expected `srcSize`,
285
- * or an error code, which can be tested using ZSTD_isError() */
286
- size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
286
+
287
+ /** ZSTD_getFrameHeader_internal() :
288
+ * decode Frame Header, or require larger `srcSize`.
289
+ * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
290
+ * @return : 0, `zfhPtr` is correctly filled,
291
+ * >0, `srcSize` is too small, value is wanted `srcSize` amount,
292
+ * or an error code, which can be tested using ZSTD_isError() */
293
+ static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
287
294
  {
288
295
  const BYTE* ip = (const BYTE*)src;
289
- if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
296
+ size_t const minInputSize = ZSTD_startingInputLength(format);
290
297
 
291
- if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
298
+ if (srcSize < minInputSize) return minInputSize;
299
+
300
+ if ( (format != ZSTD_f_zstd1_magicless)
301
+ && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
292
302
  if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
293
303
  /* skippable frame */
294
304
  if (srcSize < ZSTD_skippableHeaderSize)
295
305
  return ZSTD_skippableHeaderSize; /* magic number + frame length */
296
306
  memset(zfhPtr, 0, sizeof(*zfhPtr));
297
- zfhPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
307
+ zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_frameIdSize);
298
308
  zfhPtr->frameType = ZSTD_skippableFrame;
299
- zfhPtr->windowSize = 0;
300
309
  return 0;
301
310
  }
302
311
  return ERROR(prefix_unknown);
303
312
  }
304
313
 
305
314
  /* ensure there is enough `srcSize` to fully read/decode frame header */
306
- { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
315
+ { size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);
307
316
  if (srcSize < fhsize) return fhsize;
308
317
  zfhPtr->headerSize = (U32)fhsize;
309
318
  }
310
319
 
311
- { BYTE const fhdByte = ip[4];
312
- size_t pos = 5;
320
+ { BYTE const fhdByte = ip[minInputSize-1];
321
+ size_t pos = minInputSize;
313
322
  U32 const dictIDSizeCode = fhdByte&3;
314
323
  U32 const checksumFlag = (fhdByte>>2)&1;
315
324
  U32 const singleSegment = (fhdByte>>5)&1;
@@ -349,12 +358,25 @@ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t src
349
358
  zfhPtr->frameType = ZSTD_frame;
350
359
  zfhPtr->frameContentSize = frameContentSize;
351
360
  zfhPtr->windowSize = windowSize;
361
+ zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
352
362
  zfhPtr->dictID = dictID;
353
363
  zfhPtr->checksumFlag = checksumFlag;
354
364
  }
355
365
  return 0;
356
366
  }
357
367
 
368
+ /** ZSTD_getFrameHeader() :
369
+ * decode Frame Header, or require larger `srcSize`.
370
+ * note : this function does not consume input, it only reads it.
371
+ * @return : 0, `zfhPtr` is correctly filled,
372
+ * >0, `srcSize` is too small, value is wanted `srcSize` amount,
373
+ * or an error code, which can be tested using ZSTD_isError() */
374
+ size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
375
+ {
376
+ return ZSTD_getFrameHeader_internal(zfhPtr, src, srcSize, ZSTD_f_zstd1);
377
+ }
378
+
379
+
358
380
  /** ZSTD_getFrameContentSize() :
359
381
  * compatible with legacy mode
360
382
  * @return : decompressed size of the single frame pointed to be `src` if known, otherwise
@@ -388,14 +410,14 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
388
410
  unsigned long long totalDstSize = 0;
389
411
 
390
412
  while (srcSize >= ZSTD_frameHeaderSize_prefix) {
391
- const U32 magicNumber = MEM_readLE32(src);
413
+ U32 const magicNumber = MEM_readLE32(src);
392
414
 
393
415
  if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
394
416
  size_t skippableSize;
395
417
  if (srcSize < ZSTD_skippableHeaderSize)
396
418
  return ERROR(srcSize_wrong);
397
- skippableSize = MEM_readLE32((const BYTE *)src + 4) +
398
- ZSTD_skippableHeaderSize;
419
+ skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_frameIdSize)
420
+ + ZSTD_skippableHeaderSize;
399
421
  if (srcSize < skippableSize) {
400
422
  return ZSTD_CONTENTSIZE_ERROR;
401
423
  }
@@ -420,11 +442,9 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
420
442
  src = (const BYTE *)src + frameSrcSize;
421
443
  srcSize -= frameSrcSize;
422
444
  }
423
- }
445
+ } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
424
446
 
425
- if (srcSize) {
426
- return ZSTD_CONTENTSIZE_ERROR;
427
- }
447
+ if (srcSize) return ZSTD_CONTENTSIZE_ERROR;
428
448
 
429
449
  return totalDstSize;
430
450
  }
@@ -440,7 +460,8 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
440
460
  unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
441
461
  {
442
462
  unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
443
- return ret >= ZSTD_CONTENTSIZE_ERROR ? 0 : ret;
463
+ ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN);
464
+ return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;
444
465
  }
445
466
 
446
467
 
@@ -449,9 +470,9 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
449
470
  * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
450
471
  static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
451
472
  {
452
- size_t const result = ZSTD_getFrameHeader(&(dctx->fParams), src, headerSize);
453
- if (ZSTD_isError(result)) return result; /* invalid header */
454
- if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
473
+ size_t const result = ZSTD_getFrameHeader_internal(&(dctx->fParams), src, headerSize, dctx->format);
474
+ if (ZSTD_isError(result)) return result; /* invalid header */
475
+ if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
455
476
  if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
456
477
  return ERROR(dictionary_wrong);
457
478
  if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
@@ -497,7 +518,8 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
497
518
  }
498
519
 
499
520
  /*! ZSTD_decodeLiteralsBlock() :
500
- @return : nb of bytes read from src (< srcSize ) */
521
+ * @return : nb of bytes read from src (< srcSize )
522
+ * note : symbol not declared but exposed for fullbench */
501
523
  size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
502
524
  const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
503
525
  {
@@ -698,9 +720,9 @@ static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
698
720
  }; /* OF_defaultDTable */
699
721
 
700
722
  /*! ZSTD_buildSeqTable() :
701
- @return : nb bytes read from src,
702
- or an error code if it fails, testable with ZSTD_isError()
703
- */
723
+ * @return : nb bytes read from src,
724
+ * or an error code if it fails, testable with ZSTD_isError()
725
+ */
704
726
  static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
705
727
  symbolEncodingType_e type, U32 max, U32 maxLog,
706
728
  const void* src, size_t srcSize,
@@ -858,13 +880,25 @@ size_t ZSTD_execSequenceLast7(BYTE* op,
858
880
  }
859
881
 
860
882
 
861
- static seq_t ZSTD_decodeSequence(seqState_t* seqState)
883
+ typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
884
+
885
+ /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
886
+ * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
887
+ * bits before reloading. This value is the maximum number of bytes we read
888
+ * after reloading when we are decoding long offets.
889
+ */
890
+ #define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
891
+ (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
892
+ ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
893
+ : 0)
894
+
895
+ static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
862
896
  {
863
897
  seq_t seq;
864
898
 
865
899
  U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
866
900
  U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
867
- U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
901
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
868
902
 
869
903
  U32 const llBits = LL_bits[llCode];
870
904
  U32 const mlBits = ML_bits[mlCode];
@@ -891,15 +925,25 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
891
925
  0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
892
926
  0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
893
927
  0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
894
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
928
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
895
929
 
896
930
  /* sequence */
897
931
  { size_t offset;
898
932
  if (!ofCode)
899
933
  offset = 0;
900
934
  else {
901
- offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
902
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
935
+ ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
936
+ ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
937
+ assert(ofBits <= MaxOff);
938
+ if (MEM_32bits() && longOffsets) {
939
+ U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
940
+ offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
941
+ if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
942
+ if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
943
+ } else {
944
+ offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
945
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
946
+ }
903
947
  }
904
948
 
905
949
  if (ofCode <= 1) {
@@ -923,13 +967,17 @@ static seq_t ZSTD_decodeSequence(seqState_t* seqState)
923
967
 
924
968
  seq.matchLength = ML_base[mlCode]
925
969
  + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
926
- if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
970
+ if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
971
+ BIT_reloadDStream(&seqState->DStream);
972
+ if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
973
+ BIT_reloadDStream(&seqState->DStream);
974
+ /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
975
+ ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
927
976
 
928
977
  seq.litLength = LL_base[llCode]
929
978
  + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
930
- if ( MEM_32bits()
931
- || (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) )
932
- BIT_reloadDStream(&seqState->DStream);
979
+ if (MEM_32bits())
980
+ BIT_reloadDStream(&seqState->DStream);
933
981
 
934
982
  DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
935
983
  (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
@@ -1028,7 +1076,8 @@ size_t ZSTD_execSequence(BYTE* op,
1028
1076
  static size_t ZSTD_decompressSequences(
1029
1077
  ZSTD_DCtx* dctx,
1030
1078
  void* dst, size_t maxDstSize,
1031
- const void* seqStart, size_t seqSize)
1079
+ const void* seqStart, size_t seqSize,
1080
+ const ZSTD_longOffset_e isLongOffset)
1032
1081
  {
1033
1082
  const BYTE* ip = (const BYTE*)seqStart;
1034
1083
  const BYTE* const iend = ip + seqSize;
@@ -1063,7 +1112,7 @@ static size_t ZSTD_decompressSequences(
1063
1112
 
1064
1113
  for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
1065
1114
  nbSeq--;
1066
- { seq_t const sequence = ZSTD_decodeSequence(&seqState);
1115
+ { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1067
1116
  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
1068
1117
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1069
1118
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
@@ -1088,13 +1137,14 @@ static size_t ZSTD_decompressSequences(
1088
1137
  }
1089
1138
 
1090
1139
 
1091
- FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int const longOffsets)
1140
+ HINT_INLINE
1141
+ seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
1092
1142
  {
1093
1143
  seq_t seq;
1094
1144
 
1095
1145
  U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
1096
1146
  U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
1097
- U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
1147
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
1098
1148
 
1099
1149
  U32 const llBits = LL_bits[llCode];
1100
1150
  U32 const mlBits = ML_bits[mlCode];
@@ -1121,15 +1171,18 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
1121
1171
  0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
1122
1172
  0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
1123
1173
  0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
1124
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
1174
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
1125
1175
 
1126
1176
  /* sequence */
1127
1177
  { size_t offset;
1128
1178
  if (!ofCode)
1129
1179
  offset = 0;
1130
1180
  else {
1131
- if (longOffsets) {
1132
- int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
1181
+ ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
1182
+ ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
1183
+ assert(ofBits <= MaxOff);
1184
+ if (MEM_32bits() && longOffsets) {
1185
+ U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
1133
1186
  offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
1134
1187
  if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
1135
1188
  if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
@@ -1159,11 +1212,16 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
1159
1212
  }
1160
1213
 
1161
1214
  seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
1162
- if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
1215
+ if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
1216
+ BIT_reloadDStream(&seqState->DStream);
1217
+ if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
1218
+ BIT_reloadDStream(&seqState->DStream);
1219
+ /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
1220
+ ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
1163
1221
 
1164
1222
  seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
1165
- if (MEM_32bits() ||
1166
- (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
1223
+ if (MEM_32bits())
1224
+ BIT_reloadDStream(&seqState->DStream);
1167
1225
 
1168
1226
  { size_t const pos = seqState->pos + seq.litLength;
1169
1227
  seq.match = seqState->base + pos - seq.offset; /* single memory segment */
@@ -1180,19 +1238,12 @@ FORCE_INLINE_TEMPLATE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState
1180
1238
  return seq;
1181
1239
  }
1182
1240
 
1183
- static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
1184
- if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
1185
- return ZSTD_decodeSequenceLong_generic(seqState, 1);
1186
- } else {
1187
- return ZSTD_decodeSequenceLong_generic(seqState, 0);
1188
- }
1189
- }
1190
1241
 
1191
1242
  HINT_INLINE
1192
1243
  size_t ZSTD_execSequenceLong(BYTE* op,
1193
- BYTE* const oend, seq_t sequence,
1194
- const BYTE** litPtr, const BYTE* const litLimit,
1195
- const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
1244
+ BYTE* const oend, seq_t sequence,
1245
+ const BYTE** litPtr, const BYTE* const litLimit,
1246
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
1196
1247
  {
1197
1248
  BYTE* const oLitEnd = op + sequence.litLength;
1198
1249
  size_t const sequenceLength = sequence.litLength + sequence.matchLength;
@@ -1202,11 +1253,9 @@ size_t ZSTD_execSequenceLong(BYTE* op,
1202
1253
  const BYTE* match = sequence.match;
1203
1254
 
1204
1255
  /* check */
1205
- #if 1
1206
1256
  if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1207
1257
  if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
1208
1258
  if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1209
- #endif
1210
1259
 
1211
1260
  /* copy Literals */
1212
1261
  ZSTD_copy8(op, *litPtr);
@@ -1216,7 +1265,6 @@ size_t ZSTD_execSequenceLong(BYTE* op,
1216
1265
  *litPtr = iLitEnd; /* update for next sequence */
1217
1266
 
1218
1267
  /* copy Match */
1219
- #if 1
1220
1268
  if (sequence.offset > (size_t)(oLitEnd - base)) {
1221
1269
  /* offset beyond prefix */
1222
1270
  if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
@@ -1236,8 +1284,8 @@ size_t ZSTD_execSequenceLong(BYTE* op,
1236
1284
  return sequenceLength;
1237
1285
  }
1238
1286
  } }
1239
- /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1240
- #endif
1287
+ assert(op <= oend_w);
1288
+ assert(sequence.matchLength >= MINMATCH);
1241
1289
 
1242
1290
  /* match within prefix */
1243
1291
  if (sequence.offset < 8) {
@@ -1273,7 +1321,8 @@ size_t ZSTD_execSequenceLong(BYTE* op,
1273
1321
  static size_t ZSTD_decompressSequencesLong(
1274
1322
  ZSTD_DCtx* dctx,
1275
1323
  void* dst, size_t maxDstSize,
1276
- const void* seqStart, size_t seqSize)
1324
+ const void* seqStart, size_t seqSize,
1325
+ const ZSTD_longOffset_e isLongOffset)
1277
1326
  {
1278
1327
  const BYTE* ip = (const BYTE*)seqStart;
1279
1328
  const BYTE* const iend = ip + seqSize;
@@ -1285,7 +1334,6 @@ static size_t ZSTD_decompressSequencesLong(
1285
1334
  const BYTE* const base = (const BYTE*) (dctx->base);
1286
1335
  const BYTE* const vBase = (const BYTE*) (dctx->vBase);
1287
1336
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1288
- unsigned const windowSize32 = (unsigned)dctx->fParams.windowSize;
1289
1337
  int nbSeq;
1290
1338
 
1291
1339
  /* Build Decoding Tables */
@@ -1315,13 +1363,13 @@ static size_t ZSTD_decompressSequencesLong(
1315
1363
 
1316
1364
  /* prepare in advance */
1317
1365
  for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) {
1318
- sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, windowSize32);
1366
+ sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
1319
1367
  }
1320
1368
  if (seqNb<seqAdvance) return ERROR(corruption_detected);
1321
1369
 
1322
1370
  /* decode and decompress */
1323
1371
  for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) {
1324
- seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, windowSize32);
1372
+ seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
1325
1373
  size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
1326
1374
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1327
1375
  PREFETCH(sequence.match);
@@ -1355,10 +1403,20 @@ static size_t ZSTD_decompressSequencesLong(
1355
1403
 
1356
1404
  static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1357
1405
  void* dst, size_t dstCapacity,
1358
- const void* src, size_t srcSize)
1406
+ const void* src, size_t srcSize, const int frame)
1359
1407
  { /* blockType == blockCompressed */
1360
1408
  const BYTE* ip = (const BYTE*)src;
1361
- DEBUGLOG(5, "ZSTD_decompressBlock_internal");
1409
+ /* isLongOffset must be true if there are long offsets.
1410
+ * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
1411
+ * We don't expect that to be the case in 64-bit mode.
1412
+ * If we are in block mode we don't know the window size, so we have to be
1413
+ * conservative.
1414
+ */
1415
+ ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN)));
1416
+ /* windowSize could be any value at this point, since it is only validated
1417
+ * in the streaming API.
1418
+ */
1419
+ DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
1362
1420
 
1363
1421
  if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
1364
1422
 
@@ -1369,13 +1427,9 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1369
1427
  ip += litCSize;
1370
1428
  srcSize -= litCSize;
1371
1429
  }
1372
- if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
1373
- /* likely because of register pressure */
1374
- /* if that's the correct cause, then 32-bits ARM should be affected differently */
1375
- /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
1376
- if (dctx->fParams.windowSize > (1<<23))
1377
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
1378
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
1430
+ if (frame && dctx->fParams.windowSize > (1<<23))
1431
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
1432
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
1379
1433
  }
1380
1434
 
1381
1435
 
@@ -1395,7 +1449,7 @@ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
1395
1449
  {
1396
1450
  size_t dSize;
1397
1451
  ZSTD_checkContinuity(dctx, dst);
1398
- dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
1452
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);
1399
1453
  dctx->previousDstEnd = (char*)dst + dSize;
1400
1454
  return dSize;
1401
1455
  }
@@ -1411,7 +1465,7 @@ ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, siz
1411
1465
  }
1412
1466
 
1413
1467
 
1414
- size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
1468
+ static size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
1415
1469
  {
1416
1470
  if (length > dstCapacity) return ERROR(dstSize_tooSmall);
1417
1471
  memset(dst, byte, length);
@@ -1431,7 +1485,7 @@ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
1431
1485
  #endif
1432
1486
  if ( (srcSize >= ZSTD_skippableHeaderSize)
1433
1487
  && (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START ) {
1434
- return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4);
1488
+ return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize);
1435
1489
  } else {
1436
1490
  const BYTE* ip = (const BYTE*)src;
1437
1491
  const BYTE* const ipstart = ip;
@@ -1511,7 +1565,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1511
1565
  switch(blockProperties.blockType)
1512
1566
  {
1513
1567
  case bt_compressed:
1514
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
1568
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1);
1515
1569
  break;
1516
1570
  case bt_raw :
1517
1571
  decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
@@ -1533,6 +1587,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1533
1587
  if (blockProperties.lastBlock) break;
1534
1588
  }
1535
1589
 
1590
+ if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1591
+ if ((U64)(op-ostart) != dctx->fParams.frameContentSize) {
1592
+ return ERROR(corruption_detected);
1593
+ } }
1536
1594
  if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1537
1595
  U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
1538
1596
  U32 checkRead;
@@ -1590,13 +1648,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1590
1648
  #endif
1591
1649
 
1592
1650
  magicNumber = MEM_readLE32(src);
1651
+ DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1652
+ (U32)magicNumber, (U32)ZSTD_MAGICNUMBER);
1593
1653
  if (magicNumber != ZSTD_MAGICNUMBER) {
1594
1654
  if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1595
1655
  size_t skippableSize;
1596
1656
  if (srcSize < ZSTD_skippableHeaderSize)
1597
1657
  return ERROR(srcSize_wrong);
1598
- skippableSize = MEM_readLE32((const BYTE *)src + 4) +
1599
- ZSTD_skippableHeaderSize;
1658
+ skippableSize = MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize)
1659
+ + ZSTD_skippableHeaderSize;
1600
1660
  if (srcSize < skippableSize) return ERROR(srcSize_wrong);
1601
1661
 
1602
1662
  src = (const BYTE *)src + skippableSize;
@@ -1699,33 +1759,31 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1699
1759
  {
1700
1760
  DEBUGLOG(5, "ZSTD_decompressContinue");
1701
1761
  /* Sanity check */
1702
- if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* unauthorized */
1762
+ if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* not allowed */
1703
1763
  if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
1704
1764
 
1705
1765
  switch (dctx->stage)
1706
1766
  {
1707
1767
  case ZSTDds_getFrameHeaderSize :
1708
- if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* unauthorized */
1709
1768
  assert(src != NULL);
1710
- if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1711
- memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1712
- dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
1713
- dctx->stage = ZSTDds_decodeSkippableHeader;
1714
- return 0;
1715
- }
1716
- dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
1769
+ if (dctx->format == ZSTD_f_zstd1) { /* allows header */
1770
+ assert(srcSize >= ZSTD_frameIdSize); /* to read skippable magic number */
1771
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1772
+ memcpy(dctx->headerBuffer, src, srcSize);
1773
+ dctx->expected = ZSTD_skippableHeaderSize - srcSize; /* remaining to load to get full skippable frame header */
1774
+ dctx->stage = ZSTDds_decodeSkippableHeader;
1775
+ return 0;
1776
+ } }
1777
+ dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);
1717
1778
  if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1718
- memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1719
- if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
1720
- dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
1721
- dctx->stage = ZSTDds_decodeFrameHeader;
1722
- return 0;
1723
- }
1724
- dctx->expected = 0; /* not necessary to copy more */
1725
- /* fall-through */
1779
+ memcpy(dctx->headerBuffer, src, srcSize);
1780
+ dctx->expected = dctx->headerSize - srcSize;
1781
+ dctx->stage = ZSTDds_decodeFrameHeader;
1782
+ return 0;
1783
+
1726
1784
  case ZSTDds_decodeFrameHeader:
1727
1785
  assert(src != NULL);
1728
- memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1786
+ memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
1729
1787
  CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
1730
1788
  dctx->expected = ZSTD_blockHeaderSize;
1731
1789
  dctx->stage = ZSTDds_decodeBlockHeader;
@@ -1757,6 +1815,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1757
1815
  }
1758
1816
  return 0;
1759
1817
  }
1818
+
1760
1819
  case ZSTDds_decompressLastBlock:
1761
1820
  case ZSTDds_decompressBlock:
1762
1821
  DEBUGLOG(5, "case ZSTDds_decompressBlock");
@@ -1765,7 +1824,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1765
1824
  {
1766
1825
  case bt_compressed:
1767
1826
  DEBUGLOG(5, "case bt_compressed");
1768
- rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
1827
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);
1769
1828
  break;
1770
1829
  case bt_raw :
1771
1830
  rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
@@ -1778,9 +1837,16 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1778
1837
  return ERROR(corruption_detected);
1779
1838
  }
1780
1839
  if (ZSTD_isError(rSize)) return rSize;
1840
+ DEBUGLOG(5, "decoded size from block : %u", (U32)rSize);
1841
+ dctx->decodedSize += rSize;
1781
1842
  if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
1782
1843
 
1783
1844
  if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1845
+ DEBUGLOG(4, "decoded size from frame : %u", (U32)dctx->decodedSize);
1846
+ if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1847
+ if (dctx->decodedSize != dctx->fParams.frameContentSize) {
1848
+ return ERROR(corruption_detected);
1849
+ } }
1784
1850
  if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1785
1851
  dctx->expected = 4;
1786
1852
  dctx->stage = ZSTDds_checkChecksum;
@@ -1795,26 +1861,31 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1795
1861
  }
1796
1862
  return rSize;
1797
1863
  }
1864
+
1798
1865
  case ZSTDds_checkChecksum:
1866
+ assert(srcSize == 4); /* guaranteed by dctx->expected */
1799
1867
  { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1800
- U32 const check32 = MEM_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
1868
+ U32 const check32 = MEM_readLE32(src);
1869
+ DEBUGLOG(4, "checksum : calculated %08X :: %08X read", h32, check32);
1801
1870
  if (check32 != h32) return ERROR(checksum_wrong);
1802
1871
  dctx->expected = 0;
1803
1872
  dctx->stage = ZSTDds_getFrameHeaderSize;
1804
1873
  return 0;
1805
1874
  }
1875
+
1806
1876
  case ZSTDds_decodeSkippableHeader:
1807
- { assert(src != NULL);
1808
- memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1809
- dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
1810
- dctx->stage = ZSTDds_skipFrame;
1811
- return 0;
1812
- }
1877
+ assert(src != NULL);
1878
+ assert(srcSize <= ZSTD_skippableHeaderSize);
1879
+ memcpy(dctx->headerBuffer + (ZSTD_skippableHeaderSize - srcSize), src, srcSize); /* complete skippable header */
1880
+ dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_frameIdSize); /* note : dctx->expected can grow seriously large, beyond local buffer size */
1881
+ dctx->stage = ZSTDds_skipFrame;
1882
+ return 0;
1883
+
1813
1884
  case ZSTDds_skipFrame:
1814
- { dctx->expected = 0;
1815
- dctx->stage = ZSTDds_getFrameHeaderSize;
1816
- return 0;
1817
- }
1885
+ dctx->expected = 0;
1886
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1887
+ return 0;
1888
+
1818
1889
  default:
1819
1890
  return ERROR(GENERIC); /* impossible */
1820
1891
  }
@@ -1895,7 +1966,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
1895
1966
  if (magic != ZSTD_MAGIC_DICTIONARY) {
1896
1967
  return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
1897
1968
  } }
1898
- dctx->dictID = MEM_readLE32((const char*)dict + 4);
1969
+ dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
1899
1970
 
1900
1971
  /* load entropy tables */
1901
1972
  { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
@@ -1909,6 +1980,29 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
1909
1980
  return ZSTD_refDictContent(dctx, dict, dictSize);
1910
1981
  }
1911
1982
 
1983
+ /* Note : this function cannot fail */
1984
+ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1985
+ {
1986
+ assert(dctx != NULL);
1987
+ dctx->expected = ZSTD_startingInputLength(dctx->format); /* dctx->format must be properly set */
1988
+ dctx->stage = ZSTDds_getFrameHeaderSize;
1989
+ dctx->decodedSize = 0;
1990
+ dctx->previousDstEnd = NULL;
1991
+ dctx->base = NULL;
1992
+ dctx->vBase = NULL;
1993
+ dctx->dictEnd = NULL;
1994
+ dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
1995
+ dctx->litEntropy = dctx->fseEntropy = 0;
1996
+ dctx->dictID = 0;
1997
+ ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
1998
+ memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
1999
+ dctx->LLTptr = dctx->entropy.LLTable;
2000
+ dctx->MLTptr = dctx->entropy.MLTable;
2001
+ dctx->OFTptr = dctx->entropy.OFTable;
2002
+ dctx->HUFptr = dctx->entropy.hufTable;
2003
+ return 0;
2004
+ }
2005
+
1912
2006
  size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1913
2007
  {
1914
2008
  CHECK_F( ZSTD_decompressBegin(dctx) );
@@ -1975,7 +2069,7 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
1975
2069
  { U32 const magic = MEM_readLE32(ddict->dictContent);
1976
2070
  if (magic != ZSTD_MAGIC_DICTIONARY) return 0; /* pure content mode */
1977
2071
  }
1978
- ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
2072
+ ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_frameIdSize);
1979
2073
 
1980
2074
  /* load entropy tables */
1981
2075
  CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
@@ -1984,9 +2078,9 @@ static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
1984
2078
  }
1985
2079
 
1986
2080
 
1987
- static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, unsigned byReference)
2081
+ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
1988
2082
  {
1989
- if ((byReference) || (!dict) || (!dictSize)) {
2083
+ if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
1990
2084
  ddict->dictBuffer = NULL;
1991
2085
  ddict->dictContent = dict;
1992
2086
  } else {
@@ -2005,7 +2099,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_
2005
2099
  return 0;
2006
2100
  }
2007
2101
 
2008
- ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
2102
+ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_customMem customMem)
2009
2103
  {
2010
2104
  if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
2011
2105
 
@@ -2013,7 +2107,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
2013
2107
  if (!ddict) return NULL;
2014
2108
  ddict->cMem = customMem;
2015
2109
 
2016
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, byReference) )) {
2110
+ if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, dictLoadMethod) )) {
2017
2111
  ZSTD_freeDDict(ddict);
2018
2112
  return NULL;
2019
2113
  }
@@ -2029,7 +2123,7 @@ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigne
2029
2123
  ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
2030
2124
  {
2031
2125
  ZSTD_customMem const allocator = { NULL, NULL, NULL };
2032
- return ZSTD_createDDict_advanced(dict, dictSize, 0, allocator);
2126
+ return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, allocator);
2033
2127
  }
2034
2128
 
2035
2129
  /*! ZSTD_createDDict_byReference() :
@@ -2039,25 +2133,26 @@ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
2039
2133
  ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
2040
2134
  {
2041
2135
  ZSTD_customMem const allocator = { NULL, NULL, NULL };
2042
- return ZSTD_createDDict_advanced(dictBuffer, dictSize, 1, allocator);
2136
+ return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, allocator);
2043
2137
  }
2044
2138
 
2045
2139
 
2046
2140
  ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
2047
2141
  const void* dict, size_t dictSize,
2048
- unsigned byReference)
2142
+ ZSTD_dictLoadMethod_e dictLoadMethod)
2049
2143
  {
2050
- size_t const neededSpace = sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
2144
+ size_t const neededSpace =
2145
+ sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
2051
2146
  ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
2052
2147
  assert(workspace != NULL);
2053
2148
  assert(dict != NULL);
2054
2149
  if ((size_t)workspace & 7) return NULL; /* 8-aligned */
2055
2150
  if (workspaceSize < neededSpace) return NULL;
2056
- if (!byReference) {
2151
+ if (dictLoadMethod == ZSTD_dlm_byCopy) {
2057
2152
  memcpy(ddict+1, dict, dictSize); /* local copy */
2058
2153
  dict = ddict+1;
2059
2154
  }
2060
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, 1 /* byRef */) ))
2155
+ if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, ZSTD_dlm_byRef) ))
2061
2156
  return NULL;
2062
2157
  return ddict;
2063
2158
  }
@@ -2075,10 +2170,10 @@ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
2075
2170
 
2076
2171
  /*! ZSTD_estimateDDictSize() :
2077
2172
  * Estimate amount of memory that will be needed to create a dictionary for decompression.
2078
- * Note : dictionary created "byReference" are smaller */
2079
- size_t ZSTD_estimateDDictSize(size_t dictSize, unsigned byReference)
2173
+ * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
2174
+ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
2080
2175
  {
2081
- return sizeof(ZSTD_DDict) + (byReference ? 0 : dictSize);
2176
+ return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
2082
2177
  }
2083
2178
 
2084
2179
  size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
@@ -2095,7 +2190,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
2095
2190
  {
2096
2191
  if (dictSize < 8) return 0;
2097
2192
  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
2098
- return MEM_readLE32((const char*)dict + 4);
2193
+ return MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
2099
2194
  }
2100
2195
 
2101
2196
  /*! ZSTD_getDictID_fromDDict() :
@@ -2123,7 +2218,7 @@ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
2123
2218
  * ZSTD_getFrameHeader(), which will provide a more precise error code. */
2124
2219
  unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
2125
2220
  {
2126
- ZSTD_frameHeader zfp = { 0, 0, ZSTD_frame, 0, 0, 0 };
2221
+ ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };
2127
2222
  size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
2128
2223
  if (ZSTD_isError(hError)) return 0;
2129
2224
  return zfp.dictID;
@@ -2190,13 +2285,15 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
2190
2285
  return ZSTD_frameHeaderSize_prefix;
2191
2286
  }
2192
2287
 
2288
+ /* note : this variant can't fail */
2193
2289
  size_t ZSTD_initDStream(ZSTD_DStream* zds)
2194
2290
  {
2195
2291
  return ZSTD_initDStream_usingDict(zds, NULL, 0);
2196
2292
  }
2197
2293
 
2198
2294
  /* ZSTD_initDStream_usingDDict() :
2199
- * ddict will just be referenced, and must outlive decompression session */
2295
+ * ddict will just be referenced, and must outlive decompression session
2296
+ * this function cannot fail */
2200
2297
  size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
2201
2298
  {
2202
2299
  size_t const initResult = ZSTD_initDStream(zds);
@@ -2216,31 +2313,66 @@ size_t ZSTD_resetDStream(ZSTD_DStream* zds)
2216
2313
  size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
2217
2314
  ZSTD_DStreamParameter_e paramType, unsigned paramValue)
2218
2315
  {
2316
+ ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2317
+ if ((unsigned)zds->streamStage > (unsigned)zdss_loadHeader)
2318
+ return ERROR(stage_wrong);
2219
2319
  switch(paramType)
2220
2320
  {
2221
2321
  default : return ERROR(parameter_unsupported);
2222
- case DStream_p_maxWindowSize : zds->maxWindowSize = paramValue ? paramValue : (U32)(-1); break;
2322
+ case DStream_p_maxWindowSize :
2323
+ DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10);
2324
+ zds->maxWindowSize = paramValue ? paramValue : (U32)(-1);
2325
+ break;
2223
2326
  }
2224
2327
  return 0;
2225
2328
  }
2226
2329
 
2330
+ size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
2331
+ {
2332
+ ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2333
+ if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
2334
+ return ERROR(stage_wrong);
2335
+ dctx->maxWindowSize = maxWindowSize;
2336
+ return 0;
2337
+ }
2338
+
2339
+ size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
2340
+ {
2341
+ DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format);
2342
+ ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2343
+ if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
2344
+ return ERROR(stage_wrong);
2345
+ dctx->format = format;
2346
+ return 0;
2347
+ }
2348
+
2227
2349
 
2228
2350
  size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
2229
2351
  {
2230
2352
  return ZSTD_sizeof_DCtx(zds);
2231
2353
  }
2232
2354
 
2355
+ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
2356
+ {
2357
+ size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
2358
+ unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
2359
+ unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
2360
+ size_t const minRBSize = (size_t) neededSize;
2361
+ if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge);
2362
+ return minRBSize;
2363
+ }
2364
+
2233
2365
  size_t ZSTD_estimateDStreamSize(size_t windowSize)
2234
2366
  {
2235
2367
  size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
2236
2368
  size_t const inBuffSize = blockSize; /* no block can be larger */
2237
- size_t const outBuffSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
2369
+ size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);
2238
2370
  return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
2239
2371
  }
2240
2372
 
2241
- ZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
2373
+ size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
2242
2374
  {
2243
- U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
2375
+ U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */
2244
2376
  ZSTD_frameHeader zfh;
2245
2377
  size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
2246
2378
  if (ZSTD_isError(err)) return err;
@@ -2272,7 +2404,18 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2272
2404
  U32 someMoreWork = 1;
2273
2405
 
2274
2406
  DEBUGLOG(5, "ZSTD_decompressStream");
2407
+ if (input->pos > input->size) { /* forbidden */
2408
+ DEBUGLOG(5, "in: pos: %u vs size: %u",
2409
+ (U32)input->pos, (U32)input->size);
2410
+ return ERROR(srcSize_wrong);
2411
+ }
2412
+ if (output->pos > output->size) { /* forbidden */
2413
+ DEBUGLOG(5, "out: pos: %u vs size: %u",
2414
+ (U32)output->pos, (U32)output->size);
2415
+ return ERROR(dstSize_tooSmall);
2416
+ }
2275
2417
  DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
2418
+
2276
2419
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2277
2420
  if (zds->legacyVersion) {
2278
2421
  /* legacy support is incompatible with static dctx */
@@ -2289,7 +2432,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2289
2432
  /* fall-through */
2290
2433
 
2291
2434
  case zdss_loadHeader :
2292
- { size_t const hSize = ZSTD_getFrameHeader(&zds->fParams, zds->headerBuffer, zds->lhSize);
2435
+ DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
2436
+ { size_t const hSize = ZSTD_getFrameHeader_internal(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
2437
+ DEBUGLOG(5, "header size : %u", (U32)hSize);
2293
2438
  if (ZSTD_isError(hSize)) {
2294
2439
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2295
2440
  U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
@@ -2342,7 +2487,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2342
2487
  CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
2343
2488
 
2344
2489
  if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2345
- zds->expected = MEM_readLE32(zds->headerBuffer + 4);
2490
+ zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_frameIdSize);
2346
2491
  zds->stage = ZSTDds_skipFrame;
2347
2492
  } else {
2348
2493
  CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
@@ -2351,20 +2496,20 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2351
2496
  }
2352
2497
 
2353
2498
  /* control buffer memory usage */
2354
- DEBUGLOG(4, "Control max buffer memory usage");
2499
+ DEBUGLOG(4, "Control max buffer memory usage (max %u KB)",
2500
+ (U32)(zds->maxWindowSize >> 10));
2355
2501
  zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2356
2502
  if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
2357
2503
 
2358
2504
  /* Adapt buffer sizes to frame header instructions */
2359
- { size_t const blockSize = (size_t)(MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_MAX));
2360
- size_t const neededOutSize = (size_t)(zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2);
2361
- zds->blockSize = blockSize;
2362
- if ((zds->inBuffSize < blockSize) || (zds->outBuffSize < neededOutSize)) {
2363
- size_t const bufferSize = blockSize + neededOutSize;
2505
+ { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
2506
+ size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize);
2507
+ if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) {
2508
+ size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
2364
2509
  DEBUGLOG(4, "inBuff : from %u to %u",
2365
- (U32)zds->inBuffSize, (U32)blockSize);
2510
+ (U32)zds->inBuffSize, (U32)neededInBuffSize);
2366
2511
  DEBUGLOG(4, "outBuff : from %u to %u",
2367
- (U32)zds->outBuffSize, (U32)neededOutSize);
2512
+ (U32)zds->outBuffSize, (U32)neededOutBuffSize);
2368
2513
  if (zds->staticSize) { /* static DCtx */
2369
2514
  DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
2370
2515
  assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
@@ -2377,9 +2522,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2377
2522
  zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
2378
2523
  if (zds->inBuff == NULL) return ERROR(memory_allocation);
2379
2524
  }
2380
- zds->inBuffSize = blockSize;
2525
+ zds->inBuffSize = neededInBuffSize;
2381
2526
  zds->outBuff = zds->inBuff + zds->inBuffSize;
2382
- zds->outBuffSize = neededOutSize;
2527
+ zds->outBuffSize = neededOutBuffSize;
2383
2528
  } }
2384
2529
  zds->streamStage = zdss_read;
2385
2530
  /* fall-through */
@@ -2437,8 +2582,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2437
2582
  zds->outStart += flushedSize;
2438
2583
  if (flushedSize == toFlushSize) { /* flush completed */
2439
2584
  zds->streamStage = zdss_read;
2440
- if (zds->outStart + zds->blockSize > zds->outBuffSize)
2585
+ if ( (zds->outBuffSize < zds->fParams.frameContentSize)
2586
+ && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
2587
+ DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
2588
+ (int)(zds->outBuffSize - zds->outStart),
2589
+ (U32)zds->fParams.blockSizeMax);
2441
2590
  zds->outStart = zds->outEnd = 0;
2591
+ }
2442
2592
  break;
2443
2593
  } }
2444
2594
  /* cannot complete flush */
@@ -2476,3 +2626,30 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2476
2626
  return nextSrcSizeHint;
2477
2627
  }
2478
2628
  }
2629
+
2630
+
2631
+ size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
2632
+ {
2633
+ return ZSTD_decompressStream(dctx, output, input);
2634
+ }
2635
+
2636
+ size_t ZSTD_decompress_generic_simpleArgs (
2637
+ ZSTD_DCtx* dctx,
2638
+ void* dst, size_t dstCapacity, size_t* dstPos,
2639
+ const void* src, size_t srcSize, size_t* srcPos)
2640
+ {
2641
+ ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
2642
+ ZSTD_inBuffer input = { src, srcSize, *srcPos };
2643
+ /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
2644
+ size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input);
2645
+ *dstPos = output.pos;
2646
+ *srcPos = input.pos;
2647
+ return cErr;
2648
+ }
2649
+
2650
+ void ZSTD_DCtx_reset(ZSTD_DCtx* dctx)
2651
+ {
2652
+ (void)ZSTD_initDStream(dctx);
2653
+ dctx->format = ZSTD_f_zstd1;
2654
+ dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
2655
+ }