zstd-ruby 1.3.8.0 → 1.4.5.0

Sign up to get free protection for your applications and to get access to all the features.
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 */