zstd-ruby 1.5.5.0 → 1.5.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +2 -2
  4. data/ext/zstdruby/extconf.rb +2 -0
  5. data/ext/zstdruby/libzstd/common/allocations.h +1 -1
  6. data/ext/zstdruby/libzstd/common/bitstream.h +49 -29
  7. data/ext/zstdruby/libzstd/common/compiler.h +114 -22
  8. data/ext/zstdruby/libzstd/common/cpu.h +36 -0
  9. data/ext/zstdruby/libzstd/common/debug.c +6 -0
  10. data/ext/zstdruby/libzstd/common/debug.h +20 -11
  11. data/ext/zstdruby/libzstd/common/error_private.h +45 -36
  12. data/ext/zstdruby/libzstd/common/fse.h +3 -2
  13. data/ext/zstdruby/libzstd/common/fse_decompress.c +19 -17
  14. data/ext/zstdruby/libzstd/common/huf.h +14 -1
  15. data/ext/zstdruby/libzstd/common/mem.h +0 -9
  16. data/ext/zstdruby/libzstd/common/pool.c +1 -1
  17. data/ext/zstdruby/libzstd/common/pool.h +1 -1
  18. data/ext/zstdruby/libzstd/common/portability_macros.h +2 -0
  19. data/ext/zstdruby/libzstd/common/threading.c +8 -2
  20. data/ext/zstdruby/libzstd/common/xxhash.c +5 -11
  21. data/ext/zstdruby/libzstd/common/xxhash.h +2341 -1007
  22. data/ext/zstdruby/libzstd/common/zstd_internal.h +5 -5
  23. data/ext/zstdruby/libzstd/compress/fse_compress.c +8 -7
  24. data/ext/zstdruby/libzstd/compress/huf_compress.c +54 -25
  25. data/ext/zstdruby/libzstd/compress/zstd_compress.c +282 -161
  26. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +29 -27
  27. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +224 -113
  28. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +19 -13
  29. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +17 -5
  30. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +11 -0
  31. data/ext/zstdruby/libzstd/compress/zstd_fast.c +14 -6
  32. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +129 -87
  33. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +103 -28
  34. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +8 -2
  35. data/ext/zstdruby/libzstd/compress/zstd_opt.c +216 -112
  36. data/ext/zstdruby/libzstd/compress/zstd_opt.h +31 -7
  37. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +94 -79
  38. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +188 -126
  39. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +38 -19
  40. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +84 -32
  41. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +231 -208
  42. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
  43. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +2 -0
  44. data/ext/zstdruby/libzstd/dictBuilder/cover.c +16 -12
  45. data/ext/zstdruby/libzstd/dictBuilder/cover.h +2 -8
  46. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
  47. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +12 -6
  48. data/ext/zstdruby/libzstd/zstd.h +129 -60
  49. data/ext/zstdruby/streaming_compress.c +23 -3
  50. data/ext/zstdruby/streaming_decompress.c +23 -3
  51. data/lib/zstd-ruby/version.rb +1 -1
  52. metadata +2 -2
@@ -51,6 +51,13 @@ static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); }
51
51
  * Block decoding
52
52
  ***************************************************************/
53
53
 
54
+ static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx)
55
+ {
56
+ size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX;
57
+ assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX);
58
+ return blockSizeMax;
59
+ }
60
+
54
61
  /*! ZSTD_getcBlockSize() :
55
62
  * Provides the size of compressed block from block header `src` */
56
63
  size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
@@ -73,41 +80,49 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
73
80
  static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,
74
81
  const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
75
82
  {
76
- if (streaming == not_streaming && dstCapacity > ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH)
77
- {
78
- /* room for litbuffer to fit without read faulting */
79
- dctx->litBuffer = (BYTE*)dst + ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH;
83
+ size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);
84
+ assert(litSize <= blockSizeMax);
85
+ assert(dctx->isFrameDecompression || streaming == not_streaming);
86
+ assert(expectedWriteSize <= blockSizeMax);
87
+ if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) {
88
+ /* If we aren't streaming, we can just put the literals after the output
89
+ * of the current block. We don't need to worry about overwriting the
90
+ * extDict of our window, because it doesn't exist.
91
+ * So if we have space after the end of the block, just put it there.
92
+ */
93
+ dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH;
80
94
  dctx->litBufferEnd = dctx->litBuffer + litSize;
81
95
  dctx->litBufferLocation = ZSTD_in_dst;
82
- }
83
- else if (litSize > ZSTD_LITBUFFEREXTRASIZE)
84
- {
85
- /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
96
+ } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) {
97
+ /* Literals fit entirely within the extra buffer, put them there to avoid
98
+ * having to split the literals.
99
+ */
100
+ dctx->litBuffer = dctx->litExtraBuffer;
101
+ dctx->litBufferEnd = dctx->litBuffer + litSize;
102
+ dctx->litBufferLocation = ZSTD_not_in_dst;
103
+ } else {
104
+ assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE);
105
+ /* Literals must be split between the output block and the extra lit
106
+ * buffer. We fill the extra lit buffer with the tail of the literals,
107
+ * and put the rest of the literals at the end of the block, with
108
+ * WILDCOPY_OVERLENGTH of buffer room to allow for overreads.
109
+ * This MUST not write more than our maxBlockSize beyond dst, because in
110
+ * streaming mode, that could overwrite part of our extDict window.
111
+ */
86
112
  if (splitImmediately) {
87
113
  /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
88
114
  dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
89
115
  dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;
90
- }
91
- else {
116
+ } else {
92
117
  /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */
93
118
  dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;
94
119
  dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;
95
120
  }
96
121
  dctx->litBufferLocation = ZSTD_split;
97
- }
98
- else
99
- {
100
- /* fits entirely within litExtraBuffer, so no split is necessary */
101
- dctx->litBuffer = dctx->litExtraBuffer;
102
- dctx->litBufferEnd = dctx->litBuffer + litSize;
103
- dctx->litBufferLocation = ZSTD_not_in_dst;
122
+ assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize);
104
123
  }
105
124
  }
106
125
 
107
- /* Hidden declaration for fullbench */
108
- size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
109
- const void* src, size_t srcSize,
110
- void* dst, size_t dstCapacity, const streaming_operation streaming);
111
126
  /*! ZSTD_decodeLiteralsBlock() :
112
127
  * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored
113
128
  * in the dstBuffer. If there is room to do so, it will be stored in full in the excess dst space after where the current
@@ -116,7 +131,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
116
131
  *
117
132
  * @return : nb of bytes read from src (< srcSize )
118
133
  * note : symbol not declared but exposed for fullbench */
119
- size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
134
+ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
120
135
  const void* src, size_t srcSize, /* note : srcSize < BLOCKSIZE */
121
136
  void* dst, size_t dstCapacity, const streaming_operation streaming)
122
137
  {
@@ -125,6 +140,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
125
140
 
126
141
  { const BYTE* const istart = (const BYTE*) src;
127
142
  symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
143
+ size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);
128
144
 
129
145
  switch(litEncType)
130
146
  {
@@ -140,7 +156,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
140
156
  U32 const lhlCode = (istart[0] >> 2) & 3;
141
157
  U32 const lhc = MEM_readLE32(istart);
142
158
  size_t hufSuccess;
143
- size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
159
+ size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
144
160
  int const flags = 0
145
161
  | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)
146
162
  | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);
@@ -167,7 +183,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
167
183
  break;
168
184
  }
169
185
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
170
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
186
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
171
187
  if (!singleStream)
172
188
  RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
173
189
  "Not enough literals (%zu) for the 4-streams mode (min %u)",
@@ -214,10 +230,12 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
214
230
  }
215
231
  if (dctx->litBufferLocation == ZSTD_split)
216
232
  {
233
+ assert(litSize > ZSTD_LITBUFFEREXTRASIZE);
217
234
  ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
218
235
  ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
219
236
  dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
220
237
  dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
238
+ assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax);
221
239
  }
222
240
 
223
241
  RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
@@ -232,7 +250,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
232
250
  case set_basic:
233
251
  { size_t litSize, lhSize;
234
252
  U32 const lhlCode = ((istart[0]) >> 2) & 3;
235
- size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
253
+ size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
236
254
  switch(lhlCode)
237
255
  {
238
256
  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -251,6 +269,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
251
269
  }
252
270
 
253
271
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
272
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
254
273
  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
255
274
  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
256
275
  if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
@@ -279,7 +298,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
279
298
  case set_rle:
280
299
  { U32 const lhlCode = ((istart[0]) >> 2) & 3;
281
300
  size_t litSize, lhSize;
282
- size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
301
+ size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
283
302
  switch(lhlCode)
284
303
  {
285
304
  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -298,7 +317,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
298
317
  break;
299
318
  }
300
319
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
301
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
320
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
302
321
  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
303
322
  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
304
323
  if (dctx->litBufferLocation == ZSTD_split)
@@ -320,6 +339,18 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
320
339
  }
321
340
  }
322
341
 
342
+ /* Hidden declaration for fullbench */
343
+ size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
344
+ const void* src, size_t srcSize,
345
+ void* dst, size_t dstCapacity);
346
+ size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
347
+ const void* src, size_t srcSize,
348
+ void* dst, size_t dstCapacity)
349
+ {
350
+ dctx->isFrameDecompression = 0;
351
+ return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming);
352
+ }
353
+
323
354
  /* Default FSE distribution tables.
324
355
  * These are pre-calculated FSE decoding tables using default distributions as defined in specification :
325
356
  * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
@@ -675,11 +706,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
675
706
 
676
707
  /* SeqHead */
677
708
  nbSeq = *ip++;
678
- if (!nbSeq) {
679
- *nbSeqPtr=0;
680
- RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
681
- return 1;
682
- }
683
709
  if (nbSeq > 0x7F) {
684
710
  if (nbSeq == 0xFF) {
685
711
  RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
@@ -692,8 +718,16 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
692
718
  }
693
719
  *nbSeqPtr = nbSeq;
694
720
 
721
+ if (nbSeq == 0) {
722
+ /* No sequence : section ends immediately */
723
+ RETURN_ERROR_IF(ip != iend, corruption_detected,
724
+ "extraneous data present in the Sequences section");
725
+ return (size_t)(ip - istart);
726
+ }
727
+
695
728
  /* FSE table descriptors */
696
729
  RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
730
+ RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */
697
731
  { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
698
732
  symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
699
733
  symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
@@ -840,7 +874,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
840
874
  /* ZSTD_safecopyDstBeforeSrc():
841
875
  * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
842
876
  * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
843
- static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length) {
877
+ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) {
844
878
  ptrdiff_t const diff = op - ip;
845
879
  BYTE* const oend = op + length;
846
880
 
@@ -869,6 +903,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length
869
903
  * to be optimized for many small sequences, since those fall into ZSTD_execSequence().
870
904
  */
871
905
  FORCE_NOINLINE
906
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
872
907
  size_t ZSTD_execSequenceEnd(BYTE* op,
873
908
  BYTE* const oend, seq_t sequence,
874
909
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -916,6 +951,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
916
951
  * This version is intended to be used during instances where the litBuffer is still split. It is kept separate to avoid performance impact for the good case.
917
952
  */
918
953
  FORCE_NOINLINE
954
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
919
955
  size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
920
956
  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
921
957
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -961,6 +997,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
961
997
  }
962
998
 
963
999
  HINT_INLINE
1000
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
964
1001
  size_t ZSTD_execSequence(BYTE* op,
965
1002
  BYTE* const oend, seq_t sequence,
966
1003
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -1059,6 +1096,7 @@ size_t ZSTD_execSequence(BYTE* op,
1059
1096
  }
1060
1097
 
1061
1098
  HINT_INLINE
1099
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
1062
1100
  size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
1063
1101
  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
1064
1102
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -1181,14 +1219,20 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16
1181
1219
 
1182
1220
  typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
1183
1221
 
1222
+ /**
1223
+ * ZSTD_decodeSequence():
1224
+ * @p longOffsets : tells the decoder to reload more bit while decoding large offsets
1225
+ * only used in 32-bit mode
1226
+ * @return : Sequence (litL + matchL + offset)
1227
+ */
1184
1228
  FORCE_INLINE_TEMPLATE seq_t
1185
- ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1229
+ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
1186
1230
  {
1187
1231
  seq_t seq;
1188
1232
  /*
1189
- * ZSTD_seqSymbol is a structure with a total of 64 bits wide. So it can be
1190
- * loaded in one operation and extracted its fields by simply shifting or
1191
- * bit-extracting on aarch64.
1233
+ * ZSTD_seqSymbol is a 64 bits wide structure.
1234
+ * It can be loaded in one operation
1235
+ * and its fields extracted by simply shifting or bit-extracting on aarch64.
1192
1236
  * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh
1193
1237
  * operations that cause performance drop. This can be avoided by using this
1194
1238
  * ZSTD_memcpy hack.
@@ -1261,7 +1305,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1261
1305
  } else {
1262
1306
  offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
1263
1307
  { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1264
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
1308
+ temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */
1265
1309
  if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
1266
1310
  seqState->prevOffset[1] = seqState->prevOffset[0];
1267
1311
  seqState->prevOffset[0] = offset = temp;
@@ -1288,17 +1332,22 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1288
1332
  DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
1289
1333
  (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1290
1334
 
1291
- ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
1292
- ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
1293
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1294
- ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
1335
+ if (!isLastSeq) {
1336
+ /* don't update FSE state for last Sequence */
1337
+ ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
1338
+ ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
1339
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1340
+ ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits); /* <= 8 bits */
1341
+ BIT_reloadDStream(&seqState->DStream);
1342
+ }
1295
1343
  }
1296
1344
 
1297
1345
  return seq;
1298
1346
  }
1299
1347
 
1300
- #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1301
- MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
1348
+ #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1349
+ #if DEBUGLEVEL >= 1
1350
+ static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
1302
1351
  {
1303
1352
  size_t const windowSize = dctx->fParams.windowSize;
1304
1353
  /* No dictionary used. */
@@ -1312,30 +1361,33 @@ MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefix
1312
1361
  /* Dictionary is active. */
1313
1362
  return 1;
1314
1363
  }
1364
+ #endif
1315
1365
 
1316
- MEM_STATIC void ZSTD_assertValidSequence(
1366
+ static void ZSTD_assertValidSequence(
1317
1367
  ZSTD_DCtx const* dctx,
1318
1368
  BYTE const* op, BYTE const* oend,
1319
1369
  seq_t const seq,
1320
1370
  BYTE const* prefixStart, BYTE const* virtualStart)
1321
1371
  {
1322
1372
  #if DEBUGLEVEL >= 1
1323
- size_t const windowSize = dctx->fParams.windowSize;
1324
- size_t const sequenceSize = seq.litLength + seq.matchLength;
1325
- BYTE const* const oLitEnd = op + seq.litLength;
1326
- DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
1327
- (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1328
- assert(op <= oend);
1329
- assert((size_t)(oend - op) >= sequenceSize);
1330
- assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
1331
- if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
1332
- size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
1333
- /* Offset must be within the dictionary. */
1334
- assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
1335
- assert(seq.offset <= windowSize + dictSize);
1336
- } else {
1337
- /* Offset must be within our window. */
1338
- assert(seq.offset <= windowSize);
1373
+ if (dctx->isFrameDecompression) {
1374
+ size_t const windowSize = dctx->fParams.windowSize;
1375
+ size_t const sequenceSize = seq.litLength + seq.matchLength;
1376
+ BYTE const* const oLitEnd = op + seq.litLength;
1377
+ DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
1378
+ (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1379
+ assert(op <= oend);
1380
+ assert((size_t)(oend - op) >= sequenceSize);
1381
+ assert(sequenceSize <= ZSTD_blockSizeMax(dctx));
1382
+ if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
1383
+ size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
1384
+ /* Offset must be within the dictionary. */
1385
+ assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
1386
+ assert(seq.offset <= windowSize + dictSize);
1387
+ } else {
1388
+ /* Offset must be within our window. */
1389
+ assert(seq.offset <= windowSize);
1390
+ }
1339
1391
  }
1340
1392
  #else
1341
1393
  (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
@@ -1351,23 +1403,21 @@ DONT_VECTORIZE
1351
1403
  ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1352
1404
  void* dst, size_t maxDstSize,
1353
1405
  const void* seqStart, size_t seqSize, int nbSeq,
1354
- const ZSTD_longOffset_e isLongOffset,
1355
- const int frame)
1406
+ const ZSTD_longOffset_e isLongOffset)
1356
1407
  {
1357
1408
  const BYTE* ip = (const BYTE*)seqStart;
1358
1409
  const BYTE* const iend = ip + seqSize;
1359
1410
  BYTE* const ostart = (BYTE*)dst;
1360
- BYTE* const oend = ostart + maxDstSize;
1411
+ BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
1361
1412
  BYTE* op = ostart;
1362
1413
  const BYTE* litPtr = dctx->litPtr;
1363
1414
  const BYTE* litBufferEnd = dctx->litBufferEnd;
1364
1415
  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1365
1416
  const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
1366
1417
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1367
- DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
1368
- (void)frame;
1418
+ DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq);
1369
1419
 
1370
- /* Regen sequences */
1420
+ /* Literals are split between internal buffer & output buffer */
1371
1421
  if (nbSeq) {
1372
1422
  seqState_t seqState;
1373
1423
  dctx->fseEntropy = 1;
@@ -1386,8 +1436,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1386
1436
  BIT_DStream_completed < BIT_DStream_overflow);
1387
1437
 
1388
1438
  /* decompress without overrunning litPtr begins */
1389
- {
1390
- seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1439
+ { seq_t sequence = {0,0,0}; /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */
1391
1440
  /* Align the decompression loop to 32 + 16 bytes.
1392
1441
  *
1393
1442
  * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
@@ -1449,27 +1498,26 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1449
1498
  #endif
1450
1499
 
1451
1500
  /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
1452
- for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) {
1453
- size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1501
+ for ( ; nbSeq; nbSeq--) {
1502
+ sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
1503
+ if (litPtr + sequence.litLength > dctx->litBufferEnd) break;
1504
+ { size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1454
1505
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1455
- assert(!ZSTD_isError(oneSeqSize));
1456
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1506
+ assert(!ZSTD_isError(oneSeqSize));
1507
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1457
1508
  #endif
1458
- if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1459
- return oneSeqSize;
1460
- DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1461
- op += oneSeqSize;
1462
- if (UNLIKELY(!--nbSeq))
1463
- break;
1464
- BIT_reloadDStream(&(seqState.DStream));
1465
- sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1466
- }
1509
+ if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1510
+ return oneSeqSize;
1511
+ DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1512
+ op += oneSeqSize;
1513
+ } }
1514
+ DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)");
1467
1515
 
1468
1516
  /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
1469
1517
  if (nbSeq > 0) {
1470
1518
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1471
- if (leftoverLit)
1472
- {
1519
+ DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
1520
+ if (leftoverLit) {
1473
1521
  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1474
1522
  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1475
1523
  sequence.litLength -= leftoverLit;
@@ -1478,24 +1526,22 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1478
1526
  litPtr = dctx->litExtraBuffer;
1479
1527
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1480
1528
  dctx->litBufferLocation = ZSTD_not_in_dst;
1481
- {
1482
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1529
+ { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1483
1530
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1484
1531
  assert(!ZSTD_isError(oneSeqSize));
1485
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1532
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1486
1533
  #endif
1487
1534
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1488
1535
  return oneSeqSize;
1489
1536
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1490
1537
  op += oneSeqSize;
1491
- if (--nbSeq)
1492
- BIT_reloadDStream(&(seqState.DStream));
1493
1538
  }
1539
+ nbSeq--;
1494
1540
  }
1495
1541
  }
1496
1542
 
1497
- if (nbSeq > 0) /* there is remaining lit from extra buffer */
1498
- {
1543
+ if (nbSeq > 0) {
1544
+ /* there is remaining lit from extra buffer */
1499
1545
 
1500
1546
  #if defined(__GNUC__) && defined(__x86_64__)
1501
1547
  __asm__(".p2align 6");
@@ -1514,35 +1560,34 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1514
1560
  # endif
1515
1561
  #endif
1516
1562
 
1517
- for (; ; ) {
1518
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1563
+ for ( ; nbSeq ; nbSeq--) {
1564
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
1519
1565
  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1520
1566
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1521
1567
  assert(!ZSTD_isError(oneSeqSize));
1522
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1568
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1523
1569
  #endif
1524
1570
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1525
1571
  return oneSeqSize;
1526
1572
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1527
1573
  op += oneSeqSize;
1528
- if (UNLIKELY(!--nbSeq))
1529
- break;
1530
- BIT_reloadDStream(&(seqState.DStream));
1531
1574
  }
1532
1575
  }
1533
1576
 
1534
1577
  /* check if reached exact end */
1535
1578
  DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
1536
1579
  RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1537
- RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
1580
+ DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed);
1581
+ RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
1538
1582
  /* save reps for next block */
1539
1583
  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1540
1584
  }
1541
1585
 
1542
1586
  /* last literal segment */
1543
- if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
1544
- {
1545
- size_t const lastLLSize = litBufferEnd - litPtr;
1587
+ if (dctx->litBufferLocation == ZSTD_split) {
1588
+ /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
1589
+ size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
1590
+ DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize);
1546
1591
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1547
1592
  if (op != NULL) {
1548
1593
  ZSTD_memmove(op, litPtr, lastLLSize);
@@ -1552,15 +1597,17 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1552
1597
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1553
1598
  dctx->litBufferLocation = ZSTD_not_in_dst;
1554
1599
  }
1555
- { size_t const lastLLSize = litBufferEnd - litPtr;
1600
+ /* copy last literals from internal buffer */
1601
+ { size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
1602
+ DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize);
1556
1603
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1557
1604
  if (op != NULL) {
1558
1605
  ZSTD_memcpy(op, litPtr, lastLLSize);
1559
1606
  op += lastLLSize;
1560
- }
1561
- }
1607
+ } }
1562
1608
 
1563
- return op-ostart;
1609
+ DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
1610
+ return (size_t)(op - ostart);
1564
1611
  }
1565
1612
 
1566
1613
  FORCE_INLINE_TEMPLATE size_t
@@ -1568,13 +1615,12 @@ DONT_VECTORIZE
1568
1615
  ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1569
1616
  void* dst, size_t maxDstSize,
1570
1617
  const void* seqStart, size_t seqSize, int nbSeq,
1571
- const ZSTD_longOffset_e isLongOffset,
1572
- const int frame)
1618
+ const ZSTD_longOffset_e isLongOffset)
1573
1619
  {
1574
1620
  const BYTE* ip = (const BYTE*)seqStart;
1575
1621
  const BYTE* const iend = ip + seqSize;
1576
1622
  BYTE* const ostart = (BYTE*)dst;
1577
- BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart + maxDstSize : dctx->litBuffer;
1623
+ BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer;
1578
1624
  BYTE* op = ostart;
1579
1625
  const BYTE* litPtr = dctx->litPtr;
1580
1626
  const BYTE* const litEnd = litPtr + dctx->litSize;
@@ -1582,7 +1628,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1582
1628
  const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
1583
1629
  const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
1584
1630
  DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq);
1585
- (void)frame;
1586
1631
 
1587
1632
  /* Regen sequences */
1588
1633
  if (nbSeq) {
@@ -1597,11 +1642,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1597
1642
  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1598
1643
  assert(dst != NULL);
1599
1644
 
1600
- ZSTD_STATIC_ASSERT(
1601
- BIT_DStream_unfinished < BIT_DStream_completed &&
1602
- BIT_DStream_endOfBuffer < BIT_DStream_completed &&
1603
- BIT_DStream_completed < BIT_DStream_overflow);
1604
-
1605
1645
  #if defined(__GNUC__) && defined(__x86_64__)
1606
1646
  __asm__(".p2align 6");
1607
1647
  __asm__("nop");
@@ -1616,73 +1656,70 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1616
1656
  # endif
1617
1657
  #endif
1618
1658
 
1619
- for ( ; ; ) {
1620
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1659
+ for ( ; nbSeq ; nbSeq--) {
1660
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
1621
1661
  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
1622
1662
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1623
1663
  assert(!ZSTD_isError(oneSeqSize));
1624
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1664
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1625
1665
  #endif
1626
1666
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1627
1667
  return oneSeqSize;
1628
1668
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1629
1669
  op += oneSeqSize;
1630
- if (UNLIKELY(!--nbSeq))
1631
- break;
1632
- BIT_reloadDStream(&(seqState.DStream));
1633
1670
  }
1634
1671
 
1635
1672
  /* check if reached exact end */
1636
- DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
1637
- RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1638
- RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
1673
+ assert(nbSeq == 0);
1674
+ RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
1639
1675
  /* save reps for next block */
1640
1676
  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1641
1677
  }
1642
1678
 
1643
1679
  /* last literal segment */
1644
- { size_t const lastLLSize = litEnd - litPtr;
1680
+ { size_t const lastLLSize = (size_t)(litEnd - litPtr);
1681
+ DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize);
1645
1682
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1646
1683
  if (op != NULL) {
1647
1684
  ZSTD_memcpy(op, litPtr, lastLLSize);
1648
1685
  op += lastLLSize;
1649
- }
1650
- }
1686
+ } }
1651
1687
 
1652
- return op-ostart;
1688
+ DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
1689
+ return (size_t)(op - ostart);
1653
1690
  }
1654
1691
 
1655
1692
  static size_t
1656
1693
  ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
1657
1694
  void* dst, size_t maxDstSize,
1658
1695
  const void* seqStart, size_t seqSize, int nbSeq,
1659
- const ZSTD_longOffset_e isLongOffset,
1660
- const int frame)
1696
+ const ZSTD_longOffset_e isLongOffset)
1661
1697
  {
1662
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1698
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1663
1699
  }
1664
1700
 
1665
1701
  static size_t
1666
1702
  ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
1667
1703
  void* dst, size_t maxDstSize,
1668
1704
  const void* seqStart, size_t seqSize, int nbSeq,
1669
- const ZSTD_longOffset_e isLongOffset,
1670
- const int frame)
1705
+ const ZSTD_longOffset_e isLongOffset)
1671
1706
  {
1672
- return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1707
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1673
1708
  }
1674
1709
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1675
1710
 
1676
1711
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
1677
1712
 
1678
- FORCE_INLINE_TEMPLATE size_t
1679
- ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
1713
+ FORCE_INLINE_TEMPLATE
1714
+
1715
+ size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
1680
1716
  const BYTE* const prefixStart, const BYTE* const dictEnd)
1681
1717
  {
1682
1718
  prefetchPos += sequence.litLength;
1683
1719
  { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
1684
- const BYTE* const match = matchBase + prefetchPos - sequence.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
1685
- * No consequence though : memory address is only used for prefetching, not for dereferencing */
1720
+ /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
1721
+ * No consequence though : memory address is only used for prefetching, not for dereferencing */
1722
+ const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset);
1686
1723
  PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
1687
1724
  }
1688
1725
  return prefetchPos + sequence.matchLength;
@@ -1697,20 +1734,18 @@ ZSTD_decompressSequencesLong_body(
1697
1734
  ZSTD_DCtx* dctx,
1698
1735
  void* dst, size_t maxDstSize,
1699
1736
  const void* seqStart, size_t seqSize, int nbSeq,
1700
- const ZSTD_longOffset_e isLongOffset,
1701
- const int frame)
1737
+ const ZSTD_longOffset_e isLongOffset)
1702
1738
  {
1703
1739
  const BYTE* ip = (const BYTE*)seqStart;
1704
1740
  const BYTE* const iend = ip + seqSize;
1705
1741
  BYTE* const ostart = (BYTE*)dst;
1706
- BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart + maxDstSize;
1742
+ BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
1707
1743
  BYTE* op = ostart;
1708
1744
  const BYTE* litPtr = dctx->litPtr;
1709
1745
  const BYTE* litBufferEnd = dctx->litBufferEnd;
1710
1746
  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1711
1747
  const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
1712
1748
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1713
- (void)frame;
1714
1749
 
1715
1750
  /* Regen sequences */
1716
1751
  if (nbSeq) {
@@ -1735,20 +1770,17 @@ ZSTD_decompressSequencesLong_body(
1735
1770
  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1736
1771
 
1737
1772
  /* prepare in advance */
1738
- for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
1739
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1773
+ for (seqNb=0; seqNb<seqAdvance; seqNb++) {
1774
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
1740
1775
  prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1741
1776
  sequences[seqNb] = sequence;
1742
1777
  }
1743
- RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
1744
1778
 
1745
1779
  /* decompress without stomping litBuffer */
1746
- for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb < nbSeq); seqNb++) {
1747
- seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1748
- size_t oneSeqSize;
1780
+ for (; seqNb < nbSeq; seqNb++) {
1781
+ seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
1749
1782
 
1750
- if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
1751
- {
1783
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
1752
1784
  /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
1753
1785
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1754
1786
  if (leftoverLit)
@@ -1761,26 +1793,26 @@ ZSTD_decompressSequencesLong_body(
1761
1793
  litPtr = dctx->litExtraBuffer;
1762
1794
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1763
1795
  dctx->litBufferLocation = ZSTD_not_in_dst;
1764
- oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1796
+ { size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1765
1797
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1766
- assert(!ZSTD_isError(oneSeqSize));
1767
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1798
+ assert(!ZSTD_isError(oneSeqSize));
1799
+ ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1768
1800
  #endif
1769
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1801
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1770
1802
 
1771
- prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1772
- sequences[seqNb & STORED_SEQS_MASK] = sequence;
1773
- op += oneSeqSize;
1774
- }
1803
+ prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1804
+ sequences[seqNb & STORED_SEQS_MASK] = sequence;
1805
+ op += oneSeqSize;
1806
+ } }
1775
1807
  else
1776
1808
  {
1777
1809
  /* lit buffer is either wholly contained in first or second split, or not split at all*/
1778
- oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1810
+ size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1779
1811
  ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
1780
1812
  ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1781
1813
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1782
1814
  assert(!ZSTD_isError(oneSeqSize));
1783
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1815
+ ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
1784
1816
  #endif
1785
1817
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1786
1818
 
@@ -1789,17 +1821,15 @@ ZSTD_decompressSequencesLong_body(
1789
1821
  op += oneSeqSize;
1790
1822
  }
1791
1823
  }
1792
- RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
1824
+ RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
1793
1825
 
1794
1826
  /* finish queue */
1795
1827
  seqNb -= seqAdvance;
1796
1828
  for ( ; seqNb<nbSeq ; seqNb++) {
1797
1829
  seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
1798
- if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
1799
- {
1830
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
1800
1831
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1801
- if (leftoverLit)
1802
- {
1832
+ if (leftoverLit) {
1803
1833
  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1804
1834
  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1805
1835
  sequence->litLength -= leftoverLit;
@@ -1808,11 +1838,10 @@ ZSTD_decompressSequencesLong_body(
1808
1838
  litPtr = dctx->litExtraBuffer;
1809
1839
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1810
1840
  dctx->litBufferLocation = ZSTD_not_in_dst;
1811
- {
1812
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1841
+ { size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1813
1842
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1814
1843
  assert(!ZSTD_isError(oneSeqSize));
1815
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1844
+ ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1816
1845
  #endif
1817
1846
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1818
1847
  op += oneSeqSize;
@@ -1825,7 +1854,7 @@ ZSTD_decompressSequencesLong_body(
1825
1854
  ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1826
1855
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1827
1856
  assert(!ZSTD_isError(oneSeqSize));
1828
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1857
+ ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
1829
1858
  #endif
1830
1859
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1831
1860
  op += oneSeqSize;
@@ -1837,8 +1866,7 @@ ZSTD_decompressSequencesLong_body(
1837
1866
  }
1838
1867
 
1839
1868
  /* last literal segment */
1840
- if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */
1841
- {
1869
+ if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
1842
1870
  size_t const lastLLSize = litBufferEnd - litPtr;
1843
1871
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1844
1872
  if (op != NULL) {
@@ -1856,17 +1884,16 @@ ZSTD_decompressSequencesLong_body(
1856
1884
  }
1857
1885
  }
1858
1886
 
1859
- return op-ostart;
1887
+ return (size_t)(op - ostart);
1860
1888
  }
1861
1889
 
1862
1890
  static size_t
1863
1891
  ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
1864
1892
  void* dst, size_t maxDstSize,
1865
1893
  const void* seqStart, size_t seqSize, int nbSeq,
1866
- const ZSTD_longOffset_e isLongOffset,
1867
- const int frame)
1894
+ const ZSTD_longOffset_e isLongOffset)
1868
1895
  {
1869
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1896
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1870
1897
  }
1871
1898
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1872
1899
 
@@ -1880,20 +1907,18 @@ DONT_VECTORIZE
1880
1907
  ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
1881
1908
  void* dst, size_t maxDstSize,
1882
1909
  const void* seqStart, size_t seqSize, int nbSeq,
1883
- const ZSTD_longOffset_e isLongOffset,
1884
- const int frame)
1910
+ const ZSTD_longOffset_e isLongOffset)
1885
1911
  {
1886
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1912
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1887
1913
  }
1888
1914
  static BMI2_TARGET_ATTRIBUTE size_t
1889
1915
  DONT_VECTORIZE
1890
1916
  ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
1891
1917
  void* dst, size_t maxDstSize,
1892
1918
  const void* seqStart, size_t seqSize, int nbSeq,
1893
- const ZSTD_longOffset_e isLongOffset,
1894
- const int frame)
1919
+ const ZSTD_longOffset_e isLongOffset)
1895
1920
  {
1896
- return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1921
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1897
1922
  }
1898
1923
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1899
1924
 
@@ -1902,10 +1927,9 @@ static BMI2_TARGET_ATTRIBUTE size_t
1902
1927
  ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
1903
1928
  void* dst, size_t maxDstSize,
1904
1929
  const void* seqStart, size_t seqSize, int nbSeq,
1905
- const ZSTD_longOffset_e isLongOffset,
1906
- const int frame)
1930
+ const ZSTD_longOffset_e isLongOffset)
1907
1931
  {
1908
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1932
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1909
1933
  }
1910
1934
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1911
1935
 
@@ -1915,37 +1939,34 @@ typedef size_t (*ZSTD_decompressSequences_t)(
1915
1939
  ZSTD_DCtx* dctx,
1916
1940
  void* dst, size_t maxDstSize,
1917
1941
  const void* seqStart, size_t seqSize, int nbSeq,
1918
- const ZSTD_longOffset_e isLongOffset,
1919
- const int frame);
1942
+ const ZSTD_longOffset_e isLongOffset);
1920
1943
 
1921
1944
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
1922
1945
  static size_t
1923
1946
  ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1924
1947
  const void* seqStart, size_t seqSize, int nbSeq,
1925
- const ZSTD_longOffset_e isLongOffset,
1926
- const int frame)
1948
+ const ZSTD_longOffset_e isLongOffset)
1927
1949
  {
1928
1950
  DEBUGLOG(5, "ZSTD_decompressSequences");
1929
1951
  #if DYNAMIC_BMI2
1930
1952
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1931
- return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1953
+ return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1932
1954
  }
1933
1955
  #endif
1934
- return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1956
+ return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1935
1957
  }
1936
1958
  static size_t
1937
1959
  ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1938
1960
  const void* seqStart, size_t seqSize, int nbSeq,
1939
- const ZSTD_longOffset_e isLongOffset,
1940
- const int frame)
1961
+ const ZSTD_longOffset_e isLongOffset)
1941
1962
  {
1942
1963
  DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
1943
1964
  #if DYNAMIC_BMI2
1944
1965
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1945
- return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1966
+ return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1946
1967
  }
1947
1968
  #endif
1948
- return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1969
+ return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1949
1970
  }
1950
1971
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1951
1972
 
@@ -1960,16 +1981,15 @@ static size_t
1960
1981
  ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
1961
1982
  void* dst, size_t maxDstSize,
1962
1983
  const void* seqStart, size_t seqSize, int nbSeq,
1963
- const ZSTD_longOffset_e isLongOffset,
1964
- const int frame)
1984
+ const ZSTD_longOffset_e isLongOffset)
1965
1985
  {
1966
1986
  DEBUGLOG(5, "ZSTD_decompressSequencesLong");
1967
1987
  #if DYNAMIC_BMI2
1968
1988
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1969
- return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1989
+ return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1970
1990
  }
1971
1991
  #endif
1972
- return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1992
+ return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1973
1993
  }
1974
1994
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1975
1995
 
@@ -2051,20 +2071,20 @@ static size_t ZSTD_maxShortOffset(void)
2051
2071
  size_t
2052
2072
  ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2053
2073
  void* dst, size_t dstCapacity,
2054
- const void* src, size_t srcSize, const int frame, const streaming_operation streaming)
2074
+ const void* src, size_t srcSize, const streaming_operation streaming)
2055
2075
  { /* blockType == blockCompressed */
2056
2076
  const BYTE* ip = (const BYTE*)src;
2057
- DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
2077
+ DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize);
2058
2078
 
2059
2079
  /* Note : the wording of the specification
2060
- * allows compressed block to be sized exactly ZSTD_BLOCKSIZE_MAX.
2080
+ * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx).
2061
2081
  * This generally does not happen, as it makes little sense,
2062
2082
  * since an uncompressed block would feature same size and have no decompression cost.
2063
2083
  * Also, note that decoder from reference libzstd before < v1.5.4
2064
2084
  * would consider this edge case as an error.
2065
- * As a consequence, avoid generating compressed blocks of size ZSTD_BLOCKSIZE_MAX
2085
+ * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx)
2066
2086
  * for broader compatibility with the deployed ecosystem of zstd decoders */
2067
- RETURN_ERROR_IF(srcSize > ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
2087
+ RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, "");
2068
2088
 
2069
2089
  /* Decode literals section */
2070
2090
  { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
@@ -2079,8 +2099,8 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2079
2099
  /* Compute the maximum block size, which must also work when !frame and fParams are unset.
2080
2100
  * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
2081
2101
  */
2082
- size_t const blockSizeMax = MIN(dstCapacity, (frame ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX));
2083
- size_t const totalHistorySize = ZSTD_totalHistorySize((BYTE*)dst + blockSizeMax, (BYTE const*)dctx->virtualStart);
2102
+ size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
2103
+ size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart);
2084
2104
  /* isLongOffset must be true if there are long offsets.
2085
2105
  * Offsets are long if they are larger than ZSTD_maxShortOffset().
2086
2106
  * We don't expect that to be the case in 64-bit mode.
@@ -2145,21 +2165,22 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2145
2165
  {
2146
2166
  #endif
2147
2167
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
2148
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2168
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2149
2169
  #endif
2150
2170
  }
2151
2171
 
2152
2172
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
2153
2173
  /* else */
2154
2174
  if (dctx->litBufferLocation == ZSTD_split)
2155
- return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2175
+ return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2156
2176
  else
2157
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2177
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2158
2178
  #endif
2159
2179
  }
2160
2180
  }
2161
2181
 
2162
2182
 
2183
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
2163
2184
  void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
2164
2185
  {
2165
2186
  if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
@@ -2176,8 +2197,10 @@ size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
2176
2197
  const void* src, size_t srcSize)
2177
2198
  {
2178
2199
  size_t dSize;
2200
+ dctx->isFrameDecompression = 0;
2179
2201
  ZSTD_checkContinuity(dctx, dst, dstCapacity);
2180
- dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming);
2202
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming);
2203
+ FORWARD_IF_ERROR(dSize, "");
2181
2204
  dctx->previousDstEnd = (char*)dst + dSize;
2182
2205
  return dSize;
2183
2206
  }