multi_compress 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -3
  3. data/GET_STARTED.md +3 -3
  4. data/README.md +75 -66
  5. data/THIRD_PARTY_NOTICES.md +24 -0
  6. data/ext/multi_compress/brotli_dec_static_init.c +3 -0
  7. data/ext/multi_compress/brotli_enc_static_init.c +3 -0
  8. data/ext/multi_compress/extconf.rb +22 -1
  9. data/ext/multi_compress/multi_compress.c +152 -72
  10. data/ext/multi_compress/vendor/.vendored +2 -2
  11. data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
  12. data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
  13. data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
  14. data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
  15. data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
  16. data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
  17. data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
  18. data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
  19. data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
  20. data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
  21. data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
  22. data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
  23. data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
  24. data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
  25. data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
  26. data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
  27. data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
  28. data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
  29. data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
  30. data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
  31. data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
  32. data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
  33. data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
  34. data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
  35. data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
  36. data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
  37. data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
  38. data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
  39. data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
  40. data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
  41. data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
  42. data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
  43. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
  44. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
  45. data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
  46. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
  47. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
  48. data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
  49. data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
  50. data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
  51. data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
  52. data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
  53. data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
  54. data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
  55. data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
  56. data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
  57. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
  58. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
  59. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
  60. data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
  61. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
  62. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
  63. data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
  64. data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
  65. data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
  66. data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
  67. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
  68. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
  69. data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
  70. data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
  71. data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
  72. data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
  73. data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
  74. data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
  75. data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
  76. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
  77. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
  78. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
  79. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
  80. data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
  81. data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
  82. data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
  83. data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
  84. data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
  85. data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
  86. data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
  87. data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
  88. data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
  89. data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
  90. data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
  91. data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
  92. data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
  93. data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
  94. data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
  95. data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
  96. data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
  97. data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
  98. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
  99. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
  100. data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
  101. data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
  102. data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
  103. data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
  104. data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
  105. data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
  106. data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
  107. data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
  108. data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
  109. data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
  110. data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
  111. data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
  112. data/ext/multi_compress/vendor/zstd/COPYING +339 -0
  113. data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
  114. data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
  115. data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
  116. data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
  117. data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
  118. data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
  119. data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
  120. data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
  121. data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
  122. data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
  123. data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
  124. data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
  125. data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
  126. data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
  127. data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
  128. data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
  129. data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
  130. data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
  131. data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
  132. data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
  133. data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
  134. data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
  135. data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
  136. data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
  137. data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
  138. data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
  139. data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
  140. data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
  141. data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
  142. data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
  143. data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
  144. data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
  145. data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
  146. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
  147. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
  148. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
  149. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
  150. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
  151. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
  152. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
  153. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
  154. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
  155. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
  156. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
  157. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
  158. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
  159. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
  160. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
  161. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
  162. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
  163. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
  164. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
  165. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
  166. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
  167. data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
  168. data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
  169. data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
  170. data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
  171. data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
  172. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
  173. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
  174. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
  175. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
  176. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
  177. data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
  178. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
  179. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
  180. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
  181. data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
  182. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
  183. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
  184. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
  185. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
  186. data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
  187. data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
  188. data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
  189. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
  190. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
  191. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
  192. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
  193. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
  194. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
  195. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
  196. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
  197. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
  198. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
  199. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
  200. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
  201. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
  202. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
  203. data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
  204. data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
  205. data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
  206. data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
  207. data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
  208. data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
  209. data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
  210. data/lib/multi_compress/version.rb +1 -1
  211. metadata +29 -2
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) Yann Collet, Facebook, Inc.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -20,12 +20,12 @@
20
20
  #include "../common/mem.h" /* low level memory routines */
21
21
  #define FSE_STATIC_LINKING_ONLY
22
22
  #include "../common/fse.h"
23
- #define HUF_STATIC_LINKING_ONLY
24
23
  #include "../common/huf.h"
25
24
  #include "../common/zstd_internal.h"
26
25
  #include "zstd_decompress_internal.h" /* ZSTD_DCtx */
27
26
  #include "zstd_ddict.h" /* ZSTD_DDictDictContent */
28
27
  #include "zstd_decompress_block.h"
28
+ #include "../common/bits.h" /* ZSTD_highbit32 */
29
29
 
30
30
  /*_*******************************************************
31
31
  * Macros
@@ -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 {
92
- /* initially this will be stored entirely in dst during huffman decoding, it will partially shifted to litExtraBuffer after */
116
+ } else {
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
  {
@@ -124,7 +139,8 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
124
139
  RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
125
140
 
126
141
  { const BYTE* const istart = (const BYTE*) src;
127
- symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
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
  {
@@ -134,13 +150,16 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
134
150
  ZSTD_FALLTHROUGH;
135
151
 
136
152
  case set_compressed:
137
- RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3");
153
+ RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3");
138
154
  { size_t lhSize, litSize, litCSize;
139
155
  U32 singleStream=0;
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);
160
+ int const flags = 0
161
+ | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)
162
+ | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);
144
163
  switch(lhlCode)
145
164
  {
146
165
  case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -164,7 +183,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
164
183
  break;
165
184
  }
166
185
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
167
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
186
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
187
+ if (!singleStream)
188
+ RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
189
+ "Not enough literals (%zu) for the 4-streams mode (min %u)",
190
+ litSize, MIN_LITERALS_FOR_4_STREAMS);
168
191
  RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
169
192
  RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
170
193
  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
@@ -176,13 +199,14 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
176
199
 
177
200
  if (litEncType==set_repeat) {
178
201
  if (singleStream) {
179
- hufSuccess = HUF_decompress1X_usingDTable_bmi2(
202
+ hufSuccess = HUF_decompress1X_usingDTable(
180
203
  dctx->litBuffer, litSize, istart+lhSize, litCSize,
181
- dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
204
+ dctx->HUFptr, flags);
182
205
  } else {
183
- hufSuccess = HUF_decompress4X_usingDTable_bmi2(
206
+ assert(litSize >= MIN_LITERALS_FOR_4_STREAMS);
207
+ hufSuccess = HUF_decompress4X_usingDTable(
184
208
  dctx->litBuffer, litSize, istart+lhSize, litCSize,
185
- dctx->HUFptr, ZSTD_DCtx_get_bmi2(dctx));
209
+ dctx->HUFptr, flags);
186
210
  }
187
211
  } else {
188
212
  if (singleStream) {
@@ -190,26 +214,28 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
190
214
  hufSuccess = HUF_decompress1X_DCtx_wksp(
191
215
  dctx->entropy.hufTable, dctx->litBuffer, litSize,
192
216
  istart+lhSize, litCSize, dctx->workspace,
193
- sizeof(dctx->workspace));
217
+ sizeof(dctx->workspace), flags);
194
218
  #else
195
- hufSuccess = HUF_decompress1X1_DCtx_wksp_bmi2(
219
+ hufSuccess = HUF_decompress1X1_DCtx_wksp(
196
220
  dctx->entropy.hufTable, dctx->litBuffer, litSize,
197
221
  istart+lhSize, litCSize, dctx->workspace,
198
- sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
222
+ sizeof(dctx->workspace), flags);
199
223
  #endif
200
224
  } else {
201
- hufSuccess = HUF_decompress4X_hufOnly_wksp_bmi2(
225
+ hufSuccess = HUF_decompress4X_hufOnly_wksp(
202
226
  dctx->entropy.hufTable, dctx->litBuffer, litSize,
203
227
  istart+lhSize, litCSize, dctx->workspace,
204
- sizeof(dctx->workspace), ZSTD_DCtx_get_bmi2(dctx));
228
+ sizeof(dctx->workspace), flags);
205
229
  }
206
230
  }
207
231
  if (dctx->litBufferLocation == ZSTD_split)
208
232
  {
233
+ assert(litSize > ZSTD_LITBUFFEREXTRASIZE);
209
234
  ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
210
235
  ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
211
236
  dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
212
237
  dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
238
+ assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax);
213
239
  }
214
240
 
215
241
  RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
@@ -224,7 +250,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
224
250
  case set_basic:
225
251
  { size_t litSize, lhSize;
226
252
  U32 const lhlCode = ((istart[0]) >> 2) & 3;
227
- size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
253
+ size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
228
254
  switch(lhlCode)
229
255
  {
230
256
  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -237,11 +263,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
237
263
  break;
238
264
  case 3:
239
265
  lhSize = 3;
266
+ RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3");
240
267
  litSize = MEM_readLE24(istart) >> 4;
241
268
  break;
242
269
  }
243
270
 
244
271
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
272
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
245
273
  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
246
274
  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
247
275
  if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
@@ -270,7 +298,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
270
298
  case set_rle:
271
299
  { U32 const lhlCode = ((istart[0]) >> 2) & 3;
272
300
  size_t litSize, lhSize;
273
- size_t expectedWriteSize = MIN(ZSTD_BLOCKSIZE_MAX, dstCapacity);
301
+ size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
274
302
  switch(lhlCode)
275
303
  {
276
304
  case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
@@ -279,16 +307,17 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
279
307
  break;
280
308
  case 1:
281
309
  lhSize = 2;
310
+ RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3");
282
311
  litSize = MEM_readLE16(istart) >> 4;
283
312
  break;
284
313
  case 3:
285
314
  lhSize = 3;
315
+ RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4");
286
316
  litSize = MEM_readLE24(istart) >> 4;
287
- RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4");
288
317
  break;
289
318
  }
290
319
  RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
291
- RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected, "");
320
+ RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
292
321
  RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
293
322
  ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
294
323
  if (dctx->litBufferLocation == ZSTD_split)
@@ -310,6 +339,18 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
310
339
  }
311
340
  }
312
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
+
313
354
  /* Default FSE distribution tables.
314
355
  * These are pre-calculated FSE decoding tables using default distributions as defined in specification :
315
356
  * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
@@ -317,7 +358,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
317
358
  * - start from default distributions, present in /lib/common/zstd_internal.h
318
359
  * - generate tables normally, using ZSTD_buildFSETable()
319
360
  * - printout the content of tables
320
- * - pretify output, report below, test with fuzzer to ensure it's correct */
361
+ * - prettify output, report below, test with fuzzer to ensure it's correct */
321
362
 
322
363
  /* Default FSE distribution table for Literal Lengths */
323
364
  static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
@@ -506,14 +547,15 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
506
547
  for (i = 8; i < n; i += 8) {
507
548
  MEM_write64(spread + pos + i, sv);
508
549
  }
509
- pos += n;
550
+ assert(n>=0);
551
+ pos += (size_t)n;
510
552
  }
511
553
  }
512
554
  /* Now we spread those positions across the table.
513
- * The benefit of doing it in two stages is that we avoid the the
555
+ * The benefit of doing it in two stages is that we avoid the
514
556
  * variable size inner loop, which caused lots of branch misses.
515
557
  * Now we can run through all the positions without any branch misses.
516
- * We unroll the loop twice, since that is what emperically worked best.
558
+ * We unroll the loop twice, since that is what empirically worked best.
517
559
  */
518
560
  {
519
561
  size_t position = 0;
@@ -540,7 +582,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
540
582
  for (i=0; i<n; i++) {
541
583
  tableDecode[position].baseValue = s;
542
584
  position = (position + step) & tableMask;
543
- while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
585
+ while (UNLIKELY(position > highThreshold)) position = (position + step) & tableMask; /* lowprob area */
544
586
  } }
545
587
  assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
546
588
  }
@@ -551,7 +593,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
551
593
  for (u=0; u<tableSize; u++) {
552
594
  U32 const symbol = tableDecode[u].baseValue;
553
595
  U32 const nextState = symbolNext[symbol]++;
554
- tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );
596
+ tableDecode[u].nbBits = (BYTE) (tableLog - ZSTD_highbit32(nextState) );
555
597
  tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
556
598
  assert(nbAdditionalBits[symbol] < 255);
557
599
  tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol];
@@ -603,7 +645,7 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
603
645
  * @return : nb bytes read from src,
604
646
  * or an error code if it fails */
605
647
  static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
606
- symbolEncodingType_e type, unsigned max, U32 maxLog,
648
+ SymbolEncodingType_e type, unsigned max, U32 maxLog,
607
649
  const void* src, size_t srcSize,
608
650
  const U32* baseValue, const U8* nbAdditionalBits,
609
651
  const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
@@ -664,11 +706,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
664
706
 
665
707
  /* SeqHead */
666
708
  nbSeq = *ip++;
667
- if (!nbSeq) {
668
- *nbSeqPtr=0;
669
- RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
670
- return 1;
671
- }
672
709
  if (nbSeq > 0x7F) {
673
710
  if (nbSeq == 0xFF) {
674
711
  RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
@@ -681,11 +718,19 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
681
718
  }
682
719
  *nbSeqPtr = nbSeq;
683
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
+
684
728
  /* FSE table descriptors */
685
729
  RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
686
- { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
687
- symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
688
- symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
730
+ RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */
731
+ { SymbolEncodingType_e const LLtype = (SymbolEncodingType_e)(*ip >> 6);
732
+ SymbolEncodingType_e const OFtype = (SymbolEncodingType_e)((*ip >> 4) & 3);
733
+ SymbolEncodingType_e const MLtype = (SymbolEncodingType_e)((*ip >> 2) & 3);
689
734
  ip++;
690
735
 
691
736
  /* Build DTables */
@@ -829,7 +874,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
829
874
  /* ZSTD_safecopyDstBeforeSrc():
830
875
  * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
831
876
  * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
832
- 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) {
833
878
  ptrdiff_t const diff = op - ip;
834
879
  BYTE* const oend = op + length;
835
880
 
@@ -858,6 +903,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length
858
903
  * to be optimized for many small sequences, since those fall into ZSTD_execSequence().
859
904
  */
860
905
  FORCE_NOINLINE
906
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
861
907
  size_t ZSTD_execSequenceEnd(BYTE* op,
862
908
  BYTE* const oend, seq_t sequence,
863
909
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -905,6 +951,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
905
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.
906
952
  */
907
953
  FORCE_NOINLINE
954
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
908
955
  size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
909
956
  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
910
957
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -950,6 +997,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
950
997
  }
951
998
 
952
999
  HINT_INLINE
1000
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
953
1001
  size_t ZSTD_execSequence(BYTE* op,
954
1002
  BYTE* const oend, seq_t sequence,
955
1003
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -964,6 +1012,11 @@ size_t ZSTD_execSequence(BYTE* op,
964
1012
 
965
1013
  assert(op != NULL /* Precondition */);
966
1014
  assert(oend_w < oend /* No underflow */);
1015
+
1016
+ #if defined(__aarch64__)
1017
+ /* prefetch sequence starting from match that will be used for copy later */
1018
+ PREFETCH_L1(match);
1019
+ #endif
967
1020
  /* Handle edge cases in a slow path:
968
1021
  * - Read beyond end of literals
969
1022
  * - Match end is within WILDCOPY_OVERLIMIT of oend
@@ -1043,6 +1096,7 @@ size_t ZSTD_execSequence(BYTE* op,
1043
1096
  }
1044
1097
 
1045
1098
  HINT_INLINE
1099
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
1046
1100
  size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
1047
1101
  BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
1048
1102
  const BYTE** litPtr, const BYTE* const litLimit,
@@ -1154,7 +1208,7 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16
1154
1208
  }
1155
1209
 
1156
1210
  /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
1157
- * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
1211
+ * offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32
1158
1212
  * bits before reloading. This value is the maximum number of bytes we read
1159
1213
  * after reloading when we are decoding long offsets.
1160
1214
  */
@@ -1165,13 +1219,37 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16
1165
1219
 
1166
1220
  typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
1167
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
+ */
1168
1228
  FORCE_INLINE_TEMPLATE seq_t
1169
- ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1229
+ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
1170
1230
  {
1171
1231
  seq_t seq;
1232
+ /*
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.
1236
+ * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh
1237
+ * operations that cause performance drop. This can be avoided by using this
1238
+ * ZSTD_memcpy hack.
1239
+ */
1240
+ #if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__))
1241
+ ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
1242
+ ZSTD_seqSymbol* const llDInfo = &llDInfoS;
1243
+ ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
1244
+ ZSTD_seqSymbol* const ofDInfo = &ofDInfoS;
1245
+ ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol));
1246
+ ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol));
1247
+ ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol));
1248
+ #else
1172
1249
  const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
1173
1250
  const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
1174
1251
  const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
1252
+ #endif
1175
1253
  seq.matchLength = mlDInfo->baseValue;
1176
1254
  seq.litLength = llDInfo->baseValue;
1177
1255
  { U32 const ofBase = ofDInfo->baseValue;
@@ -1186,28 +1264,31 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1186
1264
  U32 const llnbBits = llDInfo->nbBits;
1187
1265
  U32 const mlnbBits = mlDInfo->nbBits;
1188
1266
  U32 const ofnbBits = ofDInfo->nbBits;
1267
+
1268
+ assert(llBits <= MaxLLBits);
1269
+ assert(mlBits <= MaxMLBits);
1270
+ assert(ofBits <= MaxOff);
1189
1271
  /*
1190
1272
  * As gcc has better branch and block analyzers, sometimes it is only
1191
- * valuable to mark likelyness for clang, it gives around 3-4% of
1273
+ * valuable to mark likeliness for clang, it gives around 3-4% of
1192
1274
  * performance.
1193
1275
  */
1194
1276
 
1195
1277
  /* sequence */
1196
1278
  { size_t offset;
1197
- #if defined(__clang__)
1198
- if (LIKELY(ofBits > 1)) {
1199
- #else
1200
1279
  if (ofBits > 1) {
1201
- #endif
1202
1280
  ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
1203
1281
  ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
1204
- assert(ofBits <= MaxOff);
1282
+ ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32);
1283
+ ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits);
1205
1284
  if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
1206
- U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);
1285
+ /* Always read extra bits, this keeps the logic simple,
1286
+ * avoids branches, and avoids accidentally reading 0 bits.
1287
+ */
1288
+ U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32;
1207
1289
  offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
1208
1290
  BIT_reloadDStream(&seqState->DStream);
1209
- if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
1210
- assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
1291
+ offset += BIT_readBitsFast(&seqState->DStream, extraBits);
1211
1292
  } else {
1212
1293
  offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1213
1294
  if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
@@ -1224,7 +1305,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1224
1305
  } else {
1225
1306
  offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
1226
1307
  { size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1227
- 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 */
1228
1309
  if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
1229
1310
  seqState->prevOffset[1] = seqState->prevOffset[0];
1230
1311
  seqState->prevOffset[0] = offset = temp;
@@ -1232,11 +1313,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1232
1313
  seq.offset = offset;
1233
1314
  }
1234
1315
 
1235
- #if defined(__clang__)
1236
- if (UNLIKELY(mlBits > 0))
1237
- #else
1238
1316
  if (mlBits > 0)
1239
- #endif
1240
1317
  seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
1241
1318
 
1242
1319
  if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
@@ -1246,11 +1323,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1246
1323
  /* Ensure there are enough bits to read the rest of data in 64-bit mode. */
1247
1324
  ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
1248
1325
 
1249
- #if defined(__clang__)
1250
- if (UNLIKELY(llBits > 0))
1251
- #else
1252
1326
  if (llBits > 0)
1253
- #endif
1254
1327
  seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
1255
1328
 
1256
1329
  if (MEM_32bits())
@@ -1259,17 +1332,22 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
1259
1332
  DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
1260
1333
  (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1261
1334
 
1262
- ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits); /* <= 9 bits */
1263
- ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits); /* <= 9 bits */
1264
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1265
- 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
+ }
1266
1343
  }
1267
1344
 
1268
1345
  return seq;
1269
1346
  }
1270
1347
 
1271
- #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1272
- 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)
1273
1351
  {
1274
1352
  size_t const windowSize = dctx->fParams.windowSize;
1275
1353
  /* No dictionary used. */
@@ -1283,30 +1361,33 @@ MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefix
1283
1361
  /* Dictionary is active. */
1284
1362
  return 1;
1285
1363
  }
1364
+ #endif
1286
1365
 
1287
- MEM_STATIC void ZSTD_assertValidSequence(
1366
+ static void ZSTD_assertValidSequence(
1288
1367
  ZSTD_DCtx const* dctx,
1289
1368
  BYTE const* op, BYTE const* oend,
1290
1369
  seq_t const seq,
1291
1370
  BYTE const* prefixStart, BYTE const* virtualStart)
1292
1371
  {
1293
1372
  #if DEBUGLEVEL >= 1
1294
- size_t const windowSize = dctx->fParams.windowSize;
1295
- size_t const sequenceSize = seq.litLength + seq.matchLength;
1296
- BYTE const* const oLitEnd = op + seq.litLength;
1297
- DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
1298
- (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
1299
- assert(op <= oend);
1300
- assert((size_t)(oend - op) >= sequenceSize);
1301
- assert(sequenceSize <= ZSTD_BLOCKSIZE_MAX);
1302
- if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
1303
- size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
1304
- /* Offset must be within the dictionary. */
1305
- assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
1306
- assert(seq.offset <= windowSize + dictSize);
1307
- } else {
1308
- /* Offset must be within our window. */
1309
- 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
+ }
1310
1391
  }
1311
1392
  #else
1312
1393
  (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
@@ -1322,23 +1403,21 @@ DONT_VECTORIZE
1322
1403
  ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1323
1404
  void* dst, size_t maxDstSize,
1324
1405
  const void* seqStart, size_t seqSize, int nbSeq,
1325
- const ZSTD_longOffset_e isLongOffset,
1326
- const int frame)
1406
+ const ZSTD_longOffset_e isLongOffset)
1327
1407
  {
1328
1408
  const BYTE* ip = (const BYTE*)seqStart;
1329
1409
  const BYTE* const iend = ip + seqSize;
1330
1410
  BYTE* const ostart = (BYTE*)dst;
1331
- BYTE* const oend = ostart + maxDstSize;
1411
+ BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
1332
1412
  BYTE* op = ostart;
1333
1413
  const BYTE* litPtr = dctx->litPtr;
1334
1414
  const BYTE* litBufferEnd = dctx->litBufferEnd;
1335
1415
  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1336
1416
  const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
1337
1417
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1338
- DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
1339
- (void)frame;
1418
+ DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq);
1340
1419
 
1341
- /* Regen sequences */
1420
+ /* Literals are split between internal buffer & output buffer */
1342
1421
  if (nbSeq) {
1343
1422
  seqState_t seqState;
1344
1423
  dctx->fseEntropy = 1;
@@ -1357,8 +1436,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1357
1436
  BIT_DStream_completed < BIT_DStream_overflow);
1358
1437
 
1359
1438
  /* decompress without overrunning litPtr begins */
1360
- {
1361
- 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) */
1362
1440
  /* Align the decompression loop to 32 + 16 bytes.
1363
1441
  *
1364
1442
  * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
@@ -1420,27 +1498,26 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1420
1498
  #endif
1421
1499
 
1422
1500
  /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
1423
- for (; litPtr + sequence.litLength <= dctx->litBufferEnd; ) {
1424
- 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);
1425
1505
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1426
- assert(!ZSTD_isError(oneSeqSize));
1427
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1506
+ assert(!ZSTD_isError(oneSeqSize));
1507
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1428
1508
  #endif
1429
- if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1430
- return oneSeqSize;
1431
- DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1432
- op += oneSeqSize;
1433
- if (UNLIKELY(!--nbSeq))
1434
- break;
1435
- BIT_reloadDStream(&(seqState.DStream));
1436
- sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1437
- }
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)");
1438
1515
 
1439
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 */
1440
1517
  if (nbSeq > 0) {
1441
1518
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1442
- if (leftoverLit)
1443
- {
1519
+ DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
1520
+ if (leftoverLit) {
1444
1521
  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1445
1522
  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1446
1523
  sequence.litLength -= leftoverLit;
@@ -1449,24 +1526,22 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1449
1526
  litPtr = dctx->litExtraBuffer;
1450
1527
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1451
1528
  dctx->litBufferLocation = ZSTD_not_in_dst;
1452
- {
1453
- 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);
1454
1530
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1455
1531
  assert(!ZSTD_isError(oneSeqSize));
1456
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1532
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1457
1533
  #endif
1458
1534
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1459
1535
  return oneSeqSize;
1460
1536
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1461
1537
  op += oneSeqSize;
1462
- if (--nbSeq)
1463
- BIT_reloadDStream(&(seqState.DStream));
1464
1538
  }
1539
+ nbSeq--;
1465
1540
  }
1466
1541
  }
1467
1542
 
1468
- if (nbSeq > 0) /* there is remaining lit from extra buffer */
1469
- {
1543
+ if (nbSeq > 0) {
1544
+ /* there is remaining lit from extra buffer */
1470
1545
 
1471
1546
  #if defined(__GNUC__) && defined(__x86_64__)
1472
1547
  __asm__(".p2align 6");
@@ -1485,35 +1560,34 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1485
1560
  # endif
1486
1561
  #endif
1487
1562
 
1488
- for (; ; ) {
1489
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1563
+ for ( ; nbSeq ; nbSeq--) {
1564
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
1490
1565
  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
1491
1566
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1492
1567
  assert(!ZSTD_isError(oneSeqSize));
1493
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1568
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1494
1569
  #endif
1495
1570
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1496
1571
  return oneSeqSize;
1497
1572
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1498
1573
  op += oneSeqSize;
1499
- if (UNLIKELY(!--nbSeq))
1500
- break;
1501
- BIT_reloadDStream(&(seqState.DStream));
1502
1574
  }
1503
1575
  }
1504
1576
 
1505
1577
  /* check if reached exact end */
1506
1578
  DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
1507
1579
  RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1508
- 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, "");
1509
1582
  /* save reps for next block */
1510
1583
  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1511
1584
  }
1512
1585
 
1513
1586
  /* last literal segment */
1514
- if (dctx->litBufferLocation == ZSTD_split) /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
1515
- {
1516
- 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);
1517
1591
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1518
1592
  if (op != NULL) {
1519
1593
  ZSTD_memmove(op, litPtr, lastLLSize);
@@ -1523,15 +1597,17 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
1523
1597
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1524
1598
  dctx->litBufferLocation = ZSTD_not_in_dst;
1525
1599
  }
1526
- { 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);
1527
1603
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1528
1604
  if (op != NULL) {
1529
1605
  ZSTD_memcpy(op, litPtr, lastLLSize);
1530
1606
  op += lastLLSize;
1531
- }
1532
- }
1607
+ } }
1533
1608
 
1534
- return op-ostart;
1609
+ DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
1610
+ return (size_t)(op - ostart);
1535
1611
  }
1536
1612
 
1537
1613
  FORCE_INLINE_TEMPLATE size_t
@@ -1539,21 +1615,19 @@ DONT_VECTORIZE
1539
1615
  ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1540
1616
  void* dst, size_t maxDstSize,
1541
1617
  const void* seqStart, size_t seqSize, int nbSeq,
1542
- const ZSTD_longOffset_e isLongOffset,
1543
- const int frame)
1618
+ const ZSTD_longOffset_e isLongOffset)
1544
1619
  {
1545
1620
  const BYTE* ip = (const BYTE*)seqStart;
1546
1621
  const BYTE* const iend = ip + seqSize;
1547
1622
  BYTE* const ostart = (BYTE*)dst;
1548
- 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;
1549
1624
  BYTE* op = ostart;
1550
1625
  const BYTE* litPtr = dctx->litPtr;
1551
1626
  const BYTE* const litEnd = litPtr + dctx->litSize;
1552
1627
  const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart);
1553
1628
  const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
1554
1629
  const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
1555
- DEBUGLOG(5, "ZSTD_decompressSequences_body");
1556
- (void)frame;
1630
+ DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq);
1557
1631
 
1558
1632
  /* Regen sequences */
1559
1633
  if (nbSeq) {
@@ -1568,11 +1642,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1568
1642
  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1569
1643
  assert(dst != NULL);
1570
1644
 
1571
- ZSTD_STATIC_ASSERT(
1572
- BIT_DStream_unfinished < BIT_DStream_completed &&
1573
- BIT_DStream_endOfBuffer < BIT_DStream_completed &&
1574
- BIT_DStream_completed < BIT_DStream_overflow);
1575
-
1576
1645
  #if defined(__GNUC__) && defined(__x86_64__)
1577
1646
  __asm__(".p2align 6");
1578
1647
  __asm__("nop");
@@ -1587,73 +1656,70 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
1587
1656
  # endif
1588
1657
  #endif
1589
1658
 
1590
- for ( ; ; ) {
1591
- seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1659
+ for ( ; nbSeq ; nbSeq--) {
1660
+ seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
1592
1661
  size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
1593
1662
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1594
1663
  assert(!ZSTD_isError(oneSeqSize));
1595
- if (frame) ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1664
+ ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
1596
1665
  #endif
1597
1666
  if (UNLIKELY(ZSTD_isError(oneSeqSize)))
1598
1667
  return oneSeqSize;
1599
1668
  DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1600
1669
  op += oneSeqSize;
1601
- if (UNLIKELY(!--nbSeq))
1602
- break;
1603
- BIT_reloadDStream(&(seqState.DStream));
1604
1670
  }
1605
1671
 
1606
1672
  /* check if reached exact end */
1607
- DEBUGLOG(5, "ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i", nbSeq);
1608
- RETURN_ERROR_IF(nbSeq, corruption_detected, "");
1609
- 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, "");
1610
1675
  /* save reps for next block */
1611
1676
  { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1612
1677
  }
1613
1678
 
1614
1679
  /* last literal segment */
1615
- { size_t const lastLLSize = litEnd - litPtr;
1680
+ { size_t const lastLLSize = (size_t)(litEnd - litPtr);
1681
+ DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize);
1616
1682
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
1617
1683
  if (op != NULL) {
1618
1684
  ZSTD_memcpy(op, litPtr, lastLLSize);
1619
1685
  op += lastLLSize;
1620
- }
1621
- }
1686
+ } }
1622
1687
 
1623
- return op-ostart;
1688
+ DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
1689
+ return (size_t)(op - ostart);
1624
1690
  }
1625
1691
 
1626
1692
  static size_t
1627
1693
  ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
1628
1694
  void* dst, size_t maxDstSize,
1629
1695
  const void* seqStart, size_t seqSize, int nbSeq,
1630
- const ZSTD_longOffset_e isLongOffset,
1631
- const int frame)
1696
+ const ZSTD_longOffset_e isLongOffset)
1632
1697
  {
1633
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1698
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1634
1699
  }
1635
1700
 
1636
1701
  static size_t
1637
1702
  ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
1638
1703
  void* dst, size_t maxDstSize,
1639
1704
  const void* seqStart, size_t seqSize, int nbSeq,
1640
- const ZSTD_longOffset_e isLongOffset,
1641
- const int frame)
1705
+ const ZSTD_longOffset_e isLongOffset)
1642
1706
  {
1643
- return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1707
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1644
1708
  }
1645
1709
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1646
1710
 
1647
1711
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
1648
1712
 
1649
- FORCE_INLINE_TEMPLATE size_t
1650
- 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,
1651
1716
  const BYTE* const prefixStart, const BYTE* const dictEnd)
1652
1717
  {
1653
1718
  prefetchPos += sequence.litLength;
1654
1719
  { const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
1655
- 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.
1656
- * 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);
1657
1723
  PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
1658
1724
  }
1659
1725
  return prefetchPos + sequence.matchLength;
@@ -1668,20 +1734,18 @@ ZSTD_decompressSequencesLong_body(
1668
1734
  ZSTD_DCtx* dctx,
1669
1735
  void* dst, size_t maxDstSize,
1670
1736
  const void* seqStart, size_t seqSize, int nbSeq,
1671
- const ZSTD_longOffset_e isLongOffset,
1672
- const int frame)
1737
+ const ZSTD_longOffset_e isLongOffset)
1673
1738
  {
1674
1739
  const BYTE* ip = (const BYTE*)seqStart;
1675
1740
  const BYTE* const iend = ip + seqSize;
1676
1741
  BYTE* const ostart = (BYTE*)dst;
1677
- 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);
1678
1743
  BYTE* op = ostart;
1679
1744
  const BYTE* litPtr = dctx->litPtr;
1680
1745
  const BYTE* litBufferEnd = dctx->litBufferEnd;
1681
1746
  const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
1682
1747
  const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
1683
1748
  const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1684
- (void)frame;
1685
1749
 
1686
1750
  /* Regen sequences */
1687
1751
  if (nbSeq) {
@@ -1706,20 +1770,17 @@ ZSTD_decompressSequencesLong_body(
1706
1770
  ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1707
1771
 
1708
1772
  /* prepare in advance */
1709
- for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {
1710
- 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);
1711
1775
  prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1712
1776
  sequences[seqNb] = sequence;
1713
1777
  }
1714
- RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
1715
1778
 
1716
1779
  /* decompress without stomping litBuffer */
1717
- for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb < nbSeq); seqNb++) {
1718
- seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1719
- size_t oneSeqSize;
1780
+ for (; seqNb < nbSeq; seqNb++) {
1781
+ seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
1720
1782
 
1721
- if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
1722
- {
1783
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
1723
1784
  /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
1724
1785
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1725
1786
  if (leftoverLit)
@@ -1732,26 +1793,26 @@ ZSTD_decompressSequencesLong_body(
1732
1793
  litPtr = dctx->litExtraBuffer;
1733
1794
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1734
1795
  dctx->litBufferLocation = ZSTD_not_in_dst;
1735
- 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);
1736
1797
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1737
- assert(!ZSTD_isError(oneSeqSize));
1738
- 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);
1739
1800
  #endif
1740
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1801
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1741
1802
 
1742
- prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1743
- sequences[seqNb & STORED_SEQS_MASK] = sequence;
1744
- op += oneSeqSize;
1745
- }
1803
+ prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
1804
+ sequences[seqNb & STORED_SEQS_MASK] = sequence;
1805
+ op += oneSeqSize;
1806
+ } }
1746
1807
  else
1747
1808
  {
1748
1809
  /* lit buffer is either wholly contained in first or second split, or not split at all*/
1749
- oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1810
+ size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
1750
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) :
1751
1812
  ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1752
1813
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1753
1814
  assert(!ZSTD_isError(oneSeqSize));
1754
- 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);
1755
1816
  #endif
1756
1817
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1757
1818
 
@@ -1760,17 +1821,15 @@ ZSTD_decompressSequencesLong_body(
1760
1821
  op += oneSeqSize;
1761
1822
  }
1762
1823
  }
1763
- RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected, "");
1824
+ RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
1764
1825
 
1765
1826
  /* finish queue */
1766
1827
  seqNb -= seqAdvance;
1767
1828
  for ( ; seqNb<nbSeq ; seqNb++) {
1768
1829
  seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
1769
- if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
1770
- {
1830
+ if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
1771
1831
  const size_t leftoverLit = dctx->litBufferEnd - litPtr;
1772
- if (leftoverLit)
1773
- {
1832
+ if (leftoverLit) {
1774
1833
  RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
1775
1834
  ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
1776
1835
  sequence->litLength -= leftoverLit;
@@ -1779,11 +1838,10 @@ ZSTD_decompressSequencesLong_body(
1779
1838
  litPtr = dctx->litExtraBuffer;
1780
1839
  litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
1781
1840
  dctx->litBufferLocation = ZSTD_not_in_dst;
1782
- {
1783
- 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);
1784
1842
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1785
1843
  assert(!ZSTD_isError(oneSeqSize));
1786
- 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);
1787
1845
  #endif
1788
1846
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1789
1847
  op += oneSeqSize;
@@ -1796,7 +1854,7 @@ ZSTD_decompressSequencesLong_body(
1796
1854
  ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
1797
1855
  #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
1798
1856
  assert(!ZSTD_isError(oneSeqSize));
1799
- 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);
1800
1858
  #endif
1801
1859
  if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1802
1860
  op += oneSeqSize;
@@ -1808,8 +1866,7 @@ ZSTD_decompressSequencesLong_body(
1808
1866
  }
1809
1867
 
1810
1868
  /* last literal segment */
1811
- if (dctx->litBufferLocation == ZSTD_split) /* first deplete literal buffer in dst, then copy litExtraBuffer */
1812
- {
1869
+ if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
1813
1870
  size_t const lastLLSize = litBufferEnd - litPtr;
1814
1871
  RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
1815
1872
  if (op != NULL) {
@@ -1827,17 +1884,16 @@ ZSTD_decompressSequencesLong_body(
1827
1884
  }
1828
1885
  }
1829
1886
 
1830
- return op-ostart;
1887
+ return (size_t)(op - ostart);
1831
1888
  }
1832
1889
 
1833
1890
  static size_t
1834
1891
  ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
1835
1892
  void* dst, size_t maxDstSize,
1836
1893
  const void* seqStart, size_t seqSize, int nbSeq,
1837
- const ZSTD_longOffset_e isLongOffset,
1838
- const int frame)
1894
+ const ZSTD_longOffset_e isLongOffset)
1839
1895
  {
1840
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1896
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1841
1897
  }
1842
1898
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1843
1899
 
@@ -1851,20 +1907,18 @@ DONT_VECTORIZE
1851
1907
  ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
1852
1908
  void* dst, size_t maxDstSize,
1853
1909
  const void* seqStart, size_t seqSize, int nbSeq,
1854
- const ZSTD_longOffset_e isLongOffset,
1855
- const int frame)
1910
+ const ZSTD_longOffset_e isLongOffset)
1856
1911
  {
1857
- return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1912
+ return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1858
1913
  }
1859
1914
  static BMI2_TARGET_ATTRIBUTE size_t
1860
1915
  DONT_VECTORIZE
1861
1916
  ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
1862
1917
  void* dst, size_t maxDstSize,
1863
1918
  const void* seqStart, size_t seqSize, int nbSeq,
1864
- const ZSTD_longOffset_e isLongOffset,
1865
- const int frame)
1919
+ const ZSTD_longOffset_e isLongOffset)
1866
1920
  {
1867
- return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1921
+ return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1868
1922
  }
1869
1923
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1870
1924
 
@@ -1873,50 +1927,40 @@ static BMI2_TARGET_ATTRIBUTE size_t
1873
1927
  ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
1874
1928
  void* dst, size_t maxDstSize,
1875
1929
  const void* seqStart, size_t seqSize, int nbSeq,
1876
- const ZSTD_longOffset_e isLongOffset,
1877
- const int frame)
1930
+ const ZSTD_longOffset_e isLongOffset)
1878
1931
  {
1879
- return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1932
+ return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1880
1933
  }
1881
1934
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1882
1935
 
1883
1936
  #endif /* DYNAMIC_BMI2 */
1884
1937
 
1885
- typedef size_t (*ZSTD_decompressSequences_t)(
1886
- ZSTD_DCtx* dctx,
1887
- void* dst, size_t maxDstSize,
1888
- const void* seqStart, size_t seqSize, int nbSeq,
1889
- const ZSTD_longOffset_e isLongOffset,
1890
- const int frame);
1891
-
1892
1938
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
1893
1939
  static size_t
1894
1940
  ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1895
1941
  const void* seqStart, size_t seqSize, int nbSeq,
1896
- const ZSTD_longOffset_e isLongOffset,
1897
- const int frame)
1942
+ const ZSTD_longOffset_e isLongOffset)
1898
1943
  {
1899
1944
  DEBUGLOG(5, "ZSTD_decompressSequences");
1900
1945
  #if DYNAMIC_BMI2
1901
1946
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1902
- return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1947
+ return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1903
1948
  }
1904
1949
  #endif
1905
- return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1950
+ return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1906
1951
  }
1907
1952
  static size_t
1908
1953
  ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
1909
1954
  const void* seqStart, size_t seqSize, int nbSeq,
1910
- const ZSTD_longOffset_e isLongOffset,
1911
- const int frame)
1955
+ const ZSTD_longOffset_e isLongOffset)
1912
1956
  {
1913
1957
  DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
1914
1958
  #if DYNAMIC_BMI2
1915
1959
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1916
- return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1960
+ return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1917
1961
  }
1918
1962
  #endif
1919
- return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1963
+ return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1920
1964
  }
1921
1965
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
1922
1966
 
@@ -1931,69 +1975,114 @@ static size_t
1931
1975
  ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
1932
1976
  void* dst, size_t maxDstSize,
1933
1977
  const void* seqStart, size_t seqSize, int nbSeq,
1934
- const ZSTD_longOffset_e isLongOffset,
1935
- const int frame)
1978
+ const ZSTD_longOffset_e isLongOffset)
1936
1979
  {
1937
1980
  DEBUGLOG(5, "ZSTD_decompressSequencesLong");
1938
1981
  #if DYNAMIC_BMI2
1939
1982
  if (ZSTD_DCtx_get_bmi2(dctx)) {
1940
- return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1983
+ return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1941
1984
  }
1942
1985
  #endif
1943
- return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset, frame);
1986
+ return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
1944
1987
  }
1945
1988
  #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
1946
1989
 
1947
1990
 
1991
+ /**
1992
+ * @returns The total size of the history referenceable by zstd, including
1993
+ * both the prefix and the extDict. At @p op any offset larger than this
1994
+ * is invalid.
1995
+ */
1996
+ static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart)
1997
+ {
1998
+ return (size_t)(op - virtualStart);
1999
+ }
2000
+
2001
+ typedef struct {
2002
+ unsigned longOffsetShare;
2003
+ unsigned maxNbAdditionalBits;
2004
+ } ZSTD_OffsetInfo;
1948
2005
 
1949
- #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
1950
- !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
1951
- /* ZSTD_getLongOffsetsShare() :
2006
+ /* ZSTD_getOffsetInfo() :
1952
2007
  * condition : offTable must be valid
1953
2008
  * @return : "share" of long offsets (arbitrarily defined as > (1<<23))
1954
- * compared to maximum possible of (1<<OffFSELog) */
1955
- static unsigned
1956
- ZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)
2009
+ * compared to maximum possible of (1<<OffFSELog),
2010
+ * as well as the maximum number additional bits required.
2011
+ */
2012
+ static ZSTD_OffsetInfo
2013
+ ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable, int nbSeq)
1957
2014
  {
1958
- const void* ptr = offTable;
1959
- U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
1960
- const ZSTD_seqSymbol* table = offTable + 1;
1961
- U32 const max = 1 << tableLog;
1962
- U32 u, total = 0;
1963
- DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
1964
-
1965
- assert(max <= (1 << OffFSELog)); /* max not too large */
1966
- for (u=0; u<max; u++) {
1967
- if (table[u].nbAdditionalBits > 22) total += 1;
2015
+ ZSTD_OffsetInfo info = {0, 0};
2016
+ /* If nbSeq == 0, then the offTable is uninitialized, but we have
2017
+ * no sequences, so both values should be 0.
2018
+ */
2019
+ if (nbSeq != 0) {
2020
+ const void* ptr = offTable;
2021
+ U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
2022
+ const ZSTD_seqSymbol* table = offTable + 1;
2023
+ U32 const max = 1 << tableLog;
2024
+ U32 u;
2025
+ DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
2026
+
2027
+ assert(max <= (1 << OffFSELog)); /* max not too large */
2028
+ for (u=0; u<max; u++) {
2029
+ info.maxNbAdditionalBits = MAX(info.maxNbAdditionalBits, table[u].nbAdditionalBits);
2030
+ if (table[u].nbAdditionalBits > 22) info.longOffsetShare += 1;
2031
+ }
2032
+
2033
+ assert(tableLog <= OffFSELog);
2034
+ info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */
1968
2035
  }
1969
2036
 
1970
- assert(tableLog <= OffFSELog);
1971
- total <<= (OffFSELog - tableLog); /* scale to OffFSELog */
2037
+ return info;
2038
+ }
1972
2039
 
1973
- return total;
2040
+ /**
2041
+ * @returns The maximum offset we can decode in one read of our bitstream, without
2042
+ * reloading more bits in the middle of the offset bits read. Any offsets larger
2043
+ * than this must use the long offset decoder.
2044
+ */
2045
+ static size_t ZSTD_maxShortOffset(void)
2046
+ {
2047
+ if (MEM_64bits()) {
2048
+ /* We can decode any offset without reloading bits.
2049
+ * This might change if the max window size grows.
2050
+ */
2051
+ ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
2052
+ return (size_t)-1;
2053
+ } else {
2054
+ /* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1.
2055
+ * This offBase would require STREAM_ACCUMULATOR_MIN extra bits.
2056
+ * Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset.
2057
+ */
2058
+ size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1;
2059
+ size_t const maxOffset = maxOffbase - ZSTD_REP_NUM;
2060
+ assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN);
2061
+ return maxOffset;
2062
+ }
1974
2063
  }
1975
- #endif
1976
2064
 
1977
2065
  size_t
1978
2066
  ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1979
2067
  void* dst, size_t dstCapacity,
1980
- const void* src, size_t srcSize, const int frame, const streaming_operation streaming)
2068
+ const void* src, size_t srcSize, const streaming_operation streaming)
1981
2069
  { /* blockType == blockCompressed */
1982
2070
  const BYTE* ip = (const BYTE*)src;
1983
- /* isLongOffset must be true if there are long offsets.
1984
- * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
1985
- * We don't expect that to be the case in 64-bit mode.
1986
- * In block mode, window size is not known, so we have to be conservative.
1987
- * (note: but it could be evaluated from current-lowLimit)
1988
- */
1989
- ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))));
1990
- DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
1991
-
1992
- RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong, "");
2071
+ DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize);
2072
+
2073
+ /* Note : the wording of the specification
2074
+ * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx).
2075
+ * This generally does not happen, as it makes little sense,
2076
+ * since an uncompressed block would feature same size and have no decompression cost.
2077
+ * Also, note that decoder from reference libzstd before < v1.5.4
2078
+ * would consider this edge case as an error.
2079
+ * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx)
2080
+ * for broader compatibility with the deployed ecosystem of zstd decoders */
2081
+ RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, "");
1993
2082
 
1994
2083
  /* Decode literals section */
1995
2084
  { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
1996
- DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize);
2085
+ DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize);
1997
2086
  if (ZSTD_isError(litCSize)) return litCSize;
1998
2087
  ip += litCSize;
1999
2088
  srcSize -= litCSize;
@@ -2001,6 +2090,23 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2001
2090
 
2002
2091
  /* Build Decoding Tables */
2003
2092
  {
2093
+ /* Compute the maximum block size, which must also work when !frame and fParams are unset.
2094
+ * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
2095
+ */
2096
+ size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
2097
+ size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart);
2098
+ /* isLongOffset must be true if there are long offsets.
2099
+ * Offsets are long if they are larger than ZSTD_maxShortOffset().
2100
+ * We don't expect that to be the case in 64-bit mode.
2101
+ *
2102
+ * We check here to see if our history is large enough to allow long offsets.
2103
+ * If it isn't, then we can't possible have (valid) long offsets. If the offset
2104
+ * is invalid, then it is okay to read it incorrectly.
2105
+ *
2106
+ * If isLongOffsets is true, then we will later check our decoding table to see
2107
+ * if it is even possible to generate long offsets.
2108
+ */
2109
+ ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset()));
2004
2110
  /* These macros control at build-time which decompressor implementation
2005
2111
  * we use. If neither is defined, we do some inspection and dispatch at
2006
2112
  * runtime.
@@ -2008,6 +2114,11 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2008
2114
  #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2009
2115
  !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2010
2116
  int usePrefetchDecoder = dctx->ddictIsCold;
2117
+ #else
2118
+ /* Set to 1 to avoid computing offset info if we don't need to.
2119
+ * Otherwise this value is ignored.
2120
+ */
2121
+ int usePrefetchDecoder = 1;
2011
2122
  #endif
2012
2123
  int nbSeq;
2013
2124
  size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);
@@ -2015,40 +2126,55 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
2015
2126
  ip += seqHSize;
2016
2127
  srcSize -= seqHSize;
2017
2128
 
2018
- RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
2129
+ RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
2130
+ RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall,
2131
+ "invalid dst");
2019
2132
 
2020
- #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2021
- !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2022
- if ( !usePrefetchDecoder
2023
- && (!frame || (dctx->fParams.windowSize > (1<<24)))
2024
- && (nbSeq>ADVANCED_SEQS) ) { /* could probably use a larger nbSeq limit */
2025
- U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr);
2026
- U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
2027
- usePrefetchDecoder = (shareLongOffsets >= minShare);
2133
+ /* If we could potentially have long offsets, or we might want to use the prefetch decoder,
2134
+ * compute information about the share of long offsets, and the maximum nbAdditionalBits.
2135
+ * NOTE: could probably use a larger nbSeq limit
2136
+ */
2137
+ if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) {
2138
+ ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq);
2139
+ if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) {
2140
+ /* If isLongOffset, but the maximum number of additional bits that we see in our table is small
2141
+ * enough, then we know it is impossible to have too long an offset in this block, so we can
2142
+ * use the regular offset decoder.
2143
+ */
2144
+ isLongOffset = ZSTD_lo_isRegularOffset;
2145
+ }
2146
+ if (!usePrefetchDecoder) {
2147
+ U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
2148
+ usePrefetchDecoder = (info.longOffsetShare >= minShare);
2149
+ }
2028
2150
  }
2029
- #endif
2030
2151
 
2031
2152
  dctx->ddictIsCold = 0;
2032
2153
 
2033
2154
  #if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
2034
2155
  !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
2035
- if (usePrefetchDecoder)
2156
+ if (usePrefetchDecoder) {
2157
+ #else
2158
+ (void)usePrefetchDecoder;
2159
+ {
2036
2160
  #endif
2037
2161
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
2038
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2162
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2039
2163
  #endif
2164
+ }
2040
2165
 
2041
2166
  #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
2042
2167
  /* else */
2043
2168
  if (dctx->litBufferLocation == ZSTD_split)
2044
- return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2169
+ return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2045
2170
  else
2046
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset, frame);
2171
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
2047
2172
  #endif
2048
2173
  }
2049
2174
  }
2050
2175
 
2051
2176
 
2177
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
2052
2178
  void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
2053
2179
  {
2054
2180
  if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
@@ -2060,13 +2186,24 @@ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
2060
2186
  }
2061
2187
 
2062
2188
 
2063
- size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
2064
- void* dst, size_t dstCapacity,
2065
- const void* src, size_t srcSize)
2189
+ size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
2190
+ void* dst, size_t dstCapacity,
2191
+ const void* src, size_t srcSize)
2066
2192
  {
2067
2193
  size_t dSize;
2194
+ dctx->isFrameDecompression = 0;
2068
2195
  ZSTD_checkContinuity(dctx, dst, dstCapacity);
2069
- dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0, not_streaming);
2196
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming);
2197
+ FORWARD_IF_ERROR(dSize, "");
2070
2198
  dctx->previousDstEnd = (char*)dst + dSize;
2071
2199
  return dSize;
2072
2200
  }
2201
+
2202
+
2203
+ /* NOTE: Must just wrap ZSTD_decompressBlock_deprecated() */
2204
+ size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
2205
+ void* dst, size_t dstCapacity,
2206
+ const void* src, size_t srcSize)
2207
+ {
2208
+ return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize);
2209
+ }