zstd-ruby 1.3.8.0 → 1.4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -5
- data/README.md +1 -1
- data/ext/zstdruby/libzstd/Makefile +7 -3
- data/ext/zstdruby/libzstd/README.md +4 -2
- data/ext/zstdruby/libzstd/common/compiler.h +1 -1
- data/ext/zstdruby/libzstd/common/fse.h +1 -1
- data/ext/zstdruby/libzstd/common/threading.c +2 -2
- data/ext/zstdruby/libzstd/common/xxhash.c +2 -2
- data/ext/zstdruby/libzstd/common/zstd_internal.h +55 -2
- data/ext/zstdruby/libzstd/compress/fse_compress.c +2 -2
- data/ext/zstdruby/libzstd/compress/zstd_compress.c +423 -296
- data/ext/zstdruby/libzstd/compress/zstd_compress_internal.h +14 -11
- data/ext/zstdruby/libzstd/compress/zstd_fast.c +203 -124
- data/ext/zstdruby/libzstd/compress/zstd_lazy.h +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_ldm.c +1 -1
- data/ext/zstdruby/libzstd/compress/zstd_opt.c +27 -11
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.c +41 -49
- data/ext/zstdruby/libzstd/compress/zstdmt_compress.h +43 -26
- data/ext/zstdruby/libzstd/decompress/zstd_ddict.c +4 -4
- data/ext/zstdruby/libzstd/decompress/zstd_decompress.c +257 -164
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_block.c +51 -47
- data/ext/zstdruby/libzstd/decompress/zstd_decompress_internal.h +7 -0
- data/ext/zstdruby/libzstd/dictBuilder/cover.c +58 -13
- data/ext/zstdruby/libzstd/dictBuilder/cover.h +29 -0
- data/ext/zstdruby/libzstd/dictBuilder/fastcover.c +25 -13
- data/ext/zstdruby/libzstd/dictBuilder/zdict.h +18 -8
- data/ext/zstdruby/libzstd/dll/example/build_package.bat +3 -2
- data/ext/zstdruby/libzstd/legacy/zstd_legacy.h +42 -12
- data/ext/zstdruby/libzstd/legacy/zstd_v01.c +32 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v01.h +12 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v02.c +31 -12
- data/ext/zstdruby/libzstd/legacy/zstd_v02.h +12 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v03.c +32 -12
- data/ext/zstdruby/libzstd/legacy/zstd_v03.h +12 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v04.c +32 -12
- data/ext/zstdruby/libzstd/legacy/zstd_v04.h +12 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v05.c +32 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v05.h +12 -7
- data/ext/zstdruby/libzstd/legacy/zstd_v06.c +36 -8
- data/ext/zstdruby/libzstd/legacy/zstd_v06.h +10 -5
- data/ext/zstdruby/libzstd/legacy/zstd_v07.c +40 -9
- data/ext/zstdruby/libzstd/legacy/zstd_v07.h +10 -5
- data/ext/zstdruby/libzstd/zstd.h +689 -542
- data/lib/zstd-ruby/version.rb +1 -1
- data/zstd-ruby.gemspec +1 -1
- metadata +6 -7
- data/ext/zstdruby/libzstd/dll/libzstd.def +0 -87
@@ -105,9 +105,9 @@ ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict,
|
|
105
105
|
ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE);
|
106
106
|
|
107
107
|
/* load entropy tables */
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy(
|
109
|
+
&ddict->entropy, ddict->dictContent, ddict->dictSize)),
|
110
|
+
dictionary_corrupted);
|
111
111
|
ddict->entropyPresent = 1;
|
112
112
|
return 0;
|
113
113
|
}
|
@@ -133,7 +133,7 @@ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
|
|
133
133
|
ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
|
134
134
|
|
135
135
|
/* parse dictionary content */
|
136
|
-
|
136
|
+
FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) );
|
137
137
|
|
138
138
|
return 0;
|
139
139
|
}
|
@@ -106,6 +106,7 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
|
|
106
106
|
dctx->ddictLocal = NULL;
|
107
107
|
dctx->dictEnd = NULL;
|
108
108
|
dctx->ddictIsCold = 0;
|
109
|
+
dctx->dictUses = ZSTD_dont_use;
|
109
110
|
dctx->inBuff = NULL;
|
110
111
|
dctx->inBuffSize = 0;
|
111
112
|
dctx->outBuffSize = 0;
|
@@ -147,13 +148,20 @@ ZSTD_DCtx* ZSTD_createDCtx(void)
|
|
147
148
|
return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
|
148
149
|
}
|
149
150
|
|
151
|
+
static void ZSTD_clearDict(ZSTD_DCtx* dctx)
|
152
|
+
{
|
153
|
+
ZSTD_freeDDict(dctx->ddictLocal);
|
154
|
+
dctx->ddictLocal = NULL;
|
155
|
+
dctx->ddict = NULL;
|
156
|
+
dctx->dictUses = ZSTD_dont_use;
|
157
|
+
}
|
158
|
+
|
150
159
|
size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
|
151
160
|
{
|
152
161
|
if (dctx==NULL) return 0; /* support free on NULL */
|
153
|
-
|
162
|
+
RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
|
154
163
|
{ ZSTD_customMem const cMem = dctx->customMem;
|
155
|
-
|
156
|
-
dctx->ddictLocal = NULL;
|
164
|
+
ZSTD_clearDict(dctx);
|
157
165
|
ZSTD_free(dctx->inBuff, cMem);
|
158
166
|
dctx->inBuff = NULL;
|
159
167
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
@@ -203,7 +211,7 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
|
|
203
211
|
static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
|
204
212
|
{
|
205
213
|
size_t const minInputSize = ZSTD_startingInputLength(format);
|
206
|
-
|
214
|
+
RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong);
|
207
215
|
|
208
216
|
{ BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
|
209
217
|
U32 const dictID= fhd & 3;
|
@@ -238,7 +246,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
|
238
246
|
|
239
247
|
memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
|
240
248
|
if (srcSize < minInputSize) return minInputSize;
|
241
|
-
|
249
|
+
RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
|
242
250
|
|
243
251
|
if ( (format != ZSTD_f_zstd1_magicless)
|
244
252
|
&& (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
|
@@ -251,7 +259,7 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
|
251
259
|
zfhPtr->frameType = ZSTD_skippableFrame;
|
252
260
|
return 0;
|
253
261
|
}
|
254
|
-
|
262
|
+
RETURN_ERROR(prefix_unknown);
|
255
263
|
}
|
256
264
|
|
257
265
|
/* ensure there is enough `srcSize` to fully read/decode frame header */
|
@@ -269,14 +277,13 @@ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, s
|
|
269
277
|
U64 windowSize = 0;
|
270
278
|
U32 dictID = 0;
|
271
279
|
U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;
|
272
|
-
|
273
|
-
|
280
|
+
RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,
|
281
|
+
"reserved bits, must be zero");
|
274
282
|
|
275
283
|
if (!singleSegment) {
|
276
284
|
BYTE const wlByte = ip[pos++];
|
277
285
|
U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
|
278
|
-
|
279
|
-
return ERROR(frameParameter_windowTooLarge);
|
286
|
+
RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge);
|
280
287
|
windowSize = (1ULL << windowLog);
|
281
288
|
windowSize += (windowSize >> 3) * (wlByte&7);
|
282
289
|
}
|
@@ -348,12 +355,11 @@ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
|
|
348
355
|
size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
|
349
356
|
U32 sizeU32;
|
350
357
|
|
351
|
-
|
352
|
-
return ERROR(srcSize_wrong);
|
358
|
+
RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong);
|
353
359
|
|
354
360
|
sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
|
355
|
-
|
356
|
-
|
361
|
+
RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
|
362
|
+
frameParameter_unsupported);
|
357
363
|
|
358
364
|
return skippableHeaderSize + sizeU32;
|
359
365
|
}
|
@@ -428,67 +434,124 @@ static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t he
|
|
428
434
|
{
|
429
435
|
size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
|
430
436
|
if (ZSTD_isError(result)) return result; /* invalid header */
|
431
|
-
|
432
|
-
|
433
|
-
|
437
|
+
RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
|
438
|
+
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
439
|
+
/* Skip the dictID check in fuzzing mode, because it makes the search
|
440
|
+
* harder.
|
441
|
+
*/
|
442
|
+
RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
|
443
|
+
dictionary_wrong);
|
444
|
+
#endif
|
434
445
|
if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
|
435
446
|
return 0;
|
436
447
|
}
|
437
448
|
|
449
|
+
static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
|
450
|
+
{
|
451
|
+
ZSTD_frameSizeInfo frameSizeInfo;
|
452
|
+
frameSizeInfo.compressedSize = ret;
|
453
|
+
frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
|
454
|
+
return frameSizeInfo;
|
455
|
+
}
|
438
456
|
|
439
|
-
|
440
|
-
* compatible with legacy mode
|
441
|
-
* `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
|
442
|
-
* `srcSize` must be at least as large as the frame contained
|
443
|
-
* @return : the compressed size of the frame starting at `src` */
|
444
|
-
size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
|
457
|
+
static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
|
445
458
|
{
|
459
|
+
ZSTD_frameSizeInfo frameSizeInfo;
|
460
|
+
memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
|
461
|
+
|
446
462
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
|
447
463
|
if (ZSTD_isLegacy(src, srcSize))
|
448
|
-
return
|
464
|
+
return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
|
449
465
|
#endif
|
450
|
-
|
451
|
-
|
452
|
-
|
466
|
+
|
467
|
+
if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
|
468
|
+
&& (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
|
469
|
+
frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
|
470
|
+
return frameSizeInfo;
|
453
471
|
} else {
|
454
472
|
const BYTE* ip = (const BYTE*)src;
|
455
473
|
const BYTE* const ipstart = ip;
|
456
474
|
size_t remainingSize = srcSize;
|
475
|
+
size_t nbBlocks = 0;
|
457
476
|
ZSTD_frameHeader zfh;
|
458
477
|
|
459
478
|
/* Extract Frame Header */
|
460
479
|
{ size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
|
461
|
-
if (ZSTD_isError(ret))
|
462
|
-
|
480
|
+
if (ZSTD_isError(ret))
|
481
|
+
return ZSTD_errorFrameSizeInfo(ret);
|
482
|
+
if (ret > 0)
|
483
|
+
return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
|
463
484
|
}
|
464
485
|
|
465
486
|
ip += zfh.headerSize;
|
466
487
|
remainingSize -= zfh.headerSize;
|
467
488
|
|
468
|
-
/*
|
489
|
+
/* Iterate over each block */
|
469
490
|
while (1) {
|
470
491
|
blockProperties_t blockProperties;
|
471
492
|
size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
|
472
|
-
if (ZSTD_isError(cBlockSize))
|
493
|
+
if (ZSTD_isError(cBlockSize))
|
494
|
+
return ZSTD_errorFrameSizeInfo(cBlockSize);
|
473
495
|
|
474
496
|
if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
|
475
|
-
return ERROR(srcSize_wrong);
|
497
|
+
return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
|
476
498
|
|
477
499
|
ip += ZSTD_blockHeaderSize + cBlockSize;
|
478
500
|
remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
|
501
|
+
nbBlocks++;
|
479
502
|
|
480
503
|
if (blockProperties.lastBlock) break;
|
481
504
|
}
|
482
505
|
|
483
|
-
|
484
|
-
|
506
|
+
/* Final frame content checksum */
|
507
|
+
if (zfh.checksumFlag) {
|
508
|
+
if (remainingSize < 4)
|
509
|
+
return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
|
485
510
|
ip += 4;
|
486
511
|
}
|
487
512
|
|
488
|
-
|
513
|
+
frameSizeInfo.compressedSize = ip - ipstart;
|
514
|
+
frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
|
515
|
+
? zfh.frameContentSize
|
516
|
+
: nbBlocks * zfh.blockSizeMax;
|
517
|
+
return frameSizeInfo;
|
489
518
|
}
|
490
519
|
}
|
491
520
|
|
521
|
+
/** ZSTD_findFrameCompressedSize() :
|
522
|
+
* compatible with legacy mode
|
523
|
+
* `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
|
524
|
+
* `srcSize` must be at least as large as the frame contained
|
525
|
+
* @return : the compressed size of the frame starting at `src` */
|
526
|
+
size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
|
527
|
+
{
|
528
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
|
529
|
+
return frameSizeInfo.compressedSize;
|
530
|
+
}
|
531
|
+
|
532
|
+
|
533
|
+
/** ZSTD_decompressBound() :
|
534
|
+
* compatible with legacy mode
|
535
|
+
* `src` must point to the start of a ZSTD frame or a skippeable frame
|
536
|
+
* `srcSize` must be at least as large as the frame contained
|
537
|
+
* @return : the maximum decompressed size of the compressed source
|
538
|
+
*/
|
539
|
+
unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
|
540
|
+
{
|
541
|
+
unsigned long long bound = 0;
|
542
|
+
/* Iterate over each frame */
|
543
|
+
while (srcSize > 0) {
|
544
|
+
ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
|
545
|
+
size_t const compressedSize = frameSizeInfo.compressedSize;
|
546
|
+
unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
|
547
|
+
if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
|
548
|
+
return ZSTD_CONTENTSIZE_ERROR;
|
549
|
+
src = (const BYTE*)src + compressedSize;
|
550
|
+
srcSize -= compressedSize;
|
551
|
+
bound += decompressedBound;
|
552
|
+
}
|
553
|
+
return bound;
|
554
|
+
}
|
492
555
|
|
493
556
|
|
494
557
|
/*-*************************************************************
|
@@ -522,9 +585,9 @@ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
|
|
522
585
|
DEBUGLOG(5, "ZSTD_copyRawBlock");
|
523
586
|
if (dst == NULL) {
|
524
587
|
if (srcSize == 0) return 0;
|
525
|
-
|
588
|
+
RETURN_ERROR(dstBuffer_null);
|
526
589
|
}
|
527
|
-
|
590
|
+
RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall);
|
528
591
|
memcpy(dst, src, srcSize);
|
529
592
|
return srcSize;
|
530
593
|
}
|
@@ -535,9 +598,9 @@ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
|
|
535
598
|
{
|
536
599
|
if (dst == NULL) {
|
537
600
|
if (regenSize == 0) return 0;
|
538
|
-
|
601
|
+
RETURN_ERROR(dstBuffer_null);
|
539
602
|
}
|
540
|
-
|
603
|
+
RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall);
|
541
604
|
memset(dst, b, regenSize);
|
542
605
|
return regenSize;
|
543
606
|
}
|
@@ -560,15 +623,16 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
560
623
|
DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr);
|
561
624
|
|
562
625
|
/* check */
|
563
|
-
|
564
|
-
|
626
|
+
RETURN_ERROR_IF(
|
627
|
+
remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN+ZSTD_blockHeaderSize,
|
628
|
+
srcSize_wrong);
|
565
629
|
|
566
630
|
/* Frame Header */
|
567
631
|
{ size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_FRAMEHEADERSIZE_PREFIX);
|
568
632
|
if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
|
569
|
-
|
570
|
-
|
571
|
-
|
633
|
+
RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
|
634
|
+
srcSize_wrong);
|
635
|
+
FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) );
|
572
636
|
ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
|
573
637
|
}
|
574
638
|
|
@@ -581,7 +645,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
581
645
|
|
582
646
|
ip += ZSTD_blockHeaderSize;
|
583
647
|
remainingSrcSize -= ZSTD_blockHeaderSize;
|
584
|
-
|
648
|
+
RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong);
|
585
649
|
|
586
650
|
switch(blockProperties.blockType)
|
587
651
|
{
|
@@ -596,7 +660,7 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
596
660
|
break;
|
597
661
|
case bt_reserved :
|
598
662
|
default:
|
599
|
-
|
663
|
+
RETURN_ERROR(corruption_detected);
|
600
664
|
}
|
601
665
|
|
602
666
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
@@ -609,15 +673,15 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
|
|
609
673
|
}
|
610
674
|
|
611
675
|
if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
|
612
|
-
|
613
|
-
|
614
|
-
}
|
676
|
+
RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
|
677
|
+
corruption_detected);
|
678
|
+
}
|
615
679
|
if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
|
616
680
|
U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
|
617
681
|
U32 checkRead;
|
618
|
-
|
682
|
+
RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong);
|
619
683
|
checkRead = MEM_readLE32(ip);
|
620
|
-
|
684
|
+
RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong);
|
621
685
|
ip += 4;
|
622
686
|
remainingSrcSize -= 4;
|
623
687
|
}
|
@@ -652,8 +716,8 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
652
716
|
size_t decodedSize;
|
653
717
|
size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
|
654
718
|
if (ZSTD_isError(frameSize)) return frameSize;
|
655
|
-
|
656
|
-
|
719
|
+
RETURN_ERROR_IF(dctx->staticSize, memory_allocation,
|
720
|
+
"legacy support is not compatible with static dctx");
|
657
721
|
|
658
722
|
decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
|
659
723
|
if (ZSTD_isError(decodedSize)) return decodedSize;
|
@@ -676,7 +740,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
676
740
|
size_t const skippableSize = readSkippableFrameSize(src, srcSize);
|
677
741
|
if (ZSTD_isError(skippableSize))
|
678
742
|
return skippableSize;
|
679
|
-
|
743
|
+
RETURN_ERROR_IF(srcSize < skippableSize, srcSize_wrong);
|
680
744
|
|
681
745
|
src = (const BYTE *)src + skippableSize;
|
682
746
|
srcSize -= skippableSize;
|
@@ -685,29 +749,29 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
685
749
|
|
686
750
|
if (ddict) {
|
687
751
|
/* we were called from ZSTD_decompress_usingDDict */
|
688
|
-
|
752
|
+
FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict));
|
689
753
|
} else {
|
690
754
|
/* this will initialize correctly with no dict if dict == NULL, so
|
691
755
|
* use this in all cases but ddict */
|
692
|
-
|
756
|
+
FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
|
693
757
|
}
|
694
758
|
ZSTD_checkContinuity(dctx, dst);
|
695
759
|
|
696
760
|
{ const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
|
697
761
|
&src, &srcSize);
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
762
|
+
RETURN_ERROR_IF(
|
763
|
+
(ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
|
764
|
+
&& (moreThan1Frame==1),
|
765
|
+
srcSize_wrong,
|
766
|
+
"at least one frame successfully completed, but following "
|
767
|
+
"bytes are garbage: it's more likely to be a srcSize error, "
|
768
|
+
"specifying more bytes than compressed size of frame(s). This "
|
769
|
+
"error message replaces ERROR(prefix_unknown), which would be "
|
770
|
+
"confusing, as the first header is actually correct. Note that "
|
771
|
+
"one could be unlucky, it might be a corruption error instead, "
|
772
|
+
"happening right at the place where we expect zstd magic "
|
773
|
+
"bytes. But this is _much_ less likely than a srcSize field "
|
774
|
+
"error.");
|
711
775
|
if (ZSTD_isError(res)) return res;
|
712
776
|
assert(res <= dstCapacity);
|
713
777
|
dst = (BYTE*)dst + res;
|
@@ -716,7 +780,7 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
|
|
716
780
|
moreThan1Frame = 1;
|
717
781
|
} /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
|
718
782
|
|
719
|
-
|
783
|
+
RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
|
720
784
|
|
721
785
|
return (BYTE*)dst - (BYTE*)dststart;
|
722
786
|
}
|
@@ -730,9 +794,26 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
|
|
730
794
|
}
|
731
795
|
|
732
796
|
|
797
|
+
static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
|
798
|
+
{
|
799
|
+
switch (dctx->dictUses) {
|
800
|
+
default:
|
801
|
+
assert(0 /* Impossible */);
|
802
|
+
/* fall-through */
|
803
|
+
case ZSTD_dont_use:
|
804
|
+
ZSTD_clearDict(dctx);
|
805
|
+
return NULL;
|
806
|
+
case ZSTD_use_indefinitely:
|
807
|
+
return dctx->ddict;
|
808
|
+
case ZSTD_use_once:
|
809
|
+
dctx->dictUses = ZSTD_dont_use;
|
810
|
+
return dctx->ddict;
|
811
|
+
}
|
812
|
+
}
|
813
|
+
|
733
814
|
size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
|
734
815
|
{
|
735
|
-
return
|
816
|
+
return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));
|
736
817
|
}
|
737
818
|
|
738
819
|
|
@@ -741,7 +822,7 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
|
|
741
822
|
#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
|
742
823
|
size_t regenSize;
|
743
824
|
ZSTD_DCtx* const dctx = ZSTD_createDCtx();
|
744
|
-
|
825
|
+
RETURN_ERROR_IF(dctx==NULL, memory_allocation);
|
745
826
|
regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
|
746
827
|
ZSTD_freeDCtx(dctx);
|
747
828
|
return regenSize;
|
@@ -791,8 +872,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
791
872
|
{
|
792
873
|
DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
|
793
874
|
/* Sanity check */
|
794
|
-
|
795
|
-
return ERROR(srcSize_wrong); /* not allowed */
|
875
|
+
RETURN_ERROR_IF(srcSize != dctx->expected, srcSize_wrong, "not allowed");
|
796
876
|
if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
|
797
877
|
|
798
878
|
switch (dctx->stage)
|
@@ -817,7 +897,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
817
897
|
case ZSTDds_decodeFrameHeader:
|
818
898
|
assert(src != NULL);
|
819
899
|
memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
|
820
|
-
|
900
|
+
FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
|
821
901
|
dctx->expected = ZSTD_blockHeaderSize;
|
822
902
|
dctx->stage = ZSTDds_decodeBlockHeader;
|
823
903
|
return 0;
|
@@ -867,7 +947,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
867
947
|
break;
|
868
948
|
case bt_reserved : /* should never happen */
|
869
949
|
default:
|
870
|
-
|
950
|
+
RETURN_ERROR(corruption_detected);
|
871
951
|
}
|
872
952
|
if (ZSTD_isError(rSize)) return rSize;
|
873
953
|
DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
|
@@ -876,10 +956,10 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
876
956
|
|
877
957
|
if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
|
878
958
|
DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
959
|
+
RETURN_ERROR_IF(
|
960
|
+
dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
|
961
|
+
&& dctx->decodedSize != dctx->fParams.frameContentSize,
|
962
|
+
corruption_detected);
|
883
963
|
if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
|
884
964
|
dctx->expected = 4;
|
885
965
|
dctx->stage = ZSTDds_checkChecksum;
|
@@ -900,7 +980,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
900
980
|
{ U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
|
901
981
|
U32 const check32 = MEM_readLE32(src);
|
902
982
|
DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
|
903
|
-
|
983
|
+
RETURN_ERROR_IF(check32 != h32, checksum_wrong);
|
904
984
|
dctx->expected = 0;
|
905
985
|
dctx->stage = ZSTDds_getFrameHeaderSize;
|
906
986
|
return 0;
|
@@ -921,7 +1001,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
|
|
921
1001
|
|
922
1002
|
default:
|
923
1003
|
assert(0); /* impossible */
|
924
|
-
|
1004
|
+
RETURN_ERROR(GENERIC); /* some compiler require default to do something */
|
925
1005
|
}
|
926
1006
|
}
|
927
1007
|
|
@@ -945,7 +1025,7 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
945
1025
|
const BYTE* dictPtr = (const BYTE*)dict;
|
946
1026
|
const BYTE* const dictEnd = dictPtr + dictSize;
|
947
1027
|
|
948
|
-
|
1028
|
+
RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted);
|
949
1029
|
assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */
|
950
1030
|
dictPtr += 8; /* skip header = magic + dictID */
|
951
1031
|
|
@@ -964,16 +1044,16 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
964
1044
|
dictPtr, dictEnd - dictPtr,
|
965
1045
|
workspace, workspaceSize);
|
966
1046
|
#endif
|
967
|
-
|
1047
|
+
RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted);
|
968
1048
|
dictPtr += hSize;
|
969
1049
|
}
|
970
1050
|
|
971
1051
|
{ short offcodeNCount[MaxOff+1];
|
972
1052
|
unsigned offcodeMaxValue = MaxOff, offcodeLog;
|
973
1053
|
size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
|
974
|
-
|
975
|
-
|
976
|
-
|
1054
|
+
RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
|
1055
|
+
RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted);
|
1056
|
+
RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
|
977
1057
|
ZSTD_buildFSETable( entropy->OFTable,
|
978
1058
|
offcodeNCount, offcodeMaxValue,
|
979
1059
|
OF_base, OF_bits,
|
@@ -984,9 +1064,9 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
984
1064
|
{ short matchlengthNCount[MaxML+1];
|
985
1065
|
unsigned matchlengthMaxValue = MaxML, matchlengthLog;
|
986
1066
|
size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
|
987
|
-
|
988
|
-
|
989
|
-
|
1067
|
+
RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
|
1068
|
+
RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted);
|
1069
|
+
RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
|
990
1070
|
ZSTD_buildFSETable( entropy->MLTable,
|
991
1071
|
matchlengthNCount, matchlengthMaxValue,
|
992
1072
|
ML_base, ML_bits,
|
@@ -997,9 +1077,9 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
997
1077
|
{ short litlengthNCount[MaxLL+1];
|
998
1078
|
unsigned litlengthMaxValue = MaxLL, litlengthLog;
|
999
1079
|
size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1080
|
+
RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
|
1081
|
+
RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted);
|
1082
|
+
RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
|
1003
1083
|
ZSTD_buildFSETable( entropy->LLTable,
|
1004
1084
|
litlengthNCount, litlengthMaxValue,
|
1005
1085
|
LL_base, LL_bits,
|
@@ -1007,12 +1087,13 @@ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
|
|
1007
1087
|
dictPtr += litlengthHeaderSize;
|
1008
1088
|
}
|
1009
1089
|
|
1010
|
-
|
1090
|
+
RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
|
1011
1091
|
{ int i;
|
1012
1092
|
size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
|
1013
1093
|
for (i=0; i<3; i++) {
|
1014
1094
|
U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
|
1015
|
-
|
1095
|
+
RETURN_ERROR_IF(rep==0 || rep >= dictContentSize,
|
1096
|
+
dictionary_corrupted);
|
1016
1097
|
entropy->rep[i] = rep;
|
1017
1098
|
} }
|
1018
1099
|
|
@@ -1030,7 +1111,7 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
|
|
1030
1111
|
|
1031
1112
|
/* load entropy tables */
|
1032
1113
|
{ size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
|
1033
|
-
|
1114
|
+
RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted);
|
1034
1115
|
dict = (const char*)dict + eSize;
|
1035
1116
|
dictSize -= eSize;
|
1036
1117
|
}
|
@@ -1064,9 +1145,11 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
|
|
1064
1145
|
|
1065
1146
|
size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
|
1066
1147
|
{
|
1067
|
-
|
1148
|
+
FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
|
1068
1149
|
if (dict && dictSize)
|
1069
|
-
|
1150
|
+
RETURN_ERROR_IF(
|
1151
|
+
ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
|
1152
|
+
dictionary_corrupted);
|
1070
1153
|
return 0;
|
1071
1154
|
}
|
1072
1155
|
|
@@ -1085,7 +1168,7 @@ size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
|
|
1085
1168
|
DEBUGLOG(4, "DDict is %s",
|
1086
1169
|
dctx->ddictIsCold ? "~cold~" : "hot!");
|
1087
1170
|
}
|
1088
|
-
|
1171
|
+
FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
|
1089
1172
|
if (ddict) { /* NULL ddict is equivalent to no dictionary */
|
1090
1173
|
ZSTD_copyDDictParameters(dctx, ddict);
|
1091
1174
|
}
|
@@ -1104,7 +1187,7 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
|
|
1104
1187
|
}
|
1105
1188
|
|
1106
1189
|
/*! ZSTD_getDictID_fromFrame() :
|
1107
|
-
* Provides the dictID required to
|
1190
|
+
* Provides the dictID required to decompress frame stored within `src`.
|
1108
1191
|
* If @return == 0, the dictID could not be decoded.
|
1109
1192
|
* This could for one of the following reasons :
|
1110
1193
|
* - The frame does not require a dictionary (most common case).
|
@@ -1176,15 +1259,14 @@ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
|
|
1176
1259
|
ZSTD_dictLoadMethod_e dictLoadMethod,
|
1177
1260
|
ZSTD_dictContentType_e dictContentType)
|
1178
1261
|
{
|
1179
|
-
|
1180
|
-
|
1262
|
+
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
1263
|
+
ZSTD_clearDict(dctx);
|
1181
1264
|
if (dict && dictSize >= 8) {
|
1182
1265
|
dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
|
1183
|
-
|
1184
|
-
|
1185
|
-
dctx->
|
1266
|
+
RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation);
|
1267
|
+
dctx->ddict = dctx->ddictLocal;
|
1268
|
+
dctx->dictUses = ZSTD_use_indefinitely;
|
1186
1269
|
}
|
1187
|
-
dctx->ddict = dctx->ddictLocal;
|
1188
1270
|
return 0;
|
1189
1271
|
}
|
1190
1272
|
|
@@ -1200,7 +1282,9 @@ size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSi
|
|
1200
1282
|
|
1201
1283
|
size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
|
1202
1284
|
{
|
1203
|
-
|
1285
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType));
|
1286
|
+
dctx->dictUses = ZSTD_use_once;
|
1287
|
+
return 0;
|
1204
1288
|
}
|
1205
1289
|
|
1206
1290
|
size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)
|
@@ -1215,9 +1299,8 @@ size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSiz
|
|
1215
1299
|
size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
|
1216
1300
|
{
|
1217
1301
|
DEBUGLOG(4, "ZSTD_initDStream_usingDict");
|
1218
|
-
zds
|
1219
|
-
zds
|
1220
|
-
CHECK_F( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );
|
1302
|
+
FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) );
|
1303
|
+
FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );
|
1221
1304
|
return ZSTD_FRAMEHEADERSIZE_PREFIX;
|
1222
1305
|
}
|
1223
1306
|
|
@@ -1225,7 +1308,7 @@ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t di
|
|
1225
1308
|
size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
1226
1309
|
{
|
1227
1310
|
DEBUGLOG(4, "ZSTD_initDStream");
|
1228
|
-
return
|
1311
|
+
return ZSTD_initDStream_usingDDict(zds, NULL);
|
1229
1312
|
}
|
1230
1313
|
|
1231
1314
|
/* ZSTD_initDStream_usingDDict() :
|
@@ -1233,9 +1316,9 @@ size_t ZSTD_initDStream(ZSTD_DStream* zds)
|
|
1233
1316
|
* this function cannot fail */
|
1234
1317
|
size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
1235
1318
|
{
|
1236
|
-
|
1237
|
-
dctx
|
1238
|
-
return
|
1319
|
+
FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) );
|
1320
|
+
FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) );
|
1321
|
+
return ZSTD_FRAMEHEADERSIZE_PREFIX;
|
1239
1322
|
}
|
1240
1323
|
|
1241
1324
|
/* ZSTD_resetDStream() :
|
@@ -1243,19 +1326,19 @@ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
|
|
1243
1326
|
* this function cannot fail */
|
1244
1327
|
size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
|
1245
1328
|
{
|
1246
|
-
|
1247
|
-
dctx->streamStage = zdss_loadHeader;
|
1248
|
-
dctx->lhSize = dctx->inPos = dctx->outStart = dctx->outEnd = 0;
|
1249
|
-
dctx->legacyVersion = 0;
|
1250
|
-
dctx->hostageByte = 0;
|
1329
|
+
FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only));
|
1251
1330
|
return ZSTD_FRAMEHEADERSIZE_PREFIX;
|
1252
1331
|
}
|
1253
1332
|
|
1254
1333
|
|
1255
1334
|
size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
|
1256
1335
|
{
|
1257
|
-
|
1258
|
-
dctx
|
1336
|
+
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
1337
|
+
ZSTD_clearDict(dctx);
|
1338
|
+
if (ddict) {
|
1339
|
+
dctx->ddict = ddict;
|
1340
|
+
dctx->dictUses = ZSTD_use_indefinitely;
|
1341
|
+
}
|
1259
1342
|
return 0;
|
1260
1343
|
}
|
1261
1344
|
|
@@ -1267,9 +1350,9 @@ size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
|
|
1267
1350
|
ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
|
1268
1351
|
size_t const min = (size_t)1 << bounds.lowerBound;
|
1269
1352
|
size_t const max = (size_t)1 << bounds.upperBound;
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1353
|
+
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
1354
|
+
RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound);
|
1355
|
+
RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound);
|
1273
1356
|
dctx->maxWindowSize = maxWindowSize;
|
1274
1357
|
return 0;
|
1275
1358
|
}
|
@@ -1311,15 +1394,15 @@ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
|
|
1311
1394
|
}
|
1312
1395
|
|
1313
1396
|
#define CHECK_DBOUNDS(p,v) { \
|
1314
|
-
|
1315
|
-
return ERROR(parameter_outOfBound); \
|
1397
|
+
RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound); \
|
1316
1398
|
}
|
1317
1399
|
|
1318
1400
|
size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
|
1319
1401
|
{
|
1320
|
-
|
1402
|
+
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
1321
1403
|
switch(dParam) {
|
1322
1404
|
case ZSTD_d_windowLogMax:
|
1405
|
+
if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
|
1323
1406
|
CHECK_DBOUNDS(ZSTD_d_windowLogMax, value);
|
1324
1407
|
dctx->maxWindowSize = ((size_t)1) << value;
|
1325
1408
|
return 0;
|
@@ -1329,19 +1412,20 @@ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value
|
|
1329
1412
|
return 0;
|
1330
1413
|
default:;
|
1331
1414
|
}
|
1332
|
-
|
1415
|
+
RETURN_ERROR(parameter_unsupported);
|
1333
1416
|
}
|
1334
1417
|
|
1335
1418
|
size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
|
1336
1419
|
{
|
1337
1420
|
if ( (reset == ZSTD_reset_session_only)
|
1338
1421
|
|| (reset == ZSTD_reset_session_and_parameters) ) {
|
1339
|
-
|
1422
|
+
dctx->streamStage = zdss_init;
|
1423
|
+
dctx->noForwardProgress = 0;
|
1340
1424
|
}
|
1341
1425
|
if ( (reset == ZSTD_reset_parameters)
|
1342
1426
|
|| (reset == ZSTD_reset_session_and_parameters) ) {
|
1343
|
-
|
1344
|
-
|
1427
|
+
RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
|
1428
|
+
ZSTD_clearDict(dctx);
|
1345
1429
|
dctx->format = ZSTD_f_zstd1;
|
1346
1430
|
dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
|
1347
1431
|
}
|
@@ -1360,7 +1444,8 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
|
|
1360
1444
|
unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
|
1361
1445
|
unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
|
1362
1446
|
size_t const minRBSize = (size_t) neededSize;
|
1363
|
-
|
1447
|
+
RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
|
1448
|
+
frameParameter_windowTooLarge);
|
1364
1449
|
return minRBSize;
|
1365
1450
|
}
|
1366
1451
|
|
@@ -1378,9 +1463,9 @@ size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
|
|
1378
1463
|
ZSTD_frameHeader zfh;
|
1379
1464
|
size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
|
1380
1465
|
if (ZSTD_isError(err)) return err;
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1466
|
+
RETURN_ERROR_IF(err>0, srcSize_wrong);
|
1467
|
+
RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
|
1468
|
+
frameParameter_windowTooLarge);
|
1384
1469
|
return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
|
1385
1470
|
}
|
1386
1471
|
|
@@ -1406,16 +1491,16 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1406
1491
|
U32 someMoreWork = 1;
|
1407
1492
|
|
1408
1493
|
DEBUGLOG(5, "ZSTD_decompressStream");
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1494
|
+
RETURN_ERROR_IF(
|
1495
|
+
input->pos > input->size,
|
1496
|
+
srcSize_wrong,
|
1497
|
+
"forbidden. in: pos: %u vs size: %u",
|
1498
|
+
(U32)input->pos, (U32)input->size);
|
1499
|
+
RETURN_ERROR_IF(
|
1500
|
+
output->pos > output->size,
|
1501
|
+
dstSize_tooSmall,
|
1502
|
+
"forbidden. out: pos: %u vs size: %u",
|
1503
|
+
(U32)output->pos, (U32)output->size);
|
1419
1504
|
DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
|
1420
1505
|
|
1421
1506
|
while (someMoreWork) {
|
@@ -1423,15 +1508,18 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1423
1508
|
{
|
1424
1509
|
case zdss_init :
|
1425
1510
|
DEBUGLOG(5, "stage zdss_init => transparent reset ");
|
1426
|
-
|
1511
|
+
zds->streamStage = zdss_loadHeader;
|
1512
|
+
zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
|
1513
|
+
zds->legacyVersion = 0;
|
1514
|
+
zds->hostageByte = 0;
|
1427
1515
|
/* fall-through */
|
1428
1516
|
|
1429
1517
|
case zdss_loadHeader :
|
1430
1518
|
DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
|
1431
1519
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
1432
1520
|
if (zds->legacyVersion) {
|
1433
|
-
|
1434
|
-
|
1521
|
+
RETURN_ERROR_IF(zds->staticSize, memory_allocation,
|
1522
|
+
"legacy support is incompatible with static dctx");
|
1435
1523
|
{ size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
|
1436
1524
|
if (hint==0) zds->streamStage = zdss_init;
|
1437
1525
|
return hint;
|
@@ -1443,12 +1531,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1443
1531
|
#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
|
1444
1532
|
U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
|
1445
1533
|
if (legacyVersion) {
|
1446
|
-
const
|
1447
|
-
|
1534
|
+
ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);
|
1535
|
+
const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;
|
1536
|
+
size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;
|
1448
1537
|
DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion);
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1538
|
+
RETURN_ERROR_IF(zds->staticSize, memory_allocation,
|
1539
|
+
"legacy support is incompatible with static dctx");
|
1540
|
+
FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
|
1452
1541
|
zds->previousLegacyVersion, legacyVersion,
|
1453
1542
|
dict, dictSize));
|
1454
1543
|
zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
|
@@ -1482,7 +1571,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1482
1571
|
size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
|
1483
1572
|
if (cSize <= (size_t)(iend-istart)) {
|
1484
1573
|
/* shortcut : using single-pass mode */
|
1485
|
-
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds
|
1574
|
+
size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, ZSTD_getDDict(zds));
|
1486
1575
|
if (ZSTD_isError(decompressedSize)) return decompressedSize;
|
1487
1576
|
DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
|
1488
1577
|
ip = istart + cSize;
|
@@ -1495,13 +1584,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1495
1584
|
|
1496
1585
|
/* Consume header (see ZSTDds_decodeFrameHeader) */
|
1497
1586
|
DEBUGLOG(4, "Consume header");
|
1498
|
-
|
1587
|
+
FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)));
|
1499
1588
|
|
1500
1589
|
if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
|
1501
1590
|
zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
|
1502
1591
|
zds->stage = ZSTDds_skipFrame;
|
1503
1592
|
} else {
|
1504
|
-
|
1593
|
+
FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
|
1505
1594
|
zds->expected = ZSTD_blockHeaderSize;
|
1506
1595
|
zds->stage = ZSTDds_decodeBlockHeader;
|
1507
1596
|
}
|
@@ -1511,7 +1600,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1511
1600
|
(U32)(zds->fParams.windowSize >>10),
|
1512
1601
|
(U32)(zds->maxWindowSize >> 10) );
|
1513
1602
|
zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
|
1514
|
-
|
1603
|
+
RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
|
1604
|
+
frameParameter_windowTooLarge);
|
1515
1605
|
|
1516
1606
|
/* Adapt buffer sizes to frame header instructions */
|
1517
1607
|
{ size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
|
@@ -1525,14 +1615,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1525
1615
|
if (zds->staticSize) { /* static DCtx */
|
1526
1616
|
DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
|
1527
1617
|
assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
|
1528
|
-
|
1529
|
-
|
1618
|
+
RETURN_ERROR_IF(
|
1619
|
+
bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
|
1620
|
+
memory_allocation);
|
1530
1621
|
} else {
|
1531
1622
|
ZSTD_free(zds->inBuff, zds->customMem);
|
1532
1623
|
zds->inBuffSize = 0;
|
1533
1624
|
zds->outBuffSize = 0;
|
1534
1625
|
zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
|
1535
|
-
|
1626
|
+
RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation);
|
1536
1627
|
}
|
1537
1628
|
zds->inBuffSize = neededInBuffSize;
|
1538
1629
|
zds->outBuff = zds->inBuff + zds->inBuffSize;
|
@@ -1574,7 +1665,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1574
1665
|
if (isSkipFrame) {
|
1575
1666
|
loadedSize = MIN(toLoad, (size_t)(iend-ip));
|
1576
1667
|
} else {
|
1577
|
-
|
1668
|
+
RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
|
1669
|
+
corruption_detected,
|
1670
|
+
"should never happen");
|
1578
1671
|
loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
|
1579
1672
|
}
|
1580
1673
|
ip += loadedSize;
|
@@ -1615,7 +1708,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1615
1708
|
|
1616
1709
|
default:
|
1617
1710
|
assert(0); /* impossible */
|
1618
|
-
|
1711
|
+
RETURN_ERROR(GENERIC); /* some compiler require default to do something */
|
1619
1712
|
} }
|
1620
1713
|
|
1621
1714
|
/* result */
|
@@ -1624,8 +1717,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
|
|
1624
1717
|
if ((ip==istart) && (op==ostart)) { /* no forward progress */
|
1625
1718
|
zds->noForwardProgress ++;
|
1626
1719
|
if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
|
1627
|
-
|
1628
|
-
|
1720
|
+
RETURN_ERROR_IF(op==oend, dstSize_tooSmall);
|
1721
|
+
RETURN_ERROR_IF(ip==iend, srcSize_wrong);
|
1629
1722
|
assert(0);
|
1630
1723
|
}
|
1631
1724
|
} else {
|