zstd-ruby 1.3.8.0 → 1.4.5.0

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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -5
  3. data/README.md +1 -1
  4. data/ext/zstdruby/libzstd/Makefile +133 -61
  5. data/ext/zstdruby/libzstd/README.md +51 -18
  6. data/ext/zstdruby/libzstd/common/bitstream.h +38 -39
  7. data/ext/zstdruby/libzstd/common/compiler.h +41 -6
  8. data/ext/zstdruby/libzstd/common/cpu.h +1 -1
  9. data/ext/zstdruby/libzstd/common/debug.c +11 -31
  10. data/ext/zstdruby/libzstd/common/debug.h +11 -31
  11. data/ext/zstdruby/libzstd/common/entropy_common.c +13 -33
  12. data/ext/zstdruby/libzstd/common/error_private.c +2 -1
  13. data/ext/zstdruby/libzstd/common/error_private.h +6 -2
  14. data/ext/zstdruby/libzstd/common/fse.h +13 -33
  15. data/ext/zstdruby/libzstd/common/fse_decompress.c +12 -35
  16. data/ext/zstdruby/libzstd/common/huf.h +15 -33
  17. data/ext/zstdruby/libzstd/common/mem.h +75 -2
  18. data/ext/zstdruby/libzstd/common/pool.c +8 -4
  19. data/ext/zstdruby/libzstd/common/pool.h +2 -2
  20. data/ext/zstdruby/libzstd/common/threading.c +52 -6
  21. data/ext/zstdruby/libzstd/common/threading.h +36 -4
  22. data/ext/zstdruby/libzstd/common/xxhash.c +25 -37
  23. data/ext/zstdruby/libzstd/common/xxhash.h +11 -31
  24. data/ext/zstdruby/libzstd/common/zstd_common.c +1 -1
  25. data/ext/zstdruby/libzstd/common/zstd_errors.h +2 -1
  26. data/ext/zstdruby/libzstd/common/zstd_internal.h +203 -22
  27. data/ext/zstdruby/libzstd/compress/fse_compress.c +19 -42
  28. data/ext/zstdruby/libzstd/compress/hist.c +15 -35
  29. data/ext/zstdruby/libzstd/compress/hist.h +12 -32
  30. data/ext/zstdruby/libzstd/compress/huf_compress.c +92 -92
  31. data/ext/zstdruby/libzstd/compress/zstd_compress.c +1460 -1472
  32. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +330 -65
  33. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.c +158 -0
  34. data/ext/zstdruby/libzstd/compress/zstd_compress_literals.h +29 -0
  35. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.c +419 -0
  36. data/ext/zstdruby/libzstd/compress/zstd_compress_sequences.h +54 -0
  37. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +845 -0
  38. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.h +32 -0
  39. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +525 -0
  40. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +65 -43
  41. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +2 -2
  42. data/ext/zstdruby/libzstd/compress/zstd_fast.c +264 -159
  43. data/ext/zstdruby/libzstd/compress/zstd_fast.h +2 -2
  44. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +74 -42
  45. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +2 -2
  46. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +33 -11
  47. data/ext/zstdruby/libzstd/compress/zstd_ldm.h +7 -2
  48. data/ext/zstdruby/libzstd/compress/zstd_opt.c +108 -125
  49. data/ext/zstdruby/libzstd/compress/zstd_opt.h +1 -1
  50. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +129 -93
  51. data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +46 -28
  52. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +76 -60
  53. data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +14 -10
  54. data/ext/zstdruby/libzstd/decompress/zstd_ddict.h +2 -2
  55. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +471 -258
  56. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +471 -346
  57. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +3 -3
  58. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +25 -4
  59. data/ext/zstdruby/libzstd/deprecated/zbuff.h +9 -8
  60. data/ext/zstdruby/libzstd/deprecated/zbuff_common.c +2 -2
  61. data/ext/zstdruby/libzstd/deprecated/zbuff_compress.c +1 -1
  62. data/ext/zstdruby/libzstd/deprecated/zbuff_decompress.c +1 -1
  63. data/ext/zstdruby/libzstd/dictBuilder/cover.c +220 -65
  64. data/ext/zstdruby/libzstd/dictBuilder/cover.h +81 -7
  65. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +85 -56
  66. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +43 -19
  67. data/ext/zstdruby/libzstd/dictBuilder/zdict.h +73 -35
  68. data/ext/zstdruby/libzstd/dll/example/Makefile +2 -1
  69. data/ext/zstdruby/libzstd/dll/example/build_package.bat +3 -2
  70. data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +49 -15
  71. data/ext/zstdruby/libzstd/legacy/zstd_v01.c +142 -117
  72. data/ext/zstdruby/libzstd/legacy/zstd_v01.h +13 -8
  73. data/ext/zstdruby/libzstd/legacy/zstd_v02.c +54 -25
  74. data/ext/zstdruby/libzstd/legacy/zstd_v02.h +13 -8
  75. data/ext/zstdruby/libzstd/legacy/zstd_v03.c +55 -25
  76. data/ext/zstdruby/libzstd/legacy/zstd_v03.h +13 -8
  77. data/ext/zstdruby/libzstd/legacy/zstd_v04.c +62 -29
  78. data/ext/zstdruby/libzstd/legacy/zstd_v04.h +13 -8
  79. data/ext/zstdruby/libzstd/legacy/zstd_v05.c +145 -109
  80. data/ext/zstdruby/libzstd/legacy/zstd_v05.h +14 -9
  81. data/ext/zstdruby/libzstd/legacy/zstd_v06.c +56 -26
  82. data/ext/zstdruby/libzstd/legacy/zstd_v06.h +11 -6
  83. data/ext/zstdruby/libzstd/legacy/zstd_v07.c +65 -28
  84. data/ext/zstdruby/libzstd/legacy/zstd_v07.h +11 -6
  85. data/ext/zstdruby/libzstd/libzstd.pc.in +3 -2
  86. data/ext/zstdruby/libzstd/zstd.h +921 -597
  87. data/lib/zstd-ruby/version.rb +1 -1
  88. data/zstd-ruby.gemspec +2 -2
  89. metadata +19 -14
  90. data/ext/zstdruby/libzstd/dll/libzstd.def +0 -87
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -35,13 +35,18 @@ ZSTDv03_decompress() : decompress ZSTD frames compliant with v0.3.x format
35
35
  size_t ZSTDv03_decompress( void* dst, size_t maxOriginalSize,
36
36
  const void* src, size_t compressedSize);
37
37
 
38
- /**
39
- ZSTDv03_getFrameSrcSize() : get the source length of a ZSTD frame compliant with v0.3.x format
40
- compressedSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src'
41
- return : the number of bytes that would be read to decompress this frame
42
- or an errorCode if it fails (which can be tested using ZSTDv03_isError())
43
- */
44
- size_t ZSTDv03_findFrameCompressedSize(const void* src, size_t compressedSize);
38
+ /**
39
+ ZSTDv03_findFrameSizeInfoLegacy() : get the source length and decompressed bound of a ZSTD frame compliant with v0.3.x format
40
+ srcSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src'
41
+ cSize (output parameter) : the number of bytes that would be read to decompress this frame
42
+ or an error code if it fails (which can be tested using ZSTDv01_isError())
43
+ dBound (output parameter) : an upper-bound for the decompressed size of the data in the frame
44
+ or ZSTD_CONTENTSIZE_ERROR if an error occurs
45
+
46
+ note : assumes `cSize` and `dBound` are _not_ NULL.
47
+ */
48
+ void ZSTDv03_findFrameSizeInfoLegacy(const void *src, size_t srcSize,
49
+ size_t* cSize, unsigned long long* dBound);
45
50
 
46
51
  /**
47
52
  ZSTDv03_isError() : tells if the result of ZSTDv03_decompress() is an error
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -16,7 +16,7 @@
16
16
  #include <string.h> /* memcpy */
17
17
 
18
18
  #include "zstd_v04.h"
19
- #include "error_private.h"
19
+ #include "../common/error_private.h"
20
20
 
21
21
 
22
22
  /* ******************************************************************
@@ -161,7 +161,7 @@ MEM_STATIC void MEM_write16(void* memPtr, U16 value)
161
161
  memcpy(memPtr, &value, sizeof(value));
162
162
  }
163
163
 
164
- #endif // MEM_FORCE_MEMORY_ACCESS
164
+ #endif /* MEM_FORCE_MEMORY_ACCESS */
165
165
 
166
166
 
167
167
  MEM_STATIC U16 MEM_readLE16(const void* memPtr)
@@ -189,6 +189,11 @@ MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
189
189
  }
190
190
  }
191
191
 
192
+ MEM_STATIC U32 MEM_readLE24(const void* memPtr)
193
+ {
194
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
195
+ }
196
+
192
197
  MEM_STATIC U32 MEM_readLE32(const void* memPtr)
193
198
  {
194
199
  if (MEM_isLittleEndian())
@@ -373,6 +378,8 @@ static const size_t ZSTD_frameHeaderSize_min = 5;
373
378
  #define MIN_SEQUENCES_SIZE (2 /*seqNb*/ + 2 /*dumps*/ + 3 /*seqTables*/ + 1 /*bitStream*/)
374
379
  #define MIN_CBLOCK_SIZE (3 /*litCSize*/ + MIN_SEQUENCES_SIZE)
375
380
 
381
+ #define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
382
+
376
383
  typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
377
384
 
378
385
 
@@ -620,7 +627,7 @@ MEM_STATIC unsigned BIT_highbit32 (U32 val)
620
627
  _BitScanReverse ( &r, val );
621
628
  return (unsigned) r;
622
629
  # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
623
- return 31 - __builtin_clz (val);
630
+ return __builtin_clz (val) ^ 31;
624
631
  # else /* Software version */
625
632
  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 };
626
633
  U32 v = val;
@@ -2596,7 +2603,9 @@ static size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, blockPropertie
2596
2603
  static size_t ZSTD_copyRawBlock(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
2597
2604
  {
2598
2605
  if (srcSize > maxDstSize) return ERROR(dstSize_tooSmall);
2599
- memcpy(dst, src, srcSize);
2606
+ if (srcSize > 0) {
2607
+ memcpy(dst, src, srcSize);
2608
+ }
2600
2609
  return srcSize;
2601
2610
  }
2602
2611
 
@@ -2648,6 +2657,7 @@ static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
2648
2657
  const size_t litSize = (MEM_readLE32(istart) & 0xFFFFFF) >> 2; /* no buffer issue : srcSize >= MIN_CBLOCK_SIZE */
2649
2658
  if (litSize > srcSize-11) /* risk of reading too far with wildcopy */
2650
2659
  {
2660
+ if (litSize > BLOCKSIZE) return ERROR(corruption_detected);
2651
2661
  if (litSize > srcSize-3) return ERROR(corruption_detected);
2652
2662
  memcpy(dctx->litBuffer, istart, litSize);
2653
2663
  dctx->litPtr = dctx->litBuffer;
@@ -2806,13 +2816,12 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
2806
2816
  litLength = FSE_decodeSymbol(&(seqState->stateLL), &(seqState->DStream));
2807
2817
  prevOffset = litLength ? seq->offset : seqState->prevOffset;
2808
2818
  if (litLength == MaxLL) {
2809
- U32 add = *dumps++;
2819
+ const U32 add = dumps<de ? *dumps++ : 0;
2810
2820
  if (add < 255) litLength += add;
2811
- else {
2812
- litLength = dumps[0] + (dumps[1]<<8) + (dumps[2]<<16);
2821
+ else if (dumps + 3 <= de) {
2822
+ litLength = MEM_readLE24(dumps);
2813
2823
  dumps += 3;
2814
2824
  }
2815
- if (dumps > de) { litLength = MaxLL+255; } /* late correction, to avoid using uninitialized memory */
2816
2825
  if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
2817
2826
  }
2818
2827
 
@@ -2835,13 +2844,12 @@ static void ZSTD_decodeSequence(seq_t* seq, seqState_t* seqState)
2835
2844
  /* MatchLength */
2836
2845
  matchLength = FSE_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
2837
2846
  if (matchLength == MaxML) {
2838
- U32 add = *dumps++;
2847
+ const U32 add = dumps<de ? *dumps++ : 0;
2839
2848
  if (add < 255) matchLength += add;
2840
- else {
2841
- matchLength = dumps[0] + (dumps[1]<<8) + (dumps[2]<<16);
2849
+ else if (dumps + 3 <= de){
2850
+ matchLength = MEM_readLE24(dumps);
2842
2851
  dumps += 3;
2843
2852
  }
2844
- if (dumps > de) { matchLength = MaxML+255; } /* late correction, to avoid using uninitialized memory */
2845
2853
  if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
2846
2854
  }
2847
2855
  matchLength += MINMATCH;
@@ -2860,7 +2868,7 @@ static size_t ZSTD_execSequence(BYTE* op,
2860
2868
  const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
2861
2869
  {
2862
2870
  static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
2863
- static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
2871
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
2864
2872
  BYTE* const oLitEnd = op + sequence.litLength;
2865
2873
  const size_t sequenceLength = sequence.litLength + sequence.matchLength;
2866
2874
  BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
@@ -3002,8 +3010,10 @@ static size_t ZSTD_decompressSequences(
3002
3010
  size_t lastLLSize = litEnd - litPtr;
3003
3011
  if (litPtr > litEnd) return ERROR(corruption_detected);
3004
3012
  if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
3005
- if (op != litPtr) memcpy(op, litPtr, lastLLSize);
3006
- op += lastLLSize;
3013
+ if (lastLLSize > 0) {
3014
+ if (op != litPtr) memcpy(op, litPtr, lastLLSize);
3015
+ op += lastLLSize;
3016
+ }
3007
3017
  }
3008
3018
  }
3009
3019
 
@@ -3029,9 +3039,12 @@ static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
3029
3039
  {
3030
3040
  /* blockType == blockCompressed */
3031
3041
  const BYTE* ip = (const BYTE*)src;
3042
+ size_t litCSize;
3043
+
3044
+ if (srcSize > BLOCKSIZE) return ERROR(corruption_detected);
3032
3045
 
3033
3046
  /* Decode literals sub-block */
3034
- size_t litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
3047
+ litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
3035
3048
  if (ZSTD_isError(litCSize)) return litCSize;
3036
3049
  ip += litCSize;
3037
3050
  srcSize -= litCSize;
@@ -3119,34 +3132,57 @@ static size_t ZSTD_decompress_usingDict(ZSTD_DCtx* ctx,
3119
3132
  return op-ostart;
3120
3133
  }
3121
3134
 
3122
- static size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize)
3135
+ /* ZSTD_errorFrameSizeInfoLegacy() :
3136
+ assumes `cSize` and `dBound` are _not_ NULL */
3137
+ static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)
3138
+ {
3139
+ *cSize = ret;
3140
+ *dBound = ZSTD_CONTENTSIZE_ERROR;
3141
+ }
3142
+
3143
+ void ZSTDv04_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)
3123
3144
  {
3124
3145
  const BYTE* ip = (const BYTE*)src;
3125
3146
  size_t remainingSize = srcSize;
3147
+ size_t nbBlocks = 0;
3126
3148
  blockProperties_t blockProperties;
3127
3149
 
3128
3150
  /* Frame Header */
3129
- if (srcSize < ZSTD_frameHeaderSize_min) return ERROR(srcSize_wrong);
3130
- if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) return ERROR(prefix_unknown);
3151
+ if (srcSize < ZSTD_frameHeaderSize_min) {
3152
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3153
+ return;
3154
+ }
3155
+ if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
3156
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));
3157
+ return;
3158
+ }
3131
3159
  ip += ZSTD_frameHeaderSize_min; remainingSize -= ZSTD_frameHeaderSize_min;
3132
3160
 
3133
3161
  /* Loop on each block */
3134
3162
  while (1)
3135
3163
  {
3136
3164
  size_t cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
3137
- if (ZSTD_isError(cBlockSize)) return cBlockSize;
3165
+ if (ZSTD_isError(cBlockSize)) {
3166
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);
3167
+ return;
3168
+ }
3138
3169
 
3139
3170
  ip += ZSTD_blockHeaderSize;
3140
3171
  remainingSize -= ZSTD_blockHeaderSize;
3141
- if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
3172
+ if (cBlockSize > remainingSize) {
3173
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3174
+ return;
3175
+ }
3142
3176
 
3143
3177
  if (cBlockSize == 0) break; /* bt_end */
3144
3178
 
3145
3179
  ip += cBlockSize;
3146
3180
  remainingSize -= cBlockSize;
3181
+ nbBlocks++;
3147
3182
  }
3148
3183
 
3149
- return ip - (const BYTE*)src;
3184
+ *cSize = ip - (const BYTE*)src;
3185
+ *dBound = nbBlocks * BLOCKSIZE;
3150
3186
  }
3151
3187
 
3152
3188
  /* ******************************
@@ -3375,7 +3411,9 @@ static size_t ZBUFF_decompressWithDictionary(ZBUFF_DCtx* zbc, const void* src, s
3375
3411
  static size_t ZBUFF_limitCopy(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
3376
3412
  {
3377
3413
  size_t length = MIN(maxDstSize, srcSize);
3378
- memcpy(dst, src, length);
3414
+ if (length > 0) {
3415
+ memcpy(dst, src, length);
3416
+ }
3379
3417
  return length;
3380
3418
  }
3381
3419
 
@@ -3578,11 +3616,6 @@ size_t ZSTDv04_decompress(void* dst, size_t maxDstSize, const void* src, size_t
3578
3616
  #endif
3579
3617
  }
3580
3618
 
3581
- size_t ZSTDv04_findFrameCompressedSize(const void* src, size_t srcSize)
3582
- {
3583
- return ZSTD_findFrameCompressedSize(src, srcSize);
3584
- }
3585
-
3586
3619
  size_t ZSTDv04_resetDCtx(ZSTDv04_Dctx* dctx) { return ZSTD_resetDCtx(dctx); }
3587
3620
 
3588
3621
  size_t ZSTDv04_nextSrcSizeToDecompress(ZSTDv04_Dctx* dctx)
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -35,13 +35,18 @@ ZSTDv04_decompress() : decompress ZSTD frames compliant with v0.4.x format
35
35
  size_t ZSTDv04_decompress( void* dst, size_t maxOriginalSize,
36
36
  const void* src, size_t compressedSize);
37
37
 
38
- /**
39
- ZSTDv04_getFrameSrcSize() : get the source length of a ZSTD frame compliant with v0.4.x format
40
- compressedSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src'
41
- return : the number of bytes that would be read to decompress this frame
42
- or an errorCode if it fails (which can be tested using ZSTDv04_isError())
43
- */
44
- size_t ZSTDv04_findFrameCompressedSize(const void* src, size_t compressedSize);
38
+ /**
39
+ ZSTDv04_findFrameSizeInfoLegacy() : get the source length and decompressed bound of a ZSTD frame compliant with v0.4.x format
40
+ srcSize : The size of the 'src' buffer, at least as large as the frame pointed to by 'src'
41
+ cSize (output parameter) : the number of bytes that would be read to decompress this frame
42
+ or an error code if it fails (which can be tested using ZSTDv01_isError())
43
+ dBound (output parameter) : an upper-bound for the decompressed size of the data in the frame
44
+ or ZSTD_CONTENTSIZE_ERROR if an error occurs
45
+
46
+ note : assumes `cSize` and `dBound` are _not_ NULL.
47
+ */
48
+ void ZSTDv04_findFrameSizeInfoLegacy(const void *src, size_t srcSize,
49
+ size_t* cSize, unsigned long long* dBound);
45
50
 
46
51
  /**
47
52
  ZSTDv04_isError() : tells if the result of ZSTDv04_decompress() is an error
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
2
+ * Copyright (c) 2016-2020, Yann Collet, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under both the BSD-style license (found in the
@@ -11,7 +11,7 @@
11
11
 
12
12
  /*- Dependencies -*/
13
13
  #include "zstd_v05.h"
14
- #include "error_private.h"
14
+ #include "../common/error_private.h"
15
15
 
16
16
 
17
17
  /* ******************************************************************
@@ -491,6 +491,8 @@ static const size_t ZSTDv05_frameHeaderSize_min = 5;
491
491
 
492
492
  #define WILDCOPY_OVERLENGTH 8
493
493
 
494
+ #define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
495
+
494
496
  typedef enum { bt_compressed, bt_raw, bt_rle, bt_end } blockType_t;
495
497
 
496
498
 
@@ -754,7 +756,7 @@ MEM_STATIC unsigned BITv05_highbit32 (U32 val)
754
756
  _BitScanReverse ( &r, val );
755
757
  return (unsigned) r;
756
758
  # elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
757
- return 31 - __builtin_clz (val);
759
+ return __builtin_clz (val) ^ 31;
758
760
  # else /* Software version */
759
761
  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 };
760
762
  U32 v = val;
@@ -1802,7 +1804,7 @@ static size_t HUFv05_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
1802
1804
 
1803
1805
  if (!srcSize) return ERROR(srcSize_wrong);
1804
1806
  iSize = ip[0];
1805
- //memset(huffWeight, 0, hwSize); /* is not necessary, even though some analyzer complain ... */
1807
+ /* memset(huffWeight, 0, hwSize); */ /* is not necessary, even though some analyzer complain ... */
1806
1808
 
1807
1809
  if (iSize >= 128) { /* special header */
1808
1810
  if (iSize >= (242)) { /* RLE */
@@ -1877,7 +1879,7 @@ size_t HUFv05_readDTableX2 (U16* DTable, const void* src, size_t srcSize)
1877
1879
  HUFv05_DEltX2* const dt = (HUFv05_DEltX2*)dtPtr;
1878
1880
 
1879
1881
  HUFv05_STATIC_ASSERT(sizeof(HUFv05_DEltX2) == sizeof(U16)); /* if compilation fails here, assertion is false */
1880
- //memset(huffWeight, 0, sizeof(huffWeight)); /* is not necessary, even though some analyzer complain ... */
1882
+ /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
1881
1883
 
1882
1884
  iSize = HUFv05_readStats(huffWeight, HUFv05_MAX_SYMBOL_VALUE + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
1883
1885
  if (HUFv05_isError(iSize)) return iSize;
@@ -1996,91 +1998,92 @@ size_t HUFv05_decompress4X2_usingDTable(
1996
1998
  const void* cSrc, size_t cSrcSize,
1997
1999
  const U16* DTable)
1998
2000
  {
1999
- const BYTE* const istart = (const BYTE*) cSrc;
2000
- BYTE* const ostart = (BYTE*) dst;
2001
- BYTE* const oend = ostart + dstSize;
2002
- const void* const dtPtr = DTable;
2003
- const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr) +1;
2004
- const U32 dtLog = DTable[0];
2005
- size_t errorCode;
2006
-
2007
- /* Init */
2008
- BITv05_DStream_t bitD1;
2009
- BITv05_DStream_t bitD2;
2010
- BITv05_DStream_t bitD3;
2011
- BITv05_DStream_t bitD4;
2012
- const size_t length1 = MEM_readLE16(istart);
2013
- const size_t length2 = MEM_readLE16(istart+2);
2014
- const size_t length3 = MEM_readLE16(istart+4);
2015
- size_t length4;
2016
- const BYTE* const istart1 = istart + 6; /* jumpTable */
2017
- const BYTE* const istart2 = istart1 + length1;
2018
- const BYTE* const istart3 = istart2 + length2;
2019
- const BYTE* const istart4 = istart3 + length3;
2020
- const size_t segmentSize = (dstSize+3) / 4;
2021
- BYTE* const opStart2 = ostart + segmentSize;
2022
- BYTE* const opStart3 = opStart2 + segmentSize;
2023
- BYTE* const opStart4 = opStart3 + segmentSize;
2024
- BYTE* op1 = ostart;
2025
- BYTE* op2 = opStart2;
2026
- BYTE* op3 = opStart3;
2027
- BYTE* op4 = opStart4;
2028
- U32 endSignal;
2029
-
2030
2001
  /* Check */
2031
2002
  if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
2003
+ {
2004
+ const BYTE* const istart = (const BYTE*) cSrc;
2005
+ BYTE* const ostart = (BYTE*) dst;
2006
+ BYTE* const oend = ostart + dstSize;
2007
+ const void* const dtPtr = DTable;
2008
+ const HUFv05_DEltX2* const dt = ((const HUFv05_DEltX2*)dtPtr) +1;
2009
+ const U32 dtLog = DTable[0];
2010
+ size_t errorCode;
2032
2011
 
2033
- length4 = cSrcSize - (length1 + length2 + length3 + 6);
2034
- if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
2035
- errorCode = BITv05_initDStream(&bitD1, istart1, length1);
2036
- if (HUFv05_isError(errorCode)) return errorCode;
2037
- errorCode = BITv05_initDStream(&bitD2, istart2, length2);
2038
- if (HUFv05_isError(errorCode)) return errorCode;
2039
- errorCode = BITv05_initDStream(&bitD3, istart3, length3);
2040
- if (HUFv05_isError(errorCode)) return errorCode;
2041
- errorCode = BITv05_initDStream(&bitD4, istart4, length4);
2042
- if (HUFv05_isError(errorCode)) return errorCode;
2012
+ /* Init */
2013
+ BITv05_DStream_t bitD1;
2014
+ BITv05_DStream_t bitD2;
2015
+ BITv05_DStream_t bitD3;
2016
+ BITv05_DStream_t bitD4;
2017
+ const size_t length1 = MEM_readLE16(istart);
2018
+ const size_t length2 = MEM_readLE16(istart+2);
2019
+ const size_t length3 = MEM_readLE16(istart+4);
2020
+ size_t length4;
2021
+ const BYTE* const istart1 = istart + 6; /* jumpTable */
2022
+ const BYTE* const istart2 = istart1 + length1;
2023
+ const BYTE* const istart3 = istart2 + length2;
2024
+ const BYTE* const istart4 = istart3 + length3;
2025
+ const size_t segmentSize = (dstSize+3) / 4;
2026
+ BYTE* const opStart2 = ostart + segmentSize;
2027
+ BYTE* const opStart3 = opStart2 + segmentSize;
2028
+ BYTE* const opStart4 = opStart3 + segmentSize;
2029
+ BYTE* op1 = ostart;
2030
+ BYTE* op2 = opStart2;
2031
+ BYTE* op3 = opStart3;
2032
+ BYTE* op4 = opStart4;
2033
+ U32 endSignal;
2034
+
2035
+ length4 = cSrcSize - (length1 + length2 + length3 + 6);
2036
+ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
2037
+ errorCode = BITv05_initDStream(&bitD1, istart1, length1);
2038
+ if (HUFv05_isError(errorCode)) return errorCode;
2039
+ errorCode = BITv05_initDStream(&bitD2, istart2, length2);
2040
+ if (HUFv05_isError(errorCode)) return errorCode;
2041
+ errorCode = BITv05_initDStream(&bitD3, istart3, length3);
2042
+ if (HUFv05_isError(errorCode)) return errorCode;
2043
+ errorCode = BITv05_initDStream(&bitD4, istart4, length4);
2044
+ if (HUFv05_isError(errorCode)) return errorCode;
2043
2045
 
2044
- /* 16-32 symbols per loop (4-8 symbols per stream) */
2045
- endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
2046
- for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) {
2047
- HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
2048
- HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
2049
- HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
2050
- HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
2051
- HUFv05_DECODE_SYMBOLX2_1(op1, &bitD1);
2052
- HUFv05_DECODE_SYMBOLX2_1(op2, &bitD2);
2053
- HUFv05_DECODE_SYMBOLX2_1(op3, &bitD3);
2054
- HUFv05_DECODE_SYMBOLX2_1(op4, &bitD4);
2055
- HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
2056
- HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
2057
- HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
2058
- HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
2059
- HUFv05_DECODE_SYMBOLX2_0(op1, &bitD1);
2060
- HUFv05_DECODE_SYMBOLX2_0(op2, &bitD2);
2061
- HUFv05_DECODE_SYMBOLX2_0(op3, &bitD3);
2062
- HUFv05_DECODE_SYMBOLX2_0(op4, &bitD4);
2046
+ /* 16-32 symbols per loop (4-8 symbols per stream) */
2063
2047
  endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
2064
- }
2048
+ for ( ; (endSignal==BITv05_DStream_unfinished) && (op4<(oend-7)) ; ) {
2049
+ HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
2050
+ HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
2051
+ HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
2052
+ HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
2053
+ HUFv05_DECODE_SYMBOLX2_1(op1, &bitD1);
2054
+ HUFv05_DECODE_SYMBOLX2_1(op2, &bitD2);
2055
+ HUFv05_DECODE_SYMBOLX2_1(op3, &bitD3);
2056
+ HUFv05_DECODE_SYMBOLX2_1(op4, &bitD4);
2057
+ HUFv05_DECODE_SYMBOLX2_2(op1, &bitD1);
2058
+ HUFv05_DECODE_SYMBOLX2_2(op2, &bitD2);
2059
+ HUFv05_DECODE_SYMBOLX2_2(op3, &bitD3);
2060
+ HUFv05_DECODE_SYMBOLX2_2(op4, &bitD4);
2061
+ HUFv05_DECODE_SYMBOLX2_0(op1, &bitD1);
2062
+ HUFv05_DECODE_SYMBOLX2_0(op2, &bitD2);
2063
+ HUFv05_DECODE_SYMBOLX2_0(op3, &bitD3);
2064
+ HUFv05_DECODE_SYMBOLX2_0(op4, &bitD4);
2065
+ endSignal = BITv05_reloadDStream(&bitD1) | BITv05_reloadDStream(&bitD2) | BITv05_reloadDStream(&bitD3) | BITv05_reloadDStream(&bitD4);
2066
+ }
2065
2067
 
2066
- /* check corruption */
2067
- if (op1 > opStart2) return ERROR(corruption_detected);
2068
- if (op2 > opStart3) return ERROR(corruption_detected);
2069
- if (op3 > opStart4) return ERROR(corruption_detected);
2070
- /* note : op4 supposed already verified within main loop */
2068
+ /* check corruption */
2069
+ if (op1 > opStart2) return ERROR(corruption_detected);
2070
+ if (op2 > opStart3) return ERROR(corruption_detected);
2071
+ if (op3 > opStart4) return ERROR(corruption_detected);
2072
+ /* note : op4 supposed already verified within main loop */
2071
2073
 
2072
- /* finish bitStreams one by one */
2073
- HUFv05_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
2074
- HUFv05_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
2075
- HUFv05_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
2076
- HUFv05_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
2074
+ /* finish bitStreams one by one */
2075
+ HUFv05_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
2076
+ HUFv05_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
2077
+ HUFv05_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
2078
+ HUFv05_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
2077
2079
 
2078
- /* check */
2079
- endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4);
2080
- if (!endSignal) return ERROR(corruption_detected);
2080
+ /* check */
2081
+ endSignal = BITv05_endOfDStream(&bitD1) & BITv05_endOfDStream(&bitD2) & BITv05_endOfDStream(&bitD3) & BITv05_endOfDStream(&bitD4);
2082
+ if (!endSignal) return ERROR(corruption_detected);
2081
2083
 
2082
- /* decoded size */
2083
- return dstSize;
2084
+ /* decoded size */
2085
+ return dstSize;
2086
+ }
2084
2087
  }
2085
2088
 
2086
2089
 
@@ -2207,7 +2210,7 @@ size_t HUFv05_readDTableX4 (unsigned* DTable, const void* src, size_t srcSize)
2207
2210
 
2208
2211
  HUFv05_STATIC_ASSERT(sizeof(HUFv05_DEltX4) == sizeof(unsigned)); /* if compilation fails here, assertion is false */
2209
2212
  if (memLog > HUFv05_ABSOLUTEMAX_TABLELOG) return ERROR(tableLog_tooLarge);
2210
- //memset(weightList, 0, sizeof(weightList)); /* is not necessary, even though some analyzer complain ... */
2213
+ /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
2211
2214
 
2212
2215
  iSize = HUFv05_readStats(weightList, HUFv05_MAX_SYMBOL_VALUE + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
2213
2216
  if (HUFv05_isError(iSize)) return iSize;
@@ -2536,9 +2539,9 @@ size_t HUFv05_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cS
2536
2539
 
2537
2540
  return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
2538
2541
 
2539
- //return HUFv05_decompress4X2(dst, dstSize, cSrc, cSrcSize); /* multi-streams single-symbol decoding */
2540
- //return HUFv05_decompress4X4(dst, dstSize, cSrc, cSrcSize); /* multi-streams double-symbols decoding */
2541
- //return HUFv05_decompress4X6(dst, dstSize, cSrc, cSrcSize); /* multi-streams quad-symbols decoding */
2542
+ /* return HUFv05_decompress4X2(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams single-symbol decoding */
2543
+ /* return HUFv05_decompress4X4(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams double-symbols decoding */
2544
+ /* return HUFv05_decompress4X6(dst, dstSize, cSrc, cSrcSize); */ /* multi-streams quad-symbols decoding */
2542
2545
  }
2543
2546
  /*
2544
2547
  zstd - standard compression library
@@ -3148,14 +3151,17 @@ static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState)
3148
3151
  litLength = FSEv05_peakSymbol(&(seqState->stateLL));
3149
3152
  prevOffset = litLength ? seq->offset : seqState->prevOffset;
3150
3153
  if (litLength == MaxLL) {
3151
- U32 add = *dumps++;
3154
+ const U32 add = *dumps++;
3152
3155
  if (add < 255) litLength += add;
3153
- else {
3154
- litLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no risk : dumps is always followed by seq tables > 1 byte */
3155
- if (litLength&1) litLength>>=1, dumps += 3;
3156
- else litLength = (U16)(litLength)>>1, dumps += 2;
3156
+ else if (dumps + 2 <= de) {
3157
+ litLength = MEM_readLE16(dumps);
3158
+ dumps += 2;
3159
+ if ((litLength & 1) && dumps < de) {
3160
+ litLength += *dumps << 16;
3161
+ dumps += 1;
3162
+ }
3163
+ litLength>>=1;
3157
3164
  }
3158
- if (dumps > de) { litLength = MaxLL+255; } /* late correction, to avoid using uninitialized memory */
3159
3165
  if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
3160
3166
  }
3161
3167
 
@@ -3182,14 +3188,17 @@ static void ZSTDv05_decodeSequence(seq_t* seq, seqState_t* seqState)
3182
3188
  /* MatchLength */
3183
3189
  matchLength = FSEv05_decodeSymbol(&(seqState->stateML), &(seqState->DStream));
3184
3190
  if (matchLength == MaxML) {
3185
- U32 add = *dumps++;
3191
+ const U32 add = dumps<de ? *dumps++ : 0;
3186
3192
  if (add < 255) matchLength += add;
3187
- else {
3188
- matchLength = MEM_readLE32(dumps) & 0xFFFFFF; /* no pb : dumps is always followed by seq tables > 1 byte */
3189
- if (matchLength&1) matchLength>>=1, dumps += 3;
3190
- else matchLength = (U16)(matchLength)>>1, dumps += 2;
3193
+ else if (dumps + 2 <= de) {
3194
+ matchLength = MEM_readLE16(dumps);
3195
+ dumps += 2;
3196
+ if ((matchLength & 1) && dumps < de) {
3197
+ matchLength += *dumps << 16;
3198
+ dumps += 1;
3199
+ }
3200
+ matchLength >>= 1;
3191
3201
  }
3192
- if (dumps > de) { matchLength = MaxML+255; } /* late correction, to avoid using uninitialized memory */
3193
3202
  if (dumps >= de) { dumps = de-1; } /* late correction, to avoid read overflow (data is now corrupted anyway) */
3194
3203
  }
3195
3204
  matchLength += MINMATCH;
@@ -3217,7 +3226,7 @@ static size_t ZSTDv05_execSequence(BYTE* op,
3217
3226
  const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
3218
3227
  {
3219
3228
  static const int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
3220
- static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* substracted */
3229
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
3221
3230
  BYTE* const oLitEnd = op + sequence.litLength;
3222
3231
  const size_t sequenceLength = sequence.litLength + sequence.matchLength;
3223
3232
  BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
@@ -3353,8 +3362,10 @@ static size_t ZSTDv05_decompressSequences(
3353
3362
  size_t lastLLSize = litEnd - litPtr;
3354
3363
  if (litPtr > litEnd) return ERROR(corruption_detected); /* too many literals already used */
3355
3364
  if (op+lastLLSize > oend) return ERROR(dstSize_tooSmall);
3356
- memcpy(op, litPtr, lastLLSize);
3357
- op += lastLLSize;
3365
+ if (lastLLSize > 0) {
3366
+ memcpy(op, litPtr, lastLLSize);
3367
+ op += lastLLSize;
3368
+ }
3358
3369
  }
3359
3370
 
3360
3371
  return op-ostart;
@@ -3508,34 +3519,57 @@ size_t ZSTDv05_decompress(void* dst, size_t maxDstSize, const void* src, size_t
3508
3519
  #endif
3509
3520
  }
3510
3521
 
3511
- size_t ZSTDv05_findFrameCompressedSize(const void *src, size_t srcSize)
3522
+ /* ZSTD_errorFrameSizeInfoLegacy() :
3523
+ assumes `cSize` and `dBound` are _not_ NULL */
3524
+ static void ZSTD_errorFrameSizeInfoLegacy(size_t* cSize, unsigned long long* dBound, size_t ret)
3525
+ {
3526
+ *cSize = ret;
3527
+ *dBound = ZSTD_CONTENTSIZE_ERROR;
3528
+ }
3529
+
3530
+ void ZSTDv05_findFrameSizeInfoLegacy(const void *src, size_t srcSize, size_t* cSize, unsigned long long* dBound)
3512
3531
  {
3513
3532
  const BYTE* ip = (const BYTE*)src;
3514
3533
  size_t remainingSize = srcSize;
3534
+ size_t nbBlocks = 0;
3515
3535
  blockProperties_t blockProperties;
3516
3536
 
3517
3537
  /* Frame Header */
3518
- if (srcSize < ZSTDv05_frameHeaderSize_min) return ERROR(srcSize_wrong);
3519
- if (MEM_readLE32(src) != ZSTDv05_MAGICNUMBER) return ERROR(prefix_unknown);
3538
+ if (srcSize < ZSTDv05_frameHeaderSize_min) {
3539
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3540
+ return;
3541
+ }
3542
+ if (MEM_readLE32(src) != ZSTDv05_MAGICNUMBER) {
3543
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(prefix_unknown));
3544
+ return;
3545
+ }
3520
3546
  ip += ZSTDv05_frameHeaderSize_min; remainingSize -= ZSTDv05_frameHeaderSize_min;
3521
3547
 
3522
3548
  /* Loop on each block */
3523
3549
  while (1)
3524
3550
  {
3525
3551
  size_t cBlockSize = ZSTDv05_getcBlockSize(ip, remainingSize, &blockProperties);
3526
- if (ZSTDv05_isError(cBlockSize)) return cBlockSize;
3552
+ if (ZSTDv05_isError(cBlockSize)) {
3553
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, cBlockSize);
3554
+ return;
3555
+ }
3527
3556
 
3528
3557
  ip += ZSTDv05_blockHeaderSize;
3529
3558
  remainingSize -= ZSTDv05_blockHeaderSize;
3530
- if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
3559
+ if (cBlockSize > remainingSize) {
3560
+ ZSTD_errorFrameSizeInfoLegacy(cSize, dBound, ERROR(srcSize_wrong));
3561
+ return;
3562
+ }
3531
3563
 
3532
3564
  if (cBlockSize == 0) break; /* bt_end */
3533
3565
 
3534
3566
  ip += cBlockSize;
3535
3567
  remainingSize -= cBlockSize;
3568
+ nbBlocks++;
3536
3569
  }
3537
3570
 
3538
- return ip - (const BYTE*)src;
3571
+ *cSize = ip - (const BYTE*)src;
3572
+ *dBound = nbBlocks * BLOCKSIZE;
3539
3573
  }
3540
3574
 
3541
3575
  /* ******************************
@@ -3759,7 +3793,9 @@ static size_t ZBUFFv05_blockHeaderSize = 3;
3759
3793
  static size_t ZBUFFv05_limitCopy(void* dst, size_t maxDstSize, const void* src, size_t srcSize)
3760
3794
  {
3761
3795
  size_t length = MIN(maxDstSize, srcSize);
3762
- memcpy(dst, src, length);
3796
+ if (length > 0) {
3797
+ memcpy(dst, src, length);
3798
+ }
3763
3799
  return length;
3764
3800
  }
3765
3801
 
@@ -3896,7 +3932,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
3896
3932
  *maxDstSizePtr = 0;
3897
3933
  return headerSize - zbc->hPos;
3898
3934
  }
3899
- // zbc->stage = ZBUFFv05ds_decodeHeader; break; /* useless : stage follows */
3935
+ /* zbc->stage = ZBUFFv05ds_decodeHeader; break; */ /* useless : stage follows */
3900
3936
  }
3901
3937
  /* fall-through */
3902
3938
  case ZBUFFv05ds_decodeHeader:
@@ -3969,7 +4005,7 @@ size_t ZBUFFv05_decompressContinue(ZBUFFv05_DCtx* zbc, void* dst, size_t* maxDst
3969
4005
  if (!decodedSize) { zbc->stage = ZBUFFv05ds_read; break; } /* this was just a header */
3970
4006
  zbc->outEnd = zbc->outStart + decodedSize;
3971
4007
  zbc->stage = ZBUFFv05ds_flush;
3972
- // break; /* ZBUFFv05ds_flush follows */
4008
+ /* break; */ /* ZBUFFv05ds_flush follows */
3973
4009
  }
3974
4010
  }
3975
4011
  /* fall-through */