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
@@ -56,13 +56,15 @@
56
56
  * Dependencies
57
57
  *********************************************************/
58
58
  #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
59
+ #include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
60
+ #include "../common/error_private.h"
61
+ #include "../common/zstd_internal.h" /* blockProperties_t */
59
62
  #include "../common/mem.h" /* low level memory routines */
63
+ #include "../common/bits.h" /* ZSTD_highbit32 */
60
64
  #define FSE_STATIC_LINKING_ONLY
61
65
  #include "../common/fse.h"
62
- #define HUF_STATIC_LINKING_ONLY
63
66
  #include "../common/huf.h"
64
67
  #include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
65
- #include "../common/zstd_internal.h" /* blockProperties_t */
66
68
  #include "zstd_decompress_internal.h" /* ZSTD_DCtx */
67
69
  #include "zstd_ddict.h" /* ZSTD_DDictDictContent */
68
70
  #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
@@ -78,11 +80,11 @@
78
80
  *************************************/
79
81
 
80
82
  #define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
81
- #define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
82
- * Currently, that means a 0.75 load factor.
83
- * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
84
- * the load factor of the ddict hash set.
85
- */
83
+ #define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3 /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
84
+ * Currently, that means a 0.75 load factor.
85
+ * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
86
+ * the load factor of the ddict hash set.
87
+ */
86
88
 
87
89
  #define DDICT_HASHSET_TABLE_BASE_SIZE 64
88
90
  #define DDICT_HASHSET_RESIZE_FACTOR 2
@@ -243,6 +245,8 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
243
245
  dctx->outBufferMode = ZSTD_bm_buffered;
244
246
  dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
245
247
  dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
248
+ dctx->disableHufAsm = 0;
249
+ dctx->maxBlockSizeParam = 0;
246
250
  }
247
251
 
248
252
  static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
@@ -263,6 +267,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
263
267
  #endif
264
268
  dctx->noForwardProgress = 0;
265
269
  dctx->oversizedDuration = 0;
270
+ dctx->isFrameDecompression = 1;
266
271
  #if DYNAMIC_BMI2
267
272
  dctx->bmi2 = ZSTD_cpuSupportsBmi2();
268
273
  #endif
@@ -438,16 +443,40 @@ size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
438
443
  * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
439
444
  * @return : 0, `zfhPtr` is correctly filled,
440
445
  * >0, `srcSize` is too small, value is wanted `srcSize` amount,
441
- * or an error code, which can be tested using ZSTD_isError() */
442
- size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
446
+ ** or an error code, which can be tested using ZSTD_isError() */
447
+ size_t ZSTD_getFrameHeader_advanced(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
443
448
  {
444
449
  const BYTE* ip = (const BYTE*)src;
445
450
  size_t const minInputSize = ZSTD_startingInputLength(format);
446
451
 
447
- ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
448
- if (srcSize < minInputSize) return minInputSize;
449
- RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
452
+ DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize);
450
453
 
454
+ if (srcSize > 0) {
455
+ /* note : technically could be considered an assert(), since it's an invalid entry */
456
+ RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0");
457
+ }
458
+ if (srcSize < minInputSize) {
459
+ if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) {
460
+ /* when receiving less than @minInputSize bytes,
461
+ * control these bytes at least correspond to a supported magic number
462
+ * in order to error out early if they don't.
463
+ **/
464
+ size_t const toCopy = MIN(4, srcSize);
465
+ unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER);
466
+ assert(src != NULL);
467
+ ZSTD_memcpy(hbuf, src, toCopy);
468
+ if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) {
469
+ /* not a zstd frame : let's check if it's a skippable frame */
470
+ MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START);
471
+ ZSTD_memcpy(hbuf, src, toCopy);
472
+ if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) {
473
+ RETURN_ERROR(prefix_unknown,
474
+ "first bytes don't correspond to any supported magic number");
475
+ } } }
476
+ return minInputSize;
477
+ }
478
+
479
+ ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */
451
480
  if ( (format != ZSTD_f_zstd1_magicless)
452
481
  && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
453
482
  if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
@@ -455,8 +484,10 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
455
484
  if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
456
485
  return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
457
486
  ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
458
- zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
459
487
  zfhPtr->frameType = ZSTD_skippableFrame;
488
+ zfhPtr->dictID = MEM_readLE32(src) - ZSTD_MAGIC_SKIPPABLE_START;
489
+ zfhPtr->headerSize = ZSTD_SKIPPABLEHEADERSIZE;
490
+ zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
460
491
  return 0;
461
492
  }
462
493
  RETURN_ERROR(prefix_unknown, "");
@@ -525,7 +556,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
525
556
  * @return : 0, `zfhPtr` is correctly filled,
526
557
  * >0, `srcSize` is too small, value is wanted `srcSize` amount,
527
558
  * or an error code, which can be tested using ZSTD_isError() */
528
- size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
559
+ size_t ZSTD_getFrameHeader(ZSTD_FrameHeader* zfhPtr, const void* src, size_t srcSize)
529
560
  {
530
561
  return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
531
562
  }
@@ -543,7 +574,7 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
543
574
  return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
544
575
  }
545
576
  #endif
546
- { ZSTD_frameHeader zfh;
577
+ { ZSTD_FrameHeader zfh;
547
578
  if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)
548
579
  return ZSTD_CONTENTSIZE_ERROR;
549
580
  if (zfh.frameType == ZSTD_skippableFrame) {
@@ -563,49 +594,52 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
563
594
  sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
564
595
  RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
565
596
  frameParameter_unsupported, "");
566
- {
567
- size_t const skippableSize = skippableHeaderSize + sizeU32;
597
+ { size_t const skippableSize = skippableHeaderSize + sizeU32;
568
598
  RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
569
599
  return skippableSize;
570
600
  }
571
601
  }
572
602
 
573
603
  /*! ZSTD_readSkippableFrame() :
574
- * Retrieves a zstd skippable frame containing data given by src, and writes it to dst buffer.
604
+ * Retrieves content of a skippable frame, and writes it to dst buffer.
575
605
  *
576
606
  * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
577
607
  * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START. This can be NULL if the caller is not interested
578
608
  * in the magicVariant.
579
609
  *
580
- * Returns an error if destination buffer is not large enough, or if the frame is not skippable.
610
+ * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame.
581
611
  *
582
612
  * @return : number of bytes written or a ZSTD error.
583
613
  */
584
- ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsigned* magicVariant,
585
- const void* src, size_t srcSize)
614
+ size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
615
+ unsigned* magicVariant, /* optional, can be NULL */
616
+ const void* src, size_t srcSize)
586
617
  {
587
- U32 const magicNumber = MEM_readLE32(src);
588
- size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
589
- size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
590
-
591
- /* check input validity */
592
- RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
593
- RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
594
- RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
618
+ RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
595
619
 
596
- /* deliver payload */
597
- if (skippableContentSize > 0 && dst != NULL)
598
- ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
599
- if (magicVariant != NULL)
600
- *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
601
- return skippableContentSize;
620
+ { U32 const magicNumber = MEM_readLE32(src);
621
+ size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
622
+ size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
623
+
624
+ /* check input validity */
625
+ RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
626
+ RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
627
+ RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
628
+
629
+ /* deliver payload */
630
+ if (skippableContentSize > 0 && dst != NULL)
631
+ ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
632
+ if (magicVariant != NULL)
633
+ *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
634
+ return skippableContentSize;
635
+ }
602
636
  }
603
637
 
604
638
  /** ZSTD_findDecompressedSize() :
605
- * compatible with legacy mode
606
639
  * `srcSize` must be the exact length of some number of ZSTD compressed and/or
607
640
  * skippable frames
608
- * @return : decompressed size of the frames contained */
641
+ * note: compatible with legacy mode
642
+ * @return : decompressed size of the frames contained */
609
643
  unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
610
644
  {
611
645
  unsigned long long totalDstSize = 0;
@@ -615,9 +649,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
615
649
 
616
650
  if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
617
651
  size_t const skippableSize = readSkippableFrameSize(src, srcSize);
618
- if (ZSTD_isError(skippableSize)) {
619
- return ZSTD_CONTENTSIZE_ERROR;
620
- }
652
+ if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR;
621
653
  assert(skippableSize <= srcSize);
622
654
 
623
655
  src = (const BYTE *)src + skippableSize;
@@ -625,17 +657,17 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
625
657
  continue;
626
658
  }
627
659
 
628
- { unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
629
- if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
660
+ { unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize);
661
+ if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs;
630
662
 
631
- /* check for overflow */
632
- if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
633
- totalDstSize += ret;
663
+ if (totalDstSize + fcs < totalDstSize)
664
+ return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */
665
+ totalDstSize += fcs;
634
666
  }
667
+ /* skip to next frame */
635
668
  { size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
636
- if (ZSTD_isError(frameSrcSize)) {
637
- return ZSTD_CONTENTSIZE_ERROR;
638
- }
669
+ if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR;
670
+ assert(frameSrcSize <= srcSize);
639
671
 
640
672
  src = (const BYTE *)src + frameSrcSize;
641
673
  srcSize -= frameSrcSize;
@@ -699,17 +731,17 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
699
731
  return frameSizeInfo;
700
732
  }
701
733
 
702
- static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
734
+ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format)
703
735
  {
704
736
  ZSTD_frameSizeInfo frameSizeInfo;
705
737
  ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
706
738
 
707
739
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
708
- if (ZSTD_isLegacy(src, srcSize))
740
+ if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize))
709
741
  return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
710
742
  #endif
711
743
 
712
- if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
744
+ if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
713
745
  && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
714
746
  frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
715
747
  assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
@@ -720,10 +752,10 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
720
752
  const BYTE* const ipstart = ip;
721
753
  size_t remainingSize = srcSize;
722
754
  size_t nbBlocks = 0;
723
- ZSTD_frameHeader zfh;
755
+ ZSTD_FrameHeader zfh;
724
756
 
725
757
  /* Extract Frame Header */
726
- { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
758
+ { size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format);
727
759
  if (ZSTD_isError(ret))
728
760
  return ZSTD_errorFrameSizeInfo(ret);
729
761
  if (ret > 0)
@@ -757,28 +789,31 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
757
789
  ip += 4;
758
790
  }
759
791
 
792
+ frameSizeInfo.nbBlocks = nbBlocks;
760
793
  frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
761
794
  frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
762
795
  ? zfh.frameContentSize
763
- : nbBlocks * zfh.blockSizeMax;
796
+ : (unsigned long long)nbBlocks * zfh.blockSizeMax;
764
797
  return frameSizeInfo;
765
798
  }
766
799
  }
767
800
 
801
+ static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) {
802
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format);
803
+ return frameSizeInfo.compressedSize;
804
+ }
805
+
768
806
  /** ZSTD_findFrameCompressedSize() :
769
- * compatible with legacy mode
770
- * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
771
- * `srcSize` must be at least as large as the frame contained
772
- * @return : the compressed size of the frame starting at `src` */
807
+ * See docs in zstd.h
808
+ * Note: compatible with legacy mode */
773
809
  size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
774
810
  {
775
- ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
776
- return frameSizeInfo.compressedSize;
811
+ return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1);
777
812
  }
778
813
 
779
814
  /** ZSTD_decompressBound() :
780
815
  * compatible with legacy mode
781
- * `src` must point to the start of a ZSTD frame or a skippeable frame
816
+ * `src` must point to the start of a ZSTD frame or a skippable frame
782
817
  * `srcSize` must be at least as large as the frame contained
783
818
  * @return : the maximum decompressed size of the compressed source
784
819
  */
@@ -787,7 +822,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
787
822
  unsigned long long bound = 0;
788
823
  /* Iterate over each frame */
789
824
  while (srcSize > 0) {
790
- ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
825
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
791
826
  size_t const compressedSize = frameSizeInfo.compressedSize;
792
827
  unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
793
828
  if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
@@ -800,6 +835,48 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
800
835
  return bound;
801
836
  }
802
837
 
838
+ size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
839
+ {
840
+ size_t margin = 0;
841
+ unsigned maxBlockSize = 0;
842
+
843
+ /* Iterate over each frame */
844
+ while (srcSize > 0) {
845
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
846
+ size_t const compressedSize = frameSizeInfo.compressedSize;
847
+ unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
848
+ ZSTD_FrameHeader zfh;
849
+
850
+ FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), "");
851
+ if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
852
+ return ERROR(corruption_detected);
853
+
854
+ if (zfh.frameType == ZSTD_frame) {
855
+ /* Add the frame header to our margin */
856
+ margin += zfh.headerSize;
857
+ /* Add the checksum to our margin */
858
+ margin += zfh.checksumFlag ? 4 : 0;
859
+ /* Add 3 bytes per block */
860
+ margin += 3 * frameSizeInfo.nbBlocks;
861
+
862
+ /* Compute the max block size */
863
+ maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax);
864
+ } else {
865
+ assert(zfh.frameType == ZSTD_skippableFrame);
866
+ /* Add the entire skippable frame size to our margin. */
867
+ margin += compressedSize;
868
+ }
869
+
870
+ assert(srcSize >= compressedSize);
871
+ src = (const BYTE*)src + compressedSize;
872
+ srcSize -= compressedSize;
873
+ }
874
+
875
+ /* Add the max block size back to the margin. */
876
+ margin += maxBlockSize;
877
+
878
+ return margin;
879
+ }
803
880
 
804
881
  /*-*************************************************************
805
882
  * Frame decoding
@@ -825,7 +902,7 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
825
902
  if (srcSize == 0) return 0;
826
903
  RETURN_ERROR(dstBuffer_null, "");
827
904
  }
828
- ZSTD_memcpy(dst, src, srcSize);
905
+ ZSTD_memmove(dst, src, srcSize);
829
906
  return srcSize;
830
907
  }
831
908
 
@@ -842,7 +919,7 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
842
919
  return regenSize;
843
920
  }
844
921
 
845
- static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
922
+ static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, int streaming)
846
923
  {
847
924
  #if ZSTD_TRACE
848
925
  if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) {
@@ -901,8 +978,13 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
901
978
  ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
902
979
  }
903
980
 
981
+ /* Shrink the blockSizeMax if enabled */
982
+ if (dctx->maxBlockSizeParam != 0)
983
+ dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam);
984
+
904
985
  /* Loop on each block */
905
986
  while (1) {
987
+ BYTE* oBlockEnd = oend;
906
988
  size_t decodedSize;
907
989
  blockProperties_t blockProperties;
908
990
  size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
@@ -912,27 +994,48 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
912
994
  remainingSrcSize -= ZSTD_blockHeaderSize;
913
995
  RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
914
996
 
997
+ if (ip >= op && ip < oBlockEnd) {
998
+ /* We are decompressing in-place. Limit the output pointer so that we
999
+ * don't overwrite the block that we are currently reading. This will
1000
+ * fail decompression if the input & output pointers aren't spaced
1001
+ * far enough apart.
1002
+ *
1003
+ * This is important to set, even when the pointers are far enough
1004
+ * apart, because ZSTD_decompressBlock_internal() can decide to store
1005
+ * literals in the output buffer, after the block it is decompressing.
1006
+ * Since we don't want anything to overwrite our input, we have to tell
1007
+ * ZSTD_decompressBlock_internal to never write past ip.
1008
+ *
1009
+ * See ZSTD_allocateLiteralsBuffer() for reference.
1010
+ */
1011
+ oBlockEnd = op + (ip - op);
1012
+ }
1013
+
915
1014
  switch(blockProperties.blockType)
916
1015
  {
917
1016
  case bt_compressed:
918
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oend-op), ip, cBlockSize, /* frame */ 1, not_streaming);
1017
+ assert(dctx->isFrameDecompression == 1);
1018
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming);
919
1019
  break;
920
1020
  case bt_raw :
1021
+ /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
921
1022
  decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
922
1023
  break;
923
1024
  case bt_rle :
924
- decodedSize = ZSTD_setRleBlock(op, (size_t)(oend-op), *ip, blockProperties.origSize);
1025
+ decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
925
1026
  break;
926
1027
  case bt_reserved :
927
1028
  default:
928
1029
  RETURN_ERROR(corruption_detected, "invalid block type");
929
1030
  }
930
-
931
- if (ZSTD_isError(decodedSize)) return decodedSize;
932
- if (dctx->validateChecksum)
1031
+ FORWARD_IF_ERROR(decodedSize, "Block decompression failure");
1032
+ DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize);
1033
+ if (dctx->validateChecksum) {
933
1034
  XXH64_update(&dctx->xxhState, op, decodedSize);
934
- if (decodedSize != 0)
1035
+ }
1036
+ if (decodedSize) /* support dst = NULL,0 */ {
935
1037
  op += decodedSize;
1038
+ }
936
1039
  assert(ip != NULL);
937
1040
  ip += cBlockSize;
938
1041
  remainingSrcSize -= cBlockSize;
@@ -956,12 +1059,15 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
956
1059
  }
957
1060
  ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
958
1061
  /* Allow caller to get size read */
1062
+ DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %i, consuming %i bytes of input", (int)(op-ostart), (int)(ip - (const BYTE*)*srcPtr));
959
1063
  *srcPtr = ip;
960
1064
  *srcSizePtr = remainingSrcSize;
961
1065
  return (size_t)(op-ostart);
962
1066
  }
963
1067
 
964
- static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1068
+ static
1069
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
1070
+ size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
965
1071
  void* dst, size_t dstCapacity,
966
1072
  const void* src, size_t srcSize,
967
1073
  const void* dict, size_t dictSize,
@@ -981,7 +1087,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
981
1087
  while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
982
1088
 
983
1089
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
984
- if (ZSTD_isLegacy(src, srcSize)) {
1090
+ if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) {
985
1091
  size_t decodedSize;
986
1092
  size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
987
1093
  if (ZSTD_isError(frameSize)) return frameSize;
@@ -991,6 +1097,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
991
1097
  decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
992
1098
  if (ZSTD_isError(decodedSize)) return decodedSize;
993
1099
 
1100
+ {
1101
+ unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize);
1102
+ RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!");
1103
+ if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1104
+ RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected,
1105
+ "Frame header size does not match decoded size!");
1106
+ }
1107
+ }
1108
+
994
1109
  assert(decodedSize <= dstCapacity);
995
1110
  dst = (BYTE*)dst + decodedSize;
996
1111
  dstCapacity -= decodedSize;
@@ -1002,17 +1117,18 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1002
1117
  }
1003
1118
  #endif
1004
1119
 
1005
- { U32 const magicNumber = MEM_readLE32(src);
1006
- DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1007
- (unsigned)magicNumber, ZSTD_MAGICNUMBER);
1120
+ if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) {
1121
+ U32 const magicNumber = MEM_readLE32(src);
1122
+ DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
1008
1123
  if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
1124
+ /* skippable frame detected : skip it */
1009
1125
  size_t const skippableSize = readSkippableFrameSize(src, srcSize);
1010
- FORWARD_IF_ERROR(skippableSize, "readSkippableFrameSize failed");
1126
+ FORWARD_IF_ERROR(skippableSize, "invalid skippable frame");
1011
1127
  assert(skippableSize <= srcSize);
1012
1128
 
1013
1129
  src = (const BYTE *)src + skippableSize;
1014
1130
  srcSize -= skippableSize;
1015
- continue;
1131
+ continue; /* check next frame */
1016
1132
  } }
1017
1133
 
1018
1134
  if (ddict) {
@@ -1108,8 +1224,8 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
1108
1224
  size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
1109
1225
 
1110
1226
  /**
1111
- * Similar to ZSTD_nextSrcSizeToDecompress(), but when when a block input can be streamed,
1112
- * we allow taking a partial block as the input. Currently only raw uncompressed blocks can
1227
+ * Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we
1228
+ * allow taking a partial block as the input. Currently only raw uncompressed blocks can
1113
1229
  * be streamed.
1114
1230
  *
1115
1231
  * For blocks that can be streamed, this allows us to reduce the latency until we produce
@@ -1228,7 +1344,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1228
1344
  {
1229
1345
  case bt_compressed:
1230
1346
  DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
1231
- rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming);
1347
+ assert(dctx->isFrameDecompression == 1);
1348
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming);
1232
1349
  dctx->expected = 0; /* Streaming not supported */
1233
1350
  break;
1234
1351
  case bt_raw :
@@ -1297,6 +1414,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1297
1414
  case ZSTDds_decodeSkippableHeader:
1298
1415
  assert(src != NULL);
1299
1416
  assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
1417
+ assert(dctx->format != ZSTD_f_zstd1_magicless);
1300
1418
  ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
1301
1419
  dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
1302
1420
  dctx->stage = ZSTDds_skipFrame;
@@ -1309,7 +1427,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1309
1427
 
1310
1428
  default:
1311
1429
  assert(0); /* impossible */
1312
- RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
1430
+ RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
1313
1431
  }
1314
1432
  }
1315
1433
 
@@ -1350,11 +1468,11 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
1350
1468
  /* in minimal huffman, we always use X1 variants */
1351
1469
  size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
1352
1470
  dictPtr, dictEnd - dictPtr,
1353
- workspace, workspaceSize);
1471
+ workspace, workspaceSize, /* flags */ 0);
1354
1472
  #else
1355
1473
  size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
1356
1474
  dictPtr, (size_t)(dictEnd - dictPtr),
1357
- workspace, workspaceSize);
1475
+ workspace, workspaceSize, /* flags */ 0);
1358
1476
  #endif
1359
1477
  RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
1360
1478
  dictPtr += hSize;
@@ -1453,10 +1571,11 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1453
1571
  dctx->prefixStart = NULL;
1454
1572
  dctx->virtualStart = NULL;
1455
1573
  dctx->dictEnd = NULL;
1456
- dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
1574
+ dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001); /* cover both little and big endian */
1457
1575
  dctx->litEntropy = dctx->fseEntropy = 0;
1458
1576
  dctx->dictID = 0;
1459
1577
  dctx->bType = bt_reserved;
1578
+ dctx->isFrameDecompression = 1;
1460
1579
  ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
1461
1580
  ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
1462
1581
  dctx->LLTptr = dctx->entropy.LLTable;
@@ -1515,7 +1634,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
1515
1634
  * This could for one of the following reasons :
1516
1635
  * - The frame does not require a dictionary (most common case).
1517
1636
  * - The frame was built with dictID intentionally removed.
1518
- * Needed dictionary is a hidden information.
1637
+ * Needed dictionary is a hidden piece of information.
1519
1638
  * Note : this use case also happens when using a non-conformant dictionary.
1520
1639
  * - `srcSize` is too small, and as a result, frame header could not be decoded.
1521
1640
  * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
@@ -1524,7 +1643,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
1524
1643
  * ZSTD_getFrameHeader(), which will provide a more precise error code. */
1525
1644
  unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
1526
1645
  {
1527
- ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };
1646
+ ZSTD_FrameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
1528
1647
  size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
1529
1648
  if (ZSTD_isError(hError)) return 0;
1530
1649
  return zfp.dictID;
@@ -1631,7 +1750,9 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
1631
1750
  size_t ZSTD_initDStream(ZSTD_DStream* zds)
1632
1751
  {
1633
1752
  DEBUGLOG(4, "ZSTD_initDStream");
1634
- return ZSTD_initDStream_usingDDict(zds, NULL);
1753
+ FORWARD_IF_ERROR(ZSTD_DCtx_reset(zds, ZSTD_reset_session_only), "");
1754
+ FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), "");
1755
+ return ZSTD_startingInputLength(zds->format);
1635
1756
  }
1636
1757
 
1637
1758
  /* ZSTD_initDStream_usingDDict() :
@@ -1639,6 +1760,7 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
1639
1760
  * this function cannot fail */
1640
1761
  size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
1641
1762
  {
1763
+ DEBUGLOG(4, "ZSTD_initDStream_usingDDict");
1642
1764
  FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
1643
1765
  FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
1644
1766
  return ZSTD_startingInputLength(dctx->format);
@@ -1649,6 +1771,7 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
1649
1771
  * this function cannot fail */
1650
1772
  size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
1651
1773
  {
1774
+ DEBUGLOG(4, "ZSTD_resetDStream");
1652
1775
  FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
1653
1776
  return ZSTD_startingInputLength(dctx->format);
1654
1777
  }
@@ -1720,6 +1843,15 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
1720
1843
  bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
1721
1844
  bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
1722
1845
  return bounds;
1846
+ case ZSTD_d_disableHuffmanAssembly:
1847
+ bounds.lowerBound = 0;
1848
+ bounds.upperBound = 1;
1849
+ return bounds;
1850
+ case ZSTD_d_maxBlockSize:
1851
+ bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
1852
+ bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
1853
+ return bounds;
1854
+
1723
1855
  default:;
1724
1856
  }
1725
1857
  bounds.error = ERROR(parameter_unsupported);
@@ -1760,6 +1892,12 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value
1760
1892
  case ZSTD_d_refMultipleDDicts:
1761
1893
  *value = (int)dctx->refMultipleDDicts;
1762
1894
  return 0;
1895
+ case ZSTD_d_disableHuffmanAssembly:
1896
+ *value = (int)dctx->disableHufAsm;
1897
+ return 0;
1898
+ case ZSTD_d_maxBlockSize:
1899
+ *value = dctx->maxBlockSizeParam;
1900
+ return 0;
1763
1901
  default:;
1764
1902
  }
1765
1903
  RETURN_ERROR(parameter_unsupported, "");
@@ -1793,6 +1931,14 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
1793
1931
  }
1794
1932
  dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
1795
1933
  return 0;
1934
+ case ZSTD_d_disableHuffmanAssembly:
1935
+ CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
1936
+ dctx->disableHufAsm = value != 0;
1937
+ return 0;
1938
+ case ZSTD_d_maxBlockSize:
1939
+ if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value);
1940
+ dctx->maxBlockSizeParam = value;
1941
+ return 0;
1796
1942
  default:;
1797
1943
  }
1798
1944
  RETURN_ERROR(parameter_unsupported, "");
@@ -1804,6 +1950,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
1804
1950
  || (reset == ZSTD_reset_session_and_parameters) ) {
1805
1951
  dctx->streamStage = zdss_init;
1806
1952
  dctx->noForwardProgress = 0;
1953
+ dctx->isFrameDecompression = 1;
1807
1954
  }
1808
1955
  if ( (reset == ZSTD_reset_parameters)
1809
1956
  || (reset == ZSTD_reset_session_and_parameters) ) {
@@ -1820,11 +1967,17 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
1820
1967
  return ZSTD_sizeof_DCtx(dctx);
1821
1968
  }
1822
1969
 
1823
- size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1970
+ static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax)
1824
1971
  {
1825
- size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
1826
- /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/
1827
- unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2);
1972
+ size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax);
1973
+ /* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block
1974
+ * ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing
1975
+ * the block at the beginning of the output buffer, and maintain a full window.
1976
+ *
1977
+ * We need another blockSize worth of buffer so that we can store split
1978
+ * literals at the end of the block without overwriting the extDict window.
1979
+ */
1980
+ unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2);
1828
1981
  unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
1829
1982
  size_t const minRBSize = (size_t) neededSize;
1830
1983
  RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
@@ -1832,6 +1985,11 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
1832
1985
  return minRBSize;
1833
1986
  }
1834
1987
 
1988
+ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1989
+ {
1990
+ return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX);
1991
+ }
1992
+
1835
1993
  size_t ZSTD_estimateDStreamSize(size_t windowSize)
1836
1994
  {
1837
1995
  size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
@@ -1843,7 +2001,7 @@ size_t ZSTD_estimateDStreamSize(size_t windowSize)
1843
2001
  size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
1844
2002
  {
1845
2003
  U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
1846
- ZSTD_frameHeader zfh;
2004
+ ZSTD_FrameHeader zfh;
1847
2005
  size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
1848
2006
  if (ZSTD_isError(err)) return err;
1849
2007
  RETURN_ERROR_IF(err>0, srcSize_wrong, "");
@@ -1938,6 +2096,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
1938
2096
  U32 someMoreWork = 1;
1939
2097
 
1940
2098
  DEBUGLOG(5, "ZSTD_decompressStream");
2099
+ assert(zds != NULL);
1941
2100
  RETURN_ERROR_IF(
1942
2101
  input->pos > input->size,
1943
2102
  srcSize_wrong,
@@ -1980,7 +2139,6 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
1980
2139
  if (zds->refMultipleDDicts && zds->ddictSet) {
1981
2140
  ZSTD_DCtx_selectFrameDDict(zds);
1982
2141
  }
1983
- DEBUGLOG(5, "header size : %u", (U32)hSize);
1984
2142
  if (ZSTD_isError(hSize)) {
1985
2143
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1986
2144
  U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
@@ -2012,6 +2170,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2012
2170
  zds->lhSize += remainingInput;
2013
2171
  }
2014
2172
  input->pos = input->size;
2173
+ /* check first few bytes */
2174
+ FORWARD_IF_ERROR(
2175
+ ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format),
2176
+ "First few bytes detected incorrect" );
2177
+ /* return hint input size */
2015
2178
  return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
2016
2179
  }
2017
2180
  assert(ip != NULL);
@@ -2023,14 +2186,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2023
2186
  if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2024
2187
  && zds->fParams.frameType != ZSTD_skippableFrame
2025
2188
  && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
2026
- size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart));
2189
+ size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format);
2027
2190
  if (cSize <= (size_t)(iend-istart)) {
2028
2191
  /* shortcut : using single-pass mode */
2029
2192
  size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
2030
2193
  if (ZSTD_isError(decompressedSize)) return decompressedSize;
2031
- DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
2194
+ DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()");
2195
+ assert(istart != NULL);
2032
2196
  ip = istart + cSize;
2033
- op += decompressedSize;
2197
+ op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
2034
2198
  zds->expected = 0;
2035
2199
  zds->streamStage = zdss_init;
2036
2200
  someMoreWork = 0;
@@ -2049,7 +2213,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2049
2213
  DEBUGLOG(4, "Consume header");
2050
2214
  FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
2051
2215
 
2052
- if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2216
+ if (zds->format == ZSTD_f_zstd1
2217
+ && (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2053
2218
  zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
2054
2219
  zds->stage = ZSTDds_skipFrame;
2055
2220
  } else {
@@ -2065,11 +2230,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2065
2230
  zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2066
2231
  RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
2067
2232
  frameParameter_windowTooLarge, "");
2233
+ if (zds->maxBlockSizeParam != 0)
2234
+ zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam);
2068
2235
 
2069
2236
  /* Adapt buffer sizes to frame header instructions */
2070
2237
  { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
2071
2238
  size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
2072
- ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
2239
+ ? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax)
2073
2240
  : 0;
2074
2241
 
2075
2242
  ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
@@ -2114,6 +2281,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2114
2281
  }
2115
2282
  if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
2116
2283
  FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
2284
+ assert(ip != NULL);
2117
2285
  ip += neededInSize;
2118
2286
  /* Function modifies the stage so we must break */
2119
2287
  break;
@@ -2128,7 +2296,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2128
2296
  int const isSkipFrame = ZSTD_isSkipFrame(zds);
2129
2297
  size_t loadedSize;
2130
2298
  /* At this point we shouldn't be decompressing a block that we can stream. */
2131
- assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, iend - ip));
2299
+ assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)));
2132
2300
  if (isSkipFrame) {
2133
2301
  loadedSize = MIN(toLoad, (size_t)(iend-ip));
2134
2302
  } else {
@@ -2137,8 +2305,11 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2137
2305
  "should never happen");
2138
2306
  loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
2139
2307
  }
2140
- ip += loadedSize;
2141
- zds->inPos += loadedSize;
2308
+ if (loadedSize != 0) {
2309
+ /* ip may be NULL */
2310
+ ip += loadedSize;
2311
+ zds->inPos += loadedSize;
2312
+ }
2142
2313
  if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
2143
2314
 
2144
2315
  /* decode loaded input */
@@ -2148,14 +2319,17 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2148
2319
  break;
2149
2320
  }
2150
2321
  case zdss_flush:
2151
- { size_t const toFlushSize = zds->outEnd - zds->outStart;
2322
+ {
2323
+ size_t const toFlushSize = zds->outEnd - zds->outStart;
2152
2324
  size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
2153
- op += flushedSize;
2325
+
2326
+ op = op ? op + flushedSize : op;
2327
+
2154
2328
  zds->outStart += flushedSize;
2155
2329
  if (flushedSize == toFlushSize) { /* flush completed */
2156
2330
  zds->streamStage = zdss_read;
2157
2331
  if ( (zds->outBuffSize < zds->fParams.frameContentSize)
2158
- && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
2332
+ && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
2159
2333
  DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
2160
2334
  (int)(zds->outBuffSize - zds->outStart),
2161
2335
  (U32)zds->fParams.blockSizeMax);
@@ -2169,7 +2343,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2169
2343
 
2170
2344
  default:
2171
2345
  assert(0); /* impossible */
2172
- RETURN_ERROR(GENERIC, "impossible to reach"); /* some compiler require default to do something */
2346
+ RETURN_ERROR(GENERIC, "impossible to reach"); /* some compilers require default to do something */
2173
2347
  } }
2174
2348
 
2175
2349
  /* result */
@@ -2182,8 +2356,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2182
2356
  if ((ip==istart) && (op==ostart)) { /* no forward progress */
2183
2357
  zds->noForwardProgress ++;
2184
2358
  if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
2185
- RETURN_ERROR_IF(op==oend, dstSize_tooSmall, "");
2186
- RETURN_ERROR_IF(ip==iend, srcSize_wrong, "");
2359
+ RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, "");
2360
+ RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, "");
2187
2361
  assert(0);
2188
2362
  }
2189
2363
  } else {
@@ -2220,11 +2394,17 @@ size_t ZSTD_decompressStream_simpleArgs (
2220
2394
  void* dst, size_t dstCapacity, size_t* dstPos,
2221
2395
  const void* src, size_t srcSize, size_t* srcPos)
2222
2396
  {
2223
- ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
2224
- ZSTD_inBuffer input = { src, srcSize, *srcPos };
2225
- /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
2226
- size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
2227
- *dstPos = output.pos;
2228
- *srcPos = input.pos;
2229
- return cErr;
2397
+ ZSTD_outBuffer output;
2398
+ ZSTD_inBuffer input;
2399
+ output.dst = dst;
2400
+ output.size = dstCapacity;
2401
+ output.pos = *dstPos;
2402
+ input.src = src;
2403
+ input.size = srcSize;
2404
+ input.pos = *srcPos;
2405
+ { size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
2406
+ *dstPos = output.pos;
2407
+ *srcPos = input.pos;
2408
+ return cErr;
2409
+ }
2230
2410
  }