extzstd 0.1 → 0.3.2

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 (134) hide show
  1. checksums.yaml +5 -5
  2. data/HISTORY.ja.md +39 -0
  3. data/README.md +38 -56
  4. data/contrib/zstd/CHANGELOG +613 -0
  5. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  6. data/contrib/zstd/CONTRIBUTING.md +406 -0
  7. data/contrib/zstd/COPYING +339 -0
  8. data/contrib/zstd/Makefile +420 -0
  9. data/contrib/zstd/README.md +179 -41
  10. data/contrib/zstd/TESTING.md +44 -0
  11. data/contrib/zstd/appveyor.yml +292 -0
  12. data/contrib/zstd/lib/BUCK +234 -0
  13. data/contrib/zstd/lib/Makefile +451 -0
  14. data/contrib/zstd/lib/README.md +207 -0
  15. data/contrib/zstd/{common → lib/common}/bitstream.h +187 -138
  16. data/contrib/zstd/lib/common/compiler.h +288 -0
  17. data/contrib/zstd/lib/common/cpu.h +213 -0
  18. data/contrib/zstd/lib/common/debug.c +24 -0
  19. data/contrib/zstd/lib/common/debug.h +107 -0
  20. data/contrib/zstd/lib/common/entropy_common.c +362 -0
  21. data/contrib/zstd/{common → lib/common}/error_private.c +25 -12
  22. data/contrib/zstd/{common → lib/common}/error_private.h +14 -10
  23. data/contrib/zstd/{common → lib/common}/fse.h +173 -92
  24. data/contrib/zstd/{common → lib/common}/fse_decompress.c +149 -85
  25. data/contrib/zstd/lib/common/huf.h +361 -0
  26. data/contrib/zstd/{common → lib/common}/mem.h +115 -59
  27. data/contrib/zstd/lib/common/pool.c +350 -0
  28. data/contrib/zstd/lib/common/pool.h +84 -0
  29. data/contrib/zstd/lib/common/threading.c +122 -0
  30. data/contrib/zstd/lib/common/threading.h +155 -0
  31. data/contrib/zstd/{common → lib/common}/xxhash.c +55 -96
  32. data/contrib/zstd/{common → lib/common}/xxhash.h +23 -47
  33. data/contrib/zstd/lib/common/zstd_common.c +83 -0
  34. data/contrib/zstd/lib/common/zstd_deps.h +111 -0
  35. data/contrib/zstd/lib/common/zstd_errors.h +95 -0
  36. data/contrib/zstd/lib/common/zstd_internal.h +478 -0
  37. data/contrib/zstd/{compress → lib/compress}/fse_compress.c +214 -319
  38. data/contrib/zstd/lib/compress/hist.c +181 -0
  39. data/contrib/zstd/lib/compress/hist.h +75 -0
  40. data/contrib/zstd/lib/compress/huf_compress.c +913 -0
  41. data/contrib/zstd/lib/compress/zstd_compress.c +5208 -0
  42. data/contrib/zstd/lib/compress/zstd_compress_internal.h +1203 -0
  43. data/contrib/zstd/lib/compress/zstd_compress_literals.c +158 -0
  44. data/contrib/zstd/lib/compress/zstd_compress_literals.h +29 -0
  45. data/contrib/zstd/lib/compress/zstd_compress_sequences.c +433 -0
  46. data/contrib/zstd/lib/compress/zstd_compress_sequences.h +54 -0
  47. data/contrib/zstd/lib/compress/zstd_compress_superblock.c +849 -0
  48. data/contrib/zstd/lib/compress/zstd_compress_superblock.h +32 -0
  49. data/contrib/zstd/lib/compress/zstd_cwksp.h +561 -0
  50. data/contrib/zstd/lib/compress/zstd_double_fast.c +521 -0
  51. data/contrib/zstd/lib/compress/zstd_double_fast.h +38 -0
  52. data/contrib/zstd/lib/compress/zstd_fast.c +496 -0
  53. data/contrib/zstd/lib/compress/zstd_fast.h +37 -0
  54. data/contrib/zstd/lib/compress/zstd_lazy.c +1412 -0
  55. data/contrib/zstd/lib/compress/zstd_lazy.h +87 -0
  56. data/contrib/zstd/lib/compress/zstd_ldm.c +660 -0
  57. data/contrib/zstd/lib/compress/zstd_ldm.h +116 -0
  58. data/contrib/zstd/lib/compress/zstd_opt.c +1345 -0
  59. data/contrib/zstd/lib/compress/zstd_opt.h +56 -0
  60. data/contrib/zstd/lib/compress/zstdmt_compress.c +1811 -0
  61. data/contrib/zstd/lib/compress/zstdmt_compress.h +110 -0
  62. data/contrib/zstd/lib/decompress/huf_decompress.c +1350 -0
  63. data/contrib/zstd/lib/decompress/zstd_ddict.c +244 -0
  64. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  65. data/contrib/zstd/lib/decompress/zstd_decompress.c +1930 -0
  66. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1540 -0
  67. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +62 -0
  68. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +190 -0
  69. data/contrib/zstd/{common → lib/deprecated}/zbuff.h +68 -45
  70. data/contrib/zstd/lib/deprecated/zbuff_common.c +26 -0
  71. data/contrib/zstd/lib/deprecated/zbuff_compress.c +147 -0
  72. data/contrib/zstd/lib/deprecated/zbuff_decompress.c +75 -0
  73. data/contrib/zstd/lib/dictBuilder/cover.c +1245 -0
  74. data/contrib/zstd/lib/dictBuilder/cover.h +157 -0
  75. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.c +3 -3
  76. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/divsufsort.h +0 -0
  77. data/contrib/zstd/lib/dictBuilder/fastcover.c +758 -0
  78. data/contrib/zstd/{dictBuilder → lib/dictBuilder}/zdict.c +318 -194
  79. data/contrib/zstd/lib/dictBuilder/zdict.h +305 -0
  80. data/contrib/zstd/{legacy → lib/legacy}/zstd_legacy.h +171 -15
  81. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.c +191 -124
  82. data/contrib/zstd/{legacy → lib/legacy}/zstd_v01.h +19 -5
  83. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.c +125 -125
  84. data/contrib/zstd/{legacy → lib/legacy}/zstd_v02.h +19 -5
  85. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.c +125 -124
  86. data/contrib/zstd/{legacy → lib/legacy}/zstd_v03.h +20 -6
  87. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.c +151 -299
  88. data/contrib/zstd/{legacy → lib/legacy}/zstd_v04.h +19 -5
  89. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.c +237 -243
  90. data/contrib/zstd/{legacy → lib/legacy}/zstd_v05.h +19 -6
  91. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.c +130 -143
  92. data/contrib/zstd/{legacy → lib/legacy}/zstd_v06.h +18 -5
  93. data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.c +158 -157
  94. data/contrib/zstd/{legacy → lib/legacy}/zstd_v07.h +19 -5
  95. data/contrib/zstd/lib/libzstd.pc.in +15 -0
  96. data/contrib/zstd/lib/zstd.h +2391 -0
  97. data/ext/depend +2 -0
  98. data/ext/extconf.rb +15 -6
  99. data/ext/extzstd.c +76 -145
  100. data/ext/extzstd.h +80 -31
  101. data/ext/extzstd_stream.c +417 -142
  102. data/ext/libzstd_conf.h +8 -0
  103. data/ext/zstd_common.c +10 -7
  104. data/ext/zstd_compress.c +14 -5
  105. data/ext/zstd_decompress.c +5 -4
  106. data/ext/zstd_dictbuilder.c +9 -4
  107. data/ext/zstd_dictbuilder_fastcover.c +3 -0
  108. data/ext/zstd_legacy_v01.c +3 -1
  109. data/ext/zstd_legacy_v02.c +3 -1
  110. data/ext/zstd_legacy_v03.c +3 -1
  111. data/ext/zstd_legacy_v04.c +3 -1
  112. data/ext/zstd_legacy_v05.c +3 -1
  113. data/ext/zstd_legacy_v06.c +3 -1
  114. data/ext/zstd_legacy_v07.c +3 -1
  115. data/gemstub.rb +10 -24
  116. data/lib/extzstd.rb +64 -179
  117. data/lib/extzstd/version.rb +6 -1
  118. data/test/test_basic.rb +9 -6
  119. metadata +113 -57
  120. data/HISTORY.ja +0 -5
  121. data/contrib/zstd/common/entropy_common.c +0 -225
  122. data/contrib/zstd/common/huf.h +0 -228
  123. data/contrib/zstd/common/zstd_common.c +0 -83
  124. data/contrib/zstd/common/zstd_errors.h +0 -60
  125. data/contrib/zstd/common/zstd_internal.h +0 -267
  126. data/contrib/zstd/compress/huf_compress.c +0 -533
  127. data/contrib/zstd/compress/zbuff_compress.c +0 -319
  128. data/contrib/zstd/compress/zstd_compress.c +0 -3264
  129. data/contrib/zstd/compress/zstd_opt.h +0 -900
  130. data/contrib/zstd/decompress/huf_decompress.c +0 -883
  131. data/contrib/zstd/decompress/zbuff_decompress.c +0 -252
  132. data/contrib/zstd/decompress/zstd_decompress.c +0 -1842
  133. data/contrib/zstd/dictBuilder/zdict.h +0 -111
  134. data/contrib/zstd/zstd.h +0 -640
@@ -1,10 +1,11 @@
1
- /**
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
1
+ /*
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
8
9
  */
9
10
 
10
11
  #ifndef ZSTDv05_H
@@ -18,7 +19,7 @@ extern "C" {
18
19
  * Dependencies
19
20
  ***************************************/
20
21
  #include <stddef.h> /* size_t */
21
- #include "mem.h" /* U64, U32 */
22
+ #include "../common/mem.h" /* U64, U32 */
22
23
 
23
24
 
24
25
  /* *************************************
@@ -32,6 +33,18 @@ extern "C" {
32
33
  size_t ZSTDv05_decompress( void* dst, size_t dstCapacity,
33
34
  const void* src, size_t compressedSize);
34
35
 
36
+ /**
37
+ ZSTDv05_findFrameSizeInfoLegacy() : get the source length and decompressed bound of a ZSTD frame compliant with v0.5.x format
38
+ srcSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src'
39
+ cSize (output parameter) : the number of bytes that would be read to decompress this frame
40
+ or an error code if it fails (which can be tested using ZSTDv01_isError())
41
+ dBound (output parameter) : an upper-bound for the decompressed size of the data in the frame
42
+ or ZSTD_CONTENTSIZE_ERROR if an error occurs
43
+
44
+ note : assumes `cSize` and `dBound` are _not_ NULL.
45
+ */
46
+ void ZSTDv05_findFrameSizeInfoLegacy(const void *src, size_t srcSize,
47
+ size_t* cSize, unsigned long long* dBound);
35
48
 
36
49
  /* *************************************
37
50
  * Helper functions
@@ -1,10 +1,11 @@
1
- /**
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
1
+ /*
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
- * This source code is licensed under the BSD-style license found in the
6
- * LICENSE file in the root directory of this source tree. An additional grant
7
- * of patent rights can be found in the PATENTS file in the same directory.
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
8
9
  */
9
10
 
10
11
 
@@ -13,7 +14,7 @@
13
14
  #include <stddef.h> /* size_t, ptrdiff_t */
14
15
  #include <string.h> /* memcpy */
15
16
  #include <stdlib.h> /* malloc, free, qsort */
16
- #include "error_private.h"
17
+ #include "../common/error_private.h"
17
18
 
18
19
 
19
20
 
@@ -81,7 +82,11 @@ extern "C" {
81
82
  * Basic Types
82
83
  *****************************************************************/
83
84
  #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
84
- # include <stdint.h>
85
+ # if defined(_AIX)
86
+ # include <inttypes.h>
87
+ # else
88
+ # include <stdint.h> /* intptr_t */
89
+ # endif
85
90
  typedef uint8_t BYTE;
86
91
  typedef uint16_t U16;
87
92
  typedef int16_t S16;
@@ -188,7 +193,7 @@ MEM_STATIC U32 MEM_swap32(U32 in)
188
193
  {
189
194
  #if defined(_MSC_VER) /* Visual Studio */
190
195
  return _byteswap_ulong(in);
191
- #elif defined (__GNUC__)
196
+ #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
192
197
  return __builtin_bswap32(in);
193
198
  #else
194
199
  return ((in << 24) & 0xff000000 ) |
@@ -202,7 +207,7 @@ MEM_STATIC U64 MEM_swap64(U64 in)
202
207
  {
203
208
  #if defined(_MSC_VER) /* Visual Studio */
204
209
  return _byteswap_uint64(in);
205
- #elif defined (__GNUC__)
210
+ #elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
206
211
  return __builtin_bswap64(in);
207
212
  #else
208
213
  return ((in << 56) & 0xff00000000000000ULL) |
@@ -505,6 +510,8 @@ typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
505
510
  #define FSEv06_ENCODING_STATIC 2
506
511
  #define FSEv06_ENCODING_DYNAMIC 3
507
512
 
513
+ #define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
514
+
508
515
  static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
509
516
  1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
510
517
  13,14,15,16 };
@@ -537,7 +544,7 @@ static void ZSTDv06_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
537
544
  /*! ZSTDv06_wildcopy() :
538
545
  * custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
539
546
  #define WILDCOPY_OVERLENGTH 8
540
- MEM_STATIC void ZSTDv06_wildcopy(void* dst, const void* src, size_t length)
547
+ MEM_STATIC void ZSTDv06_wildcopy(void* dst, const void* src, ptrdiff_t length)
541
548
  {
542
549
  const BYTE* ip = (const BYTE*)src;
543
550
  BYTE* op = (BYTE*)dst;
@@ -838,16 +845,6 @@ MEM_STATIC BITv06_DStream_status BITv06_reloadDStream(BITv06_DStream_t* bitD);
838
845
  MEM_STATIC unsigned BITv06_endOfDStream(const BITv06_DStream_t* bitD);
839
846
 
840
847
 
841
- /* Start by invoking BITv06_initDStream().
842
- * A chunk of the bitStream is then stored into a local register.
843
- * Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
844
- * You can then retrieve bitFields stored into the local register, **in reverse order**.
845
- * Local register is explicitly reloaded from memory by the BITv06_reloadDStream() method.
846
- * A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BITv06_DStream_unfinished.
847
- * Otherwise, it can be less than that, so proceed accordingly.
848
- * Checking if DStream has reached its end can be performed with BITv06_endOfDStream().
849
- */
850
-
851
848
 
852
849
  /*-****************************************
853
850
  * unsafe API
@@ -860,14 +857,14 @@ MEM_STATIC size_t BITv06_readBitsFast(BITv06_DStream_t* bitD, unsigned nbBits);
860
857
  /*-**************************************************************
861
858
  * Internal functions
862
859
  ****************************************************************/
863
- MEM_STATIC unsigned BITv06_highbit32 (register U32 val)
860
+ MEM_STATIC unsigned BITv06_highbit32 ( U32 val)
864
861
  {
865
862
  # if defined(_MSC_VER) /* Visual */
866
863
  unsigned long r=0;
867
864
  _BitScanReverse ( &r, val );
868
865
  return (unsigned) r;
869
866
  # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
870
- return 31 - __builtin_clz (val);
867
+ return __builtin_clz (val) ^ 31;
871
868
  # else /* Software version */
872
869
  static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
873
870
  U32 v = val;
@@ -910,13 +907,13 @@ MEM_STATIC size_t BITv06_initDStream(BITv06_DStream_t* bitD, const void* srcBuff
910
907
  bitD->bitContainer = *(const BYTE*)(bitD->start);
911
908
  switch(srcSize)
912
909
  {
913
- case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
914
- case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
915
- case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
916
- case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
917
- case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
918
- case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
919
- default:;
910
+ case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);/* fall-through */
911
+ case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);/* fall-through */
912
+ case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);/* fall-through */
913
+ case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24; /* fall-through */
914
+ case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16; /* fall-through */
915
+ case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8; /* fall-through */
916
+ default: break;
920
917
  }
921
918
  { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
922
919
  if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */
@@ -928,13 +925,6 @@ MEM_STATIC size_t BITv06_initDStream(BITv06_DStream_t* bitD, const void* srcBuff
928
925
  }
929
926
 
930
927
 
931
- /*! BITv06_lookBits() :
932
- * Provides next n bits from local register.
933
- * local register is not modified.
934
- * On 32-bits, maxNbBits==24.
935
- * On 64-bits, maxNbBits==56.
936
- * @return : value extracted
937
- */
938
928
  MEM_STATIC size_t BITv06_lookBits(const BITv06_DStream_t* bitD, U32 nbBits)
939
929
  {
940
930
  U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
@@ -954,11 +944,6 @@ MEM_STATIC void BITv06_skipBits(BITv06_DStream_t* bitD, U32 nbBits)
954
944
  bitD->bitsConsumed += nbBits;
955
945
  }
956
946
 
957
- /*! BITv06_readBits() :
958
- * Read (consume) next n bits from local register and update.
959
- * Pay attention to not read more than nbBits contained into local register.
960
- * @return : extracted value.
961
- */
962
947
  MEM_STATIC size_t BITv06_readBits(BITv06_DStream_t* bitD, U32 nbBits)
963
948
  {
964
949
  size_t const value = BITv06_lookBits(bitD, nbBits);
@@ -975,15 +960,10 @@ MEM_STATIC size_t BITv06_readBitsFast(BITv06_DStream_t* bitD, U32 nbBits)
975
960
  return value;
976
961
  }
977
962
 
978
- /*! BITv06_reloadDStream() :
979
- * Refill `BITv06_DStream_t` from src buffer previously defined (see BITv06_initDStream() ).
980
- * This function is safe, it guarantees it will not read beyond src buffer.
981
- * @return : status of `BITv06_DStream_t` internal register.
982
- if status == unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
983
963
  MEM_STATIC BITv06_DStream_status BITv06_reloadDStream(BITv06_DStream_t* bitD)
984
964
  {
985
- if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
986
- return BITv06_DStream_overflow;
965
+ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* should never happen */
966
+ return BITv06_DStream_overflow;
987
967
 
988
968
  if (bitD->ptr >= bitD->start + sizeof(bitD->bitContainer)) {
989
969
  bitD->ptr -= bitD->bitsConsumed >> 3;
@@ -1102,55 +1082,6 @@ static void FSEv06_initDState(FSEv06_DState_t* DStatePtr, BITv06_DStream_t*
1102
1082
 
1103
1083
  static unsigned char FSEv06_decodeSymbol(FSEv06_DState_t* DStatePtr, BITv06_DStream_t* bitD);
1104
1084
 
1105
- /*!
1106
- Let's now decompose FSEv06_decompress_usingDTable() into its unitary components.
1107
- You will decode FSE-encoded symbols from the bitStream,
1108
- and also any other bitFields you put in, **in reverse order**.
1109
-
1110
- You will need a few variables to track your bitStream. They are :
1111
-
1112
- BITv06_DStream_t DStream; // Stream context
1113
- FSEv06_DState_t DState; // State context. Multiple ones are possible
1114
- FSEv06_DTable* DTablePtr; // Decoding table, provided by FSEv06_buildDTable()
1115
-
1116
- The first thing to do is to init the bitStream.
1117
- errorCode = BITv06_initDStream(&DStream, srcBuffer, srcSize);
1118
-
1119
- You should then retrieve your initial state(s)
1120
- (in reverse flushing order if you have several ones) :
1121
- errorCode = FSEv06_initDState(&DState, &DStream, DTablePtr);
1122
-
1123
- You can then decode your data, symbol after symbol.
1124
- For information the maximum number of bits read by FSEv06_decodeSymbol() is 'tableLog'.
1125
- Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
1126
- unsigned char symbol = FSEv06_decodeSymbol(&DState, &DStream);
1127
-
1128
- You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
1129
- Note : maximum allowed nbBits is 25, for 32-bits compatibility
1130
- size_t bitField = BITv06_readBits(&DStream, nbBits);
1131
-
1132
- All above operations only read from local register (which size depends on size_t).
1133
- Refueling the register from memory is manually performed by the reload method.
1134
- endSignal = FSEv06_reloadDStream(&DStream);
1135
-
1136
- BITv06_reloadDStream() result tells if there is still some more data to read from DStream.
1137
- BITv06_DStream_unfinished : there is still some data left into the DStream.
1138
- BITv06_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
1139
- BITv06_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
1140
- BITv06_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
1141
-
1142
- When reaching end of buffer (BITv06_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
1143
- to properly detect the exact end of stream.
1144
- After each decoded symbol, check if DStream is fully consumed using this simple test :
1145
- BITv06_reloadDStream(&DStream) >= BITv06_DStream_completed
1146
-
1147
- When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
1148
- Checking if DStream has reached its end is performed by :
1149
- BITv06_endOfDStream(&DStream);
1150
- Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
1151
- FSEv06_endOfDState(&DState);
1152
- */
1153
-
1154
1085
 
1155
1086
  /* *****************************************
1156
1087
  * FSE unsafe API
@@ -1325,9 +1256,7 @@ const char* FSEv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
1325
1256
  /* **************************************************************
1326
1257
  * HUF Error Management
1327
1258
  ****************************************************************/
1328
- unsigned HUFv06_isError(size_t code) { return ERR_isError(code); }
1329
-
1330
- const char* HUFv06_getErrorName(size_t code) { return ERR_getErrorName(code); }
1259
+ static unsigned HUFv06_isError(size_t code) { return ERR_isError(code); }
1331
1260
 
1332
1261
 
1333
1262
  /*-**************************************************************
@@ -1937,7 +1866,7 @@ MEM_STATIC size_t HUFv06_readStats(BYTE* huffWeight, size_t hwSize, U32* rankSta
1937
1866
 
1938
1867
  if (!srcSize) return ERROR(srcSize_wrong);
1939
1868
  iSize = ip[0];
1940
- //memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
1869
+ /* memset(huffWeight, 0, hwSize); */ /* is not necessary, even though some analyzer complain ... */
1941
1870
 
1942
1871
  if (iSize >= 128) { /* special header */
1943
1872
  if (iSize >= (242)) { /* RLE */
@@ -2089,7 +2018,7 @@ size_t HUFv06_readDTableX2 (U16* DTable, const void* src, size_t srcSize)
2089
2018
  HUFv06_DEltX2* const dt = (HUFv06_DEltX2*)dtPtr;
2090
2019
 
2091
2020
  HUFv06_STATIC_ASSERT(sizeof(HUFv06_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */
2092
- //memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
2021
+ /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
2093
2022
 
2094
2023
  iSize = HUFv06_readStats(huffWeight, HUFv06_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
2095
2024
  if (HUFv06_isError(iSize)) return iSize;
@@ -2415,7 +2344,7 @@ size_t HUFv06_readDTableX4 (U32* DTable, const void* src, size_t srcSize)
2415
2344
 
2416
2345
  HUFv06_STATIC_ASSERT(sizeof(HUFv06_DEltX4) == sizeof(U32)); /* if compilation fails here, assertion is false */
2417
2346
  if (memLog > HUFv06_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
2418
- //memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
2347
+ /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
2419
2348
 
2420
2349
  iSize = HUFv06_readStats(weightList, HUFv06_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
2421
2350
  if (HUFv06_isError(iSize)) return iSize;
@@ -2739,13 +2668,13 @@ size_t HUFv06_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cS
2739
2668
 
2740
2669
  { U32 algoNb = 0;
2741
2670
  if (Dtime[1] < Dtime[0]) algoNb = 1;
2742
- // if (Dtime[2] < Dtime[algoNb]) algoNb = 2; /* current speed of HUFv06_decompress4X6 is not good */
2671
+ /* if (Dtime[2] < Dtime[algoNb]) algoNb = 2; */ /* current speed of HUFv06_decompress4X6 is not good */
2743
2672
  return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
2744
2673
  }
2745
2674
 
2746
- //return HUFv06_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */
2747
- //return HUFv06_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
2748
- //return HUFv06_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */
2675
+ /* return HUFv06_decompress4X2(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams single-symbol decoding */
2676
+ /* return HUFv06_decompress4X4(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams double-symbols decoding */
2677
+ /* return HUFv06_decompress4X6(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams quad-symbols decoding */
2749
2678
  }
2750
2679
  /*
2751
2680
  Common functions of Zstd compression library
@@ -2893,13 +2822,13 @@ struct ZSTDv06_DCtx_s
2893
2822
  ZSTDv06_dStage stage;
2894
2823
  U32 flagRepeatTable;
2895
2824
  const BYTE* litPtr;
2896
- size_t litBufSize;
2897
2825
  size_t litSize;
2898
2826
  BYTE litBuffer[ZSTDv06_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
2899
2827
  BYTE headerBuffer[ZSTDv06_FRAMEHEADERSIZE_MAX];
2900
2828
  }; /* typedef'd to ZSTDv06_DCtx within "zstd_static.h" */
2901
2829
 
2902
- size_t ZSTDv06_sizeofDCtx (void) { return sizeof(ZSTDv06_DCtx); } /* non published interface */
2830
+ size_t ZSTDv06_sizeofDCtx (void); /* Hidden declaration */
2831
+ size_t ZSTDv06_sizeofDCtx (void) { return sizeof(ZSTDv06_DCtx); }
2903
2832
 
2904
2833
  size_t ZSTDv06_decompressBegin(ZSTDv06_DCtx* dctx)
2905
2834
  {
@@ -3085,7 +3014,7 @@ size_t ZSTDv06_getFrameParams(ZSTDv06_frameParams* fparamsPtr, const void* src,
3085
3014
  static size_t ZSTDv06_decodeFrameHeader(ZSTDv06_DCtx* zc, const void* src, size_t srcSize)
3086
3015
  {
3087
3016
  size_t const result = ZSTDv06_getFrameParams(&(zc->fParams), src, srcSize);
3088
- if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupportedBy32bits);
3017
+ if ((MEM_32bits()) && (zc->fParams.windowLog > 25)) return ERROR(frameParameter_unsupported);
3089
3018
  return result;
3090
3019
  }
3091
3020
 
@@ -3098,7 +3027,7 @@ typedef struct
3098
3027
 
3099
3028
  /*! ZSTDv06_getcBlockSize() :
3100
3029
  * Provides the size of compressed block from block header `src` */
3101
- size_t ZSTDv06_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
3030
+ static size_t ZSTDv06_getcBlockSize(const void* src, size_t srcSize, blockProperties_t* bpPtr)
3102
3031
  {
3103
3032
  const BYTE* const in = (const BYTE* const)src;
3104
3033
  U32 cSize;
@@ -3117,6 +3046,7 @@ size_t ZSTDv06_getcBlockSize(const void* src, size_t srcSize, blockProperties_t*
3117
3046
 
3118
3047
  static size_t ZSTDv06_copyRawBlock(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
3119
3048
  {
3049
+ if (dst==NULL) return ERROR(dstSize_tooSmall);
3120
3050
  if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
3121
3051
  memcpy(dst, src, srcSize);
3122
3052
  return srcSize;
@@ -3125,7 +3055,7 @@ static size_t ZSTDv06_copyRawBlock(void* dst, size_t dstCapacity, const void* sr
3125
3055
 
3126
3056
  /*! ZSTDv06_decodeLiteralsBlock() :
3127
3057
  @return : nb of bytes read from src (< srcSize ) */
3128
- size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3058
+ static size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3129
3059
  const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
3130
3060
  {
3131
3061
  const BYTE* const istart = (const BYTE*) src;
@@ -3170,8 +3100,8 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3170
3100
  return ERROR(corruption_detected);
3171
3101
 
3172
3102
  dctx->litPtr = dctx->litBuffer;
3173
- dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8;
3174
3103
  dctx->litSize = litSize;
3104
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3175
3105
  return litCSize + lhSize;
3176
3106
  }
3177
3107
  case IS_PCH:
@@ -3186,14 +3116,14 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3186
3116
  lhSize=3;
3187
3117
  litSize = ((istart[0] & 15) << 6) + (istart[1] >> 2);
3188
3118
  litCSize = ((istart[1] & 3) << 8) + istart[2];
3189
- if (litCSize + litSize > srcSize) return ERROR(corruption_detected);
3119
+ if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
3190
3120
 
3191
3121
  { size_t const errorCode = HUFv06_decompress1X4_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->hufTableX4);
3192
3122
  if (HUFv06_isError(errorCode)) return ERROR(corruption_detected);
3193
3123
  }
3194
3124
  dctx->litPtr = dctx->litBuffer;
3195
- dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
3196
3125
  dctx->litSize = litSize;
3126
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3197
3127
  return litCSize + lhSize;
3198
3128
  }
3199
3129
  case IS_RAW:
@@ -3217,13 +3147,12 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3217
3147
  if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
3218
3148
  memcpy(dctx->litBuffer, istart+lhSize, litSize);
3219
3149
  dctx->litPtr = dctx->litBuffer;
3220
- dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+8;
3221
3150
  dctx->litSize = litSize;
3151
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
3222
3152
  return lhSize+litSize;
3223
3153
  }
3224
3154
  /* direct reference into compressed stream */
3225
3155
  dctx->litPtr = istart+lhSize;
3226
- dctx->litBufSize = srcSize-lhSize;
3227
3156
  dctx->litSize = litSize;
3228
3157
  return lhSize+litSize;
3229
3158
  }
@@ -3245,9 +3174,8 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3245
3174
  break;
3246
3175
  }
3247
3176
  if (litSize > ZSTDv06_BLOCKSIZE_MAX) return ERROR(corruption_detected);
3248
- memset(dctx->litBuffer, istart[lhSize], litSize);
3177
+ memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
3249
3178
  dctx->litPtr = dctx->litBuffer;
3250
- dctx->litBufSize = ZSTDv06_BLOCKSIZE_MAX+WILDCOPY_OVERLENGTH;
3251
3179
  dctx->litSize = litSize;
3252
3180
  return lhSize+1;
3253
3181
  }
@@ -3261,7 +3189,7 @@ size_t ZSTDv06_decodeLiteralsBlock(ZSTDv06_DCtx* dctx,
3261
3189
  @return : nb bytes read from src,
3262
3190
  or an error code if it fails, testable with ZSTDv06_isError()
3263
3191
  */
3264
- size_t ZSTDv06_buildSeqTable(FSEv06_DTable* DTable, U32 type, U32 max, U32 maxLog,
3192
+ static size_t ZSTDv06_buildSeqTable(FSEv06_DTable* DTable, U32 type, U32 max, U32 maxLog,
3265
3193
  const void* src, size_t srcSize,
3266
3194
  const S16* defaultNorm, U32 defaultLog, U32 flagRepeatTable)
3267
3195
  {
@@ -3291,7 +3219,7 @@ size_t ZSTDv06_buildSeqTable(FSEv06_DTable* DTable, U32 type, U32 max, U32 maxLo
3291
3219
  }
3292
3220
 
3293
3221
 
3294
- size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
3222
+ static size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
3295
3223
  FSEv06_DTable* DTableLL, FSEv06_DTable* DTableML, FSEv06_DTable* DTableOffb, U32 flagRepeatTable,
3296
3224
  const void* src, size_t srcSize)
3297
3225
  {
@@ -3318,14 +3246,12 @@ size_t ZSTDv06_decodeSeqHeaders(int* nbSeqPtr,
3318
3246
  }
3319
3247
 
3320
3248
  /* FSE table descriptors */
3249
+ if (ip + 4 > iend) return ERROR(srcSize_wrong); /* min : header byte + all 3 are "raw", hence no header, but at least xxLog bits per type */
3321
3250
  { U32 const LLtype = *ip >> 6;
3322
3251
  U32 const Offtype = (*ip >> 4) & 3;
3323
3252
  U32 const MLtype = (*ip >> 2) & 3;
3324
3253
  ip++;
3325
3254
 
3326
- /* check */
3327
- if (ip > iend-3) return ERROR(srcSize_wrong); /* min : all 3 are "raw", hence no header, but at least xxLog bits per type */
3328
-
3329
3255
  /* Build DTables */
3330
3256
  { size_t const bhSize = ZSTDv06_buildSeqTable(DTableLL, LLtype, MaxLL, LLFSELog, ip, iend-ip, LL_defaultNorm, LL_defaultNormLog, flagRepeatTable);
3331
3257
  if (ZSTDv06_isError(bhSize)) return ERROR(corruption_detected);
@@ -3436,9 +3362,9 @@ static void ZSTDv06_decodeSequence(seq_t* seq, seqState_t* seqState)
3436
3362
  }
3437
3363
 
3438
3364
 
3439
- size_t ZSTDv06_execSequence(BYTE* op,
3365
+ static size_t ZSTDv06_execSequence(BYTE* op,
3440
3366
  BYTE* const oend, seq_t sequence,
3441
- const BYTE** litPtr, const BYTE* const litLimit_8,
3367
+ const BYTE** litPtr, const BYTE* const litLimit,
3442
3368
  const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
3443
3369
  {
3444
3370
  BYTE* const oLitEnd = op + sequence.litLength;
@@ -3451,7 +3377,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
3451
3377
  /* check */
3452
3378
  if (oLitEnd > oend_8) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of 8 from oend */
3453
3379
  if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* overwrite beyond dst buffer */
3454
- if (iLitEnd > litLimit_8) return ERROR(corruption_detected); /* over-read beyond lit buffer */
3380
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
3455
3381
 
3456
3382
  /* copy Literals */
3457
3383
  ZSTDv06_wildcopy(op, *litPtr, sequence.litLength); /* note : oLitEnd <= oend-8 : no risk of overwrite beyond oend */
@@ -3473,7 +3399,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
3473
3399
  op = oLitEnd + length1;
3474
3400
  sequence.matchLength -= length1;
3475
3401
  match = base;
3476
- if (op > oend_8) {
3402
+ if (op > oend_8 || sequence.matchLength < MINMATCH) {
3477
3403
  while (op < oMatchEnd) *op++ = *match++;
3478
3404
  return sequenceLength;
3479
3405
  }
@@ -3484,7 +3410,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
3484
3410
  if (sequence.offset < 8) {
3485
3411
  /* close range match, overlap */
3486
3412
  static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
3487
- static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
3413
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
3488
3414
  int const sub2 = dec64table[sequence.offset];
3489
3415
  op[0] = match[0];
3490
3416
  op[1] = match[1];
@@ -3506,7 +3432,7 @@ size_t ZSTDv06_execSequence(BYTE* op,
3506
3432
  }
3507
3433
  while (op < oMatchEnd) *op++ = *match++;
3508
3434
  } else {
3509
- ZSTDv06_wildcopy(op, match, sequence.matchLength-8); /* works even if matchLength < 8 */
3435
+ ZSTDv06_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
3510
3436
  }
3511
3437
  return sequenceLength;
3512
3438
  }
@@ -3523,7 +3449,6 @@ static size_t ZSTDv06_decompressSequences(
3523
3449
  BYTE* const oend = ostart + maxDstSize;
3524
3450
  BYTE* op = ostart;
3525
3451
  const BYTE* litPtr = dctx->litPtr;
3526
- const BYTE* const litLimit_8 = litPtr + dctx->litBufSize - 8;
3527
3452
  const BYTE* const litEnd = litPtr + dctx->litSize;
3528
3453
  FSEv06_DTable* DTableLL = dctx->LLTable;
3529
3454
  FSEv06_DTable* DTableML = dctx->MLTable;
@@ -3567,7 +3492,7 @@ static size_t ZSTDv06_decompressSequences(
3567
3492
  pos, (U32)sequence.litLength, (U32)sequence.matchLength, (U32)sequence.offset);
3568
3493
  #endif
3569
3494
 
3570
- { size_t const oneSeqSize = ZSTDv06_execSequence(op, oend, sequence, &litPtr, litLimit_8, base, vBase, dictEnd);
3495
+ { size_t const oneSeqSize = ZSTDv06_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
3571
3496
  if (ZSTDv06_isError(oneSeqSize)) return oneSeqSize;
3572
3497
  op += oneSeqSize;
3573
3498
  } }
@@ -3580,8 +3505,10 @@ static size_t ZSTDv06_decompressSequences(
3580
3505
  { size_t const lastLLSize = litEnd - litPtr;
3581
3506
  if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
3582
3507
  if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
3583
- memcpy(op, litPtr, lastLLSize);
3584
- op += lastLLSize;
3508
+ if (lastLLSize > 0) {
3509
+ memcpy(op, litPtr, lastLLSize);
3510
+ op += lastLLSize;
3511
+ }
3585
3512
  }
3586
3513
 
3587
3514
  return op-ostart;
@@ -3733,6 +3660,63 @@ size_t ZSTDv06_decompress(void* dst, size_t dstCapacity, const void* src, size_t
3733
3660
  #endif
3734
3661
  }
3735
3662
 
3663
+ /* ZSTD_errorFrameSizeInfoLegacy() :
3664
+ assumes `cSize` and `dBound` are _not_ NULL */
3665
+ static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)
3666
+ {
3667
+ *cSize = ret;
3668
+ *dBound = ZSTD_CONTENTSIZE_ERROR;
3669
+ }
3670
+
3671
+ void ZSTDv06_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)
3672
+ {
3673
+ const BYTE* ip = (const BYTE*)src;
3674
+ size_t remainingSize = srcSize;
3675
+ size_t nbBlocks = 0;
3676
+ blockProperties_t blockProperties = { bt_compressed, 0 };
3677
+
3678
+ /* Frame Header */
3679
+ { size_t const frameHeaderSize = ZSTDv06_frameHeaderSize(src, srcSize);
3680
+ if (ZSTDv06_isError(frameHeaderSize)) {
3681
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, frameHeaderSize);
3682
+ return;
3683
+ }
3684
+ if (MEM_readLE32(src) != ZSTDv06_MAGICNUMBER) {
3685
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));
3686
+ return;
3687
+ }
3688
+ if (srcSize < frameHeaderSize+ZSTDv06_blockHeaderSize) {
3689
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3690
+ return;
3691
+ }
3692
+ ip += frameHeaderSize; remainingSize -= frameHeaderSize;
3693
+ }
3694
+
3695
+ /* Loop on each block */
3696
+ while (1) {
3697
+ size_t const cBlockSize = ZSTDv06_getcBlockSize(ip, remainingSize, &blockProperties);
3698
+ if (ZSTDv06_isError(cBlockSize)) {
3699
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);
3700
+ return;
3701
+ }
3702
+
3703
+ ip += ZSTDv06_blockHeaderSize;
3704
+ remainingSize -= ZSTDv06_blockHeaderSize;
3705
+ if (cBlockSize > remainingSize) {
3706
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3707
+ return;
3708
+ }
3709
+
3710
+ if (cBlockSize == 0) break; /* bt_end */
3711
+
3712
+ ip += cBlockSize;
3713
+ remainingSize -= cBlockSize;
3714
+ nbBlocks++;
3715
+ }
3716
+
3717
+ *cSize = ip - (const BYTE*)src;
3718
+ *dBound = nbBlocks * ZSTDv06_BLOCKSIZE_MAX;
3719
+ }
3736
3720
 
3737
3721
  /*_******************************
3738
3722
  * Streaming Decompression API
@@ -3762,7 +3746,7 @@ size_t ZSTDv06_decompressContinue(ZSTDv06_DCtx* dctx, void* dst, size_t dstCapac
3762
3746
  return 0;
3763
3747
  }
3764
3748
  dctx->expected = 0; /* not necessary to copy more */
3765
-
3749
+ /* fall-through */
3766
3750
  case ZSTDds_decodeFrameHeader:
3767
3751
  { size_t result;
3768
3752
  memcpy(dctx->headerBuffer + ZSTDv06_frameHeaderSize_min, src, dctx->expected);
@@ -4022,7 +4006,9 @@ size_t ZBUFFv06_decompressInit(ZBUFFv06_DCtx* zbd)
4022
4006
  MEM_STATIC size_t ZBUFFv06_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
4023
4007
  {
4024
4008
  size_t length = MIN(dstCapacity, srcSize);
4025
- memcpy(dst, src, length);
4009
+ if (length > 0) {
4010
+ memcpy(dst, src, length);
4011
+ }
4026
4012
  return length;
4027
4013
  }
4028
4014
 
@@ -4054,7 +4040,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
4054
4040
  if (ZSTDv06_isError(hSize)) return hSize;
4055
4041
  if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
4056
4042
  memcpy(zbd->headerBuffer + zbd->lhSize, ip, iend-ip);
4057
- zbd->lhSize += iend-ip; ip = iend; notDone = 0;
4043
+ zbd->lhSize += iend-ip;
4058
4044
  *dstCapacityPtr = 0;
4059
4045
  return (hSize - zbd->lhSize) + ZSTDv06_blockHeaderSize; /* remaining header bytes + next block header */
4060
4046
  }
@@ -4081,7 +4067,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
4081
4067
  zbd->inBuff = (char*)malloc(blockSize);
4082
4068
  if (zbd->inBuff == NULL) return ERROR(memory_allocation);
4083
4069
  }
4084
- { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize;
4070
+ { size_t const neededOutSize = ((size_t)1 << zbd->fParams.windowLog) + blockSize + WILDCOPY_OVERLENGTH * 2;
4085
4071
  if (zbd->outBuffSize < neededOutSize) {
4086
4072
  free(zbd->outBuff);
4087
4073
  zbd->outBuffSize = neededOutSize;
@@ -4089,7 +4075,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
4089
4075
  if (zbd->outBuff == NULL) return ERROR(memory_allocation);
4090
4076
  } } }
4091
4077
  zbd->stage = ZBUFFds_read;
4092
-
4078
+ /* fall-through */
4093
4079
  case ZBUFFds_read:
4094
4080
  { size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
4095
4081
  if (neededInSize==0) { /* end of frame */
@@ -4111,7 +4097,7 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
4111
4097
  if (ip==iend) { notDone = 0; break; } /* no more input */
4112
4098
  zbd->stage = ZBUFFds_load;
4113
4099
  }
4114
-
4100
+ /* fall-through */
4115
4101
  case ZBUFFds_load:
4116
4102
  { size_t const neededInSize = ZSTDv06_nextSrcSizeToDecompress(zbd->zd);
4117
4103
  size_t const toLoad = neededInSize - zbd->inPos; /* should always be <= remaining space within inBuff */
@@ -4131,9 +4117,10 @@ size_t ZBUFFv06_decompressContinue(ZBUFFv06_DCtx* zbd,
4131
4117
  if (!decodedSize) { zbd->stage = ZBUFFds_read; break; } /* this was just a header */
4132
4118
  zbd->outEnd = zbd->outStart + decodedSize;
4133
4119
  zbd->stage = ZBUFFds_flush;
4134
- // break; /* ZBUFFds_flush follows */
4135
- } }
4136
-
4120
+ /* break; */ /* ZBUFFds_flush follows */
4121
+ }
4122
+ }
4123
+ /* fall-through */
4137
4124
  case ZBUFFds_flush:
4138
4125
  { size_t const toFlushSize = zbd->outEnd - zbd->outStart;
4139
4126
  size_t const flushedSize = ZBUFFv06_limitCopy(op, oend-op, zbd->outBuff + zbd->outStart, toFlushSize);