zstd-ruby 1.5.5.1 → 1.5.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/zstdruby/libzstd/common/allocations.h +1 -1
  4. data/ext/zstdruby/libzstd/common/bitstream.h +49 -29
  5. data/ext/zstdruby/libzstd/common/compiler.h +114 -22
  6. data/ext/zstdruby/libzstd/common/cpu.h +36 -0
  7. data/ext/zstdruby/libzstd/common/debug.c +6 -0
  8. data/ext/zstdruby/libzstd/common/debug.h +20 -11
  9. data/ext/zstdruby/libzstd/common/error_private.h +45 -36
  10. data/ext/zstdruby/libzstd/common/fse.h +3 -2
  11. data/ext/zstdruby/libzstd/common/fse_decompress.c +19 -17
  12. data/ext/zstdruby/libzstd/common/huf.h +14 -1
  13. data/ext/zstdruby/libzstd/common/mem.h +0 -9
  14. data/ext/zstdruby/libzstd/common/pool.c +1 -1
  15. data/ext/zstdruby/libzstd/common/pool.h +1 -1
  16. data/ext/zstdruby/libzstd/common/portability_macros.h +2 -0
  17. data/ext/zstdruby/libzstd/common/threading.c +8 -2
  18. data/ext/zstdruby/libzstd/common/xxhash.c +5 -11
  19. data/ext/zstdruby/libzstd/common/xxhash.h +2341 -1007
  20. data/ext/zstdruby/libzstd/common/zstd_internal.h +5 -5
  21. data/ext/zstdruby/libzstd/compress/fse_compress.c +8 -7
  22. data/ext/zstdruby/libzstd/compress/huf_compress.c +54 -25
  23. data/ext/zstdruby/libzstd/compress/zstd_compress.c +282 -161
  24. data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +29 -27
  25. data/ext/zstdruby/libzstd/compress/zstd_compress_superblock.c +224 -113
  26. data/ext/zstdruby/libzstd/compress/zstd_cwksp.h +19 -13
  27. data/ext/zstdruby/libzstd/compress/zstd_double_fast.c +17 -5
  28. data/ext/zstdruby/libzstd/compress/zstd_double_fast.h +11 -0
  29. data/ext/zstdruby/libzstd/compress/zstd_fast.c +14 -6
  30. data/ext/zstdruby/libzstd/compress/zstd_lazy.c +129 -87
  31. data/ext/zstdruby/libzstd/compress/zstd_lazy.h +103 -28
  32. data/ext/zstdruby/libzstd/compress/zstd_ldm.c +8 -2
  33. data/ext/zstdruby/libzstd/compress/zstd_opt.c +216 -112
  34. data/ext/zstdruby/libzstd/compress/zstd_opt.h +31 -7
  35. data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +94 -79
  36. data/ext/zstdruby/libzstd/decompress/huf_decompress.c +188 -126
  37. data/ext/zstdruby/libzstd/decompress/huf_decompress_amd64.S +38 -19
  38. data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +84 -32
  39. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +231 -208
  40. data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.h +1 -1
  41. data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +2 -0
  42. data/ext/zstdruby/libzstd/dictBuilder/cover.c +16 -12
  43. data/ext/zstdruby/libzstd/dictBuilder/cover.h +2 -8
  44. data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +2 -2
  45. data/ext/zstdruby/libzstd/dictBuilder/zdict.c +12 -6
  46. data/ext/zstdruby/libzstd/zstd.h +129 -60
  47. data/lib/zstd-ruby/version.rb +1 -1
  48. metadata +1 -1
@@ -10,11 +10,32 @@
10
10
 
11
11
  #include "../common/portability_macros.h"
12
12
 
13
+ #if defined(__ELF__) && defined(__GNUC__)
13
14
  /* Stack marking
14
15
  * ref: https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart
15
16
  */
16
- #if defined(__ELF__) && defined(__GNUC__)
17
17
  .section .note.GNU-stack,"",%progbits
18
+
19
+ #if defined(__aarch64__)
20
+ /* Mark that this assembly supports BTI & PAC, because it is empty for aarch64.
21
+ * See: https://github.com/facebook/zstd/issues/3841
22
+ * See: https://gcc.godbolt.org/z/sqr5T4ffK
23
+ * See: https://lore.kernel.org/linux-arm-kernel/20200429211641.9279-8-broonie@kernel.org/
24
+ * See: https://reviews.llvm.org/D62609
25
+ */
26
+ .pushsection .note.gnu.property, "a"
27
+ .p2align 3
28
+ .long 4 /* size of the name - "GNU\0" */
29
+ .long 0x10 /* size of descriptor */
30
+ .long 0x5 /* NT_GNU_PROPERTY_TYPE_0 */
31
+ .asciz "GNU"
32
+ .long 0xc0000000 /* pr_type - GNU_PROPERTY_AARCH64_FEATURE_1_AND */
33
+ .long 4 /* pr_datasz - 4 bytes */
34
+ .long 3 /* pr_data - GNU_PROPERTY_AARCH64_FEATURE_1_BTI | GNU_PROPERTY_AARCH64_FEATURE_1_PAC */
35
+ .p2align 3 /* pr_padding - bring everything to 8 byte alignment */
36
+ .popsection
37
+ #endif
38
+
18
39
  #endif
19
40
 
20
41
  #if ZSTD_ENABLE_ASM_X86_64_BMI2
@@ -131,7 +152,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
131
152
  movq 88(%rax), %bits3
132
153
  movq 96(%rax), %dtable
133
154
  push %rax /* argument */
134
- push 104(%rax) /* ilimit */
155
+ push 104(%rax) /* ilowest */
135
156
  push 112(%rax) /* oend */
136
157
  push %olimit /* olimit space */
137
158
 
@@ -156,11 +177,11 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
156
177
  shrq $2, %r15
157
178
 
158
179
  movq %ip0, %rax /* rax = ip0 */
159
- movq 40(%rsp), %rdx /* rdx = ilimit */
160
- subq %rdx, %rax /* rax = ip0 - ilimit */
161
- movq %rax, %rbx /* rbx = ip0 - ilimit */
180
+ movq 40(%rsp), %rdx /* rdx = ilowest */
181
+ subq %rdx, %rax /* rax = ip0 - ilowest */
182
+ movq %rax, %rbx /* rbx = ip0 - ilowest */
162
183
 
163
- /* rdx = (ip0 - ilimit) / 7 */
184
+ /* rdx = (ip0 - ilowest) / 7 */
164
185
  movabsq $2635249153387078803, %rdx
165
186
  mulq %rdx
166
187
  subq %rdx, %rbx
@@ -183,9 +204,8 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
183
204
 
184
205
  /* If (op3 + 20 > olimit) */
185
206
  movq %op3, %rax /* rax = op3 */
186
- addq $20, %rax /* rax = op3 + 20 */
187
- cmpq %rax, %olimit /* op3 + 20 > olimit */
188
- jb .L_4X1_exit
207
+ cmpq %rax, %olimit /* op3 == olimit */
208
+ je .L_4X1_exit
189
209
 
190
210
  /* If (ip1 < ip0) go to exit */
191
211
  cmpq %ip0, %ip1
@@ -316,7 +336,7 @@ HUF_decompress4X1_usingDTable_internal_fast_asm_loop:
316
336
  /* Restore stack (oend & olimit) */
317
337
  pop %rax /* olimit */
318
338
  pop %rax /* oend */
319
- pop %rax /* ilimit */
339
+ pop %rax /* ilowest */
320
340
  pop %rax /* arg */
321
341
 
322
342
  /* Save ip / op / bits */
@@ -387,7 +407,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
387
407
  movq 96(%rax), %dtable
388
408
  push %rax /* argument */
389
409
  push %rax /* olimit */
390
- push 104(%rax) /* ilimit */
410
+ push 104(%rax) /* ilowest */
391
411
 
392
412
  movq 112(%rax), %rax
393
413
  push %rax /* oend3 */
@@ -414,9 +434,9 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
414
434
 
415
435
  /* We can consume up to 7 input bytes each iteration. */
416
436
  movq %ip0, %rax /* rax = ip0 */
417
- movq 40(%rsp), %rdx /* rdx = ilimit */
418
- subq %rdx, %rax /* rax = ip0 - ilimit */
419
- movq %rax, %r15 /* r15 = ip0 - ilimit */
437
+ movq 40(%rsp), %rdx /* rdx = ilowest */
438
+ subq %rdx, %rax /* rax = ip0 - ilowest */
439
+ movq %rax, %r15 /* r15 = ip0 - ilowest */
420
440
 
421
441
  /* rdx = rax / 7 */
422
442
  movabsq $2635249153387078803, %rdx
@@ -426,7 +446,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
426
446
  addq %r15, %rdx
427
447
  shrq $2, %rdx
428
448
 
429
- /* r15 = (ip0 - ilimit) / 7 */
449
+ /* r15 = (ip0 - ilowest) / 7 */
430
450
  movq %rdx, %r15
431
451
 
432
452
  /* r15 = min(r15, min(oend0 - op0, oend1 - op1, oend2 - op2, oend3 - op3) / 10) */
@@ -467,9 +487,8 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
467
487
 
468
488
  /* If (op3 + 10 > olimit) */
469
489
  movq %op3, %rax /* rax = op3 */
470
- addq $10, %rax /* rax = op3 + 10 */
471
- cmpq %rax, %olimit /* op3 + 10 > olimit */
472
- jb .L_4X2_exit
490
+ cmpq %rax, %olimit /* op3 == olimit */
491
+ je .L_4X2_exit
473
492
 
474
493
  /* If (ip1 < ip0) go to exit */
475
494
  cmpq %ip0, %ip1
@@ -537,7 +556,7 @@ HUF_decompress4X2_usingDTable_internal_fast_asm_loop:
537
556
  pop %rax /* oend1 */
538
557
  pop %rax /* oend2 */
539
558
  pop %rax /* oend3 */
540
- pop %rax /* ilimit */
559
+ pop %rax /* ilowest */
541
560
  pop %rax /* olimit */
542
561
  pop %rax /* arg */
543
562
 
@@ -55,18 +55,19 @@
55
55
  /*-*******************************************************
56
56
  * Dependencies
57
57
  *********************************************************/
58
- #include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
59
58
  #include "../common/zstd_deps.h" /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
59
+ #include "../common/allocations.h" /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
60
+ #include "../common/error_private.h"
61
+ #include "../common/zstd_internal.h" /* blockProperties_t */
60
62
  #include "../common/mem.h" /* low level memory routines */
63
+ #include "../common/bits.h" /* ZSTD_highbit32 */
61
64
  #define FSE_STATIC_LINKING_ONLY
62
65
  #include "../common/fse.h"
63
66
  #include "../common/huf.h"
64
67
  #include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
65
- #include "../common/zstd_internal.h" /* blockProperties_t */
66
68
  #include "zstd_decompress_internal.h" /* ZSTD_DCtx */
67
69
  #include "zstd_ddict.h" /* ZSTD_DDictDictContent */
68
70
  #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
69
- #include "../common/bits.h" /* ZSTD_highbit32 */
70
71
 
71
72
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
72
73
  # include "../legacy/zstd_legacy.h"
@@ -245,6 +246,7 @@ static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
245
246
  dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
246
247
  dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
247
248
  dctx->disableHufAsm = 0;
249
+ dctx->maxBlockSizeParam = 0;
248
250
  }
249
251
 
250
252
  static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
@@ -265,6 +267,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
265
267
  #endif
266
268
  dctx->noForwardProgress = 0;
267
269
  dctx->oversizedDuration = 0;
270
+ dctx->isFrameDecompression = 1;
268
271
  #if DYNAMIC_BMI2
269
272
  dctx->bmi2 = ZSTD_cpuSupportsBmi2();
270
273
  #endif
@@ -726,17 +729,17 @@ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
726
729
  return frameSizeInfo;
727
730
  }
728
731
 
729
- static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
732
+ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format)
730
733
  {
731
734
  ZSTD_frameSizeInfo frameSizeInfo;
732
735
  ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
733
736
 
734
737
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
735
- if (ZSTD_isLegacy(src, srcSize))
738
+ if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize))
736
739
  return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
737
740
  #endif
738
741
 
739
- if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
742
+ if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
740
743
  && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
741
744
  frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
742
745
  assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
@@ -750,7 +753,7 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
750
753
  ZSTD_frameHeader zfh;
751
754
 
752
755
  /* Extract Frame Header */
753
- { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
756
+ { size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format);
754
757
  if (ZSTD_isError(ret))
755
758
  return ZSTD_errorFrameSizeInfo(ret);
756
759
  if (ret > 0)
@@ -793,15 +796,17 @@ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize
793
796
  }
794
797
  }
795
798
 
799
+ static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) {
800
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format);
801
+ return frameSizeInfo.compressedSize;
802
+ }
803
+
796
804
  /** ZSTD_findFrameCompressedSize() :
797
- * compatible with legacy mode
798
- * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
799
- * `srcSize` must be at least as large as the frame contained
800
- * @return : the compressed size of the frame starting at `src` */
805
+ * See docs in zstd.h
806
+ * Note: compatible with legacy mode */
801
807
  size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
802
808
  {
803
- ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
804
- return frameSizeInfo.compressedSize;
809
+ return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1);
805
810
  }
806
811
 
807
812
  /** ZSTD_decompressBound() :
@@ -815,7 +820,7 @@ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
815
820
  unsigned long long bound = 0;
816
821
  /* Iterate over each frame */
817
822
  while (srcSize > 0) {
818
- ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
823
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
819
824
  size_t const compressedSize = frameSizeInfo.compressedSize;
820
825
  unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
821
826
  if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
@@ -835,7 +840,7 @@ size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
835
840
 
836
841
  /* Iterate over each frame */
837
842
  while (srcSize > 0) {
838
- ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
843
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
839
844
  size_t const compressedSize = frameSizeInfo.compressedSize;
840
845
  unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
841
846
  ZSTD_frameHeader zfh;
@@ -971,6 +976,10 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
971
976
  ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
972
977
  }
973
978
 
979
+ /* Shrink the blockSizeMax if enabled */
980
+ if (dctx->maxBlockSizeParam != 0)
981
+ dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam);
982
+
974
983
  /* Loop on each block */
975
984
  while (1) {
976
985
  BYTE* oBlockEnd = oend;
@@ -1003,7 +1012,8 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1003
1012
  switch(blockProperties.blockType)
1004
1013
  {
1005
1014
  case bt_compressed:
1006
- decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, /* frame */ 1, not_streaming);
1015
+ assert(dctx->isFrameDecompression == 1);
1016
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming);
1007
1017
  break;
1008
1018
  case bt_raw :
1009
1019
  /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
@@ -1016,12 +1026,14 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1016
1026
  default:
1017
1027
  RETURN_ERROR(corruption_detected, "invalid block type");
1018
1028
  }
1019
-
1020
- if (ZSTD_isError(decodedSize)) return decodedSize;
1021
- if (dctx->validateChecksum)
1029
+ FORWARD_IF_ERROR(decodedSize, "Block decompression failure");
1030
+ DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize);
1031
+ if (dctx->validateChecksum) {
1022
1032
  XXH64_update(&dctx->xxhState, op, decodedSize);
1023
- if (decodedSize != 0)
1033
+ }
1034
+ if (decodedSize) /* support dst = NULL,0 */ {
1024
1035
  op += decodedSize;
1036
+ }
1025
1037
  assert(ip != NULL);
1026
1038
  ip += cBlockSize;
1027
1039
  remainingSrcSize -= cBlockSize;
@@ -1051,7 +1063,9 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1051
1063
  return (size_t)(op-ostart);
1052
1064
  }
1053
1065
 
1054
- static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1066
+ static
1067
+ ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
1068
+ size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1055
1069
  void* dst, size_t dstCapacity,
1056
1070
  const void* src, size_t srcSize,
1057
1071
  const void* dict, size_t dictSize,
@@ -1071,7 +1085,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1071
1085
  while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
1072
1086
 
1073
1087
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1074
- if (ZSTD_isLegacy(src, srcSize)) {
1088
+ if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) {
1075
1089
  size_t decodedSize;
1076
1090
  size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
1077
1091
  if (ZSTD_isError(frameSize)) return frameSize;
@@ -1081,6 +1095,15 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1081
1095
  decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
1082
1096
  if (ZSTD_isError(decodedSize)) return decodedSize;
1083
1097
 
1098
+ {
1099
+ unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize);
1100
+ RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!");
1101
+ if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1102
+ RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected,
1103
+ "Frame header size does not match decoded size!");
1104
+ }
1105
+ }
1106
+
1084
1107
  assert(decodedSize <= dstCapacity);
1085
1108
  dst = (BYTE*)dst + decodedSize;
1086
1109
  dstCapacity -= decodedSize;
@@ -1092,7 +1115,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1092
1115
  }
1093
1116
  #endif
1094
1117
 
1095
- if (srcSize >= 4) {
1118
+ if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) {
1096
1119
  U32 const magicNumber = MEM_readLE32(src);
1097
1120
  DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
1098
1121
  if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
@@ -1319,7 +1342,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1319
1342
  {
1320
1343
  case bt_compressed:
1321
1344
  DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
1322
- rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1, is_streaming);
1345
+ assert(dctx->isFrameDecompression == 1);
1346
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming);
1323
1347
  dctx->expected = 0; /* Streaming not supported */
1324
1348
  break;
1325
1349
  case bt_raw :
@@ -1388,6 +1412,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1388
1412
  case ZSTDds_decodeSkippableHeader:
1389
1413
  assert(src != NULL);
1390
1414
  assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
1415
+ assert(dctx->format != ZSTD_f_zstd1_magicless);
1391
1416
  ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
1392
1417
  dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
1393
1418
  dctx->stage = ZSTDds_skipFrame;
@@ -1548,6 +1573,7 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1548
1573
  dctx->litEntropy = dctx->fseEntropy = 0;
1549
1574
  dctx->dictID = 0;
1550
1575
  dctx->bType = bt_reserved;
1576
+ dctx->isFrameDecompression = 1;
1551
1577
  ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
1552
1578
  ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
1553
1579
  dctx->LLTptr = dctx->entropy.LLTable;
@@ -1819,6 +1845,10 @@ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
1819
1845
  bounds.lowerBound = 0;
1820
1846
  bounds.upperBound = 1;
1821
1847
  return bounds;
1848
+ case ZSTD_d_maxBlockSize:
1849
+ bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
1850
+ bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
1851
+ return bounds;
1822
1852
 
1823
1853
  default:;
1824
1854
  }
@@ -1863,6 +1893,9 @@ size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value
1863
1893
  case ZSTD_d_disableHuffmanAssembly:
1864
1894
  *value = (int)dctx->disableHufAsm;
1865
1895
  return 0;
1896
+ case ZSTD_d_maxBlockSize:
1897
+ *value = dctx->maxBlockSizeParam;
1898
+ return 0;
1866
1899
  default:;
1867
1900
  }
1868
1901
  RETURN_ERROR(parameter_unsupported, "");
@@ -1900,6 +1933,10 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
1900
1933
  CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
1901
1934
  dctx->disableHufAsm = value != 0;
1902
1935
  return 0;
1936
+ case ZSTD_d_maxBlockSize:
1937
+ if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value);
1938
+ dctx->maxBlockSizeParam = value;
1939
+ return 0;
1903
1940
  default:;
1904
1941
  }
1905
1942
  RETURN_ERROR(parameter_unsupported, "");
@@ -1911,6 +1948,7 @@ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
1911
1948
  || (reset == ZSTD_reset_session_and_parameters) ) {
1912
1949
  dctx->streamStage = zdss_init;
1913
1950
  dctx->noForwardProgress = 0;
1951
+ dctx->isFrameDecompression = 1;
1914
1952
  }
1915
1953
  if ( (reset == ZSTD_reset_parameters)
1916
1954
  || (reset == ZSTD_reset_session_and_parameters) ) {
@@ -1927,11 +1965,17 @@ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
1927
1965
  return ZSTD_sizeof_DCtx(dctx);
1928
1966
  }
1929
1967
 
1930
- size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1968
+ static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax)
1931
1969
  {
1932
- size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
1933
- /* space is needed to store the litbuffer after the output of a given block without stomping the extDict of a previous run, as well as to cover both windows against wildcopy*/
1934
- unsigned long long const neededRBSize = windowSize + blockSize + ZSTD_BLOCKSIZE_MAX + (WILDCOPY_OVERLENGTH * 2);
1970
+ size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax);
1971
+ /* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block
1972
+ * ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing
1973
+ * the block at the beginning of the output buffer, and maintain a full window.
1974
+ *
1975
+ * We need another blockSize worth of buffer so that we can store split
1976
+ * literals at the end of the block without overwriting the extDict window.
1977
+ */
1978
+ unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2);
1935
1979
  unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
1936
1980
  size_t const minRBSize = (size_t) neededSize;
1937
1981
  RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
@@ -1939,6 +1983,11 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
1939
1983
  return minRBSize;
1940
1984
  }
1941
1985
 
1986
+ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1987
+ {
1988
+ return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX);
1989
+ }
1990
+
1942
1991
  size_t ZSTD_estimateDStreamSize(size_t windowSize)
1943
1992
  {
1944
1993
  size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
@@ -2134,12 +2183,12 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2134
2183
  if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2135
2184
  && zds->fParams.frameType != ZSTD_skippableFrame
2136
2185
  && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
2137
- size_t const cSize = ZSTD_findFrameCompressedSize(istart, (size_t)(iend-istart));
2186
+ size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format);
2138
2187
  if (cSize <= (size_t)(iend-istart)) {
2139
2188
  /* shortcut : using single-pass mode */
2140
2189
  size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
2141
2190
  if (ZSTD_isError(decompressedSize)) return decompressedSize;
2142
- DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
2191
+ DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()");
2143
2192
  assert(istart != NULL);
2144
2193
  ip = istart + cSize;
2145
2194
  op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
@@ -2161,7 +2210,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2161
2210
  DEBUGLOG(4, "Consume header");
2162
2211
  FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
2163
2212
 
2164
- if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2213
+ if (zds->format == ZSTD_f_zstd1
2214
+ && (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2165
2215
  zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
2166
2216
  zds->stage = ZSTDds_skipFrame;
2167
2217
  } else {
@@ -2177,11 +2227,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2177
2227
  zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2178
2228
  RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
2179
2229
  frameParameter_windowTooLarge, "");
2230
+ if (zds->maxBlockSizeParam != 0)
2231
+ zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam);
2180
2232
 
2181
2233
  /* Adapt buffer sizes to frame header instructions */
2182
2234
  { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
2183
2235
  size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
2184
- ? ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize)
2236
+ ? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax)
2185
2237
  : 0;
2186
2238
 
2187
2239
  ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);