1 // SPDX-License-Identifier: (GPL-2.0 or BSD-3-Clause-Clear)
2 /**
3 * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
4 * All rights reserved.
5 */
6
7 /* ***************************************************************
8 * Tuning parameters
9 *****************************************************************/
10 /*!
11 * MAXWINDOWSIZE_DEFAULT :
12 * maximum window size accepted by DStream, by default.
13 * Frames requiring more memory will be rejected.
14 */
15 #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
16 #define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
17 #endif
18
19 /*-*******************************************************
20 * Dependencies
21 *********************************************************/
22 #include "fse.h"
23 #include "huf.h"
24 #include "mem.h" /* low level memory routines */
25 #include "zstd_internal.h"
26 #include <linux/kernel.h>
27 #include <linux/compat.h>
28 #include <linux/string.h> /* memcpy, memmove, memset */
29
30 #define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
31
32 /*-*************************************
33 * Macros
34 ***************************************/
35 #define ZSTD_isError ERR_isError /* for inlining */
36 #define FSE_isError ERR_isError
37 #define HUF_isError ERR_isError
38
39 /*_*******************************************************
40 * Memory operations
41 **********************************************************/
ZSTD_copy4(void * dst,const void * src)42 static void ZSTD_copy4(void *dst, const void *src) { memcpy(dst, src, 4); }
43
44 /*-*************************************************************
45 * Context management
46 ***************************************************************/
47 typedef enum {
48 ZSTDds_getFrameHeaderSize,
49 ZSTDds_decodeFrameHeader,
50 ZSTDds_decodeBlockHeader,
51 ZSTDds_decompressBlock,
52 ZSTDds_decompressLastBlock,
53 ZSTDds_checkChecksum,
54 ZSTDds_decodeSkippableHeader,
55 ZSTDds_skipFrame
56 } ZSTD_dStage;
57
58 typedef struct {
59 FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
60 FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
61 FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
62 HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
63 U64 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32 / 2];
64 U32 rep[ZSTD_REP_NUM];
65 } ZSTD_entropyTables_t;
66
67 struct ZSTD_DCtx_s {
68 const FSE_DTable *LLTptr;
69 const FSE_DTable *MLTptr;
70 const FSE_DTable *OFTptr;
71 const HUF_DTable *HUFptr;
72 ZSTD_entropyTables_t entropy;
73 const void *previousDstEnd; /* detect continuity */
74 const void *base; /* start of curr segment */
75 const void *vBase; /* virtual start of previous segment if it was just before curr one */
76 const void *dictEnd; /* end of previous segment */
77 size_t expected;
78 ZSTD_frameParams fParams;
79 blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
80 ZSTD_dStage stage;
81 U32 litEntropy;
82 U32 fseEntropy;
83 struct xxh64_state xxhState;
84 size_t headerSize;
85 U32 dictID;
86 const BYTE *litPtr;
87 ZSTD_customMem customMem;
88 size_t litSize;
89 size_t rleSize;
90 BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
91 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
92 }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
93
ZSTD_DCtxWorkspaceBound(void)94 size_t ZSTD_DCtxWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DCtx)); }
95
ZSTD_decompressBegin(ZSTD_DCtx * dctx)96 size_t ZSTD_decompressBegin(ZSTD_DCtx *dctx)
97 {
98 dctx->expected = ZSTD_frameHeaderSize_prefix;
99 dctx->stage = ZSTDds_getFrameHeaderSize;
100 dctx->previousDstEnd = NULL;
101 dctx->base = NULL;
102 dctx->vBase = NULL;
103 dctx->dictEnd = NULL;
104 dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
105 dctx->litEntropy = dctx->fseEntropy = 0;
106 dctx->dictID = 0;
107 ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
108 memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
109 dctx->LLTptr = dctx->entropy.LLTable;
110 dctx->MLTptr = dctx->entropy.MLTable;
111 dctx->OFTptr = dctx->entropy.OFTable;
112 dctx->HUFptr = dctx->entropy.hufTable;
113 return 0;
114 }
115
ZSTD_createDCtx_advanced(ZSTD_customMem customMem)116 ZSTD_DCtx *ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
117 {
118 ZSTD_DCtx *dctx;
119
120 if (!customMem.customAlloc || !customMem.customFree)
121 return NULL;
122
123 dctx = (ZSTD_DCtx *)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
124 if (!dctx)
125 return NULL;
126 memcpy(&dctx->customMem, &customMem, sizeof(customMem));
127 ZSTD_decompressBegin(dctx);
128 return dctx;
129 }
130
ZSTD_initDCtx(void * workspace,size_t workspaceSize)131 ZSTD_DCtx *ZSTD_initDCtx(void *workspace, size_t workspaceSize)
132 {
133 ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
134 return ZSTD_createDCtx_advanced(stackMem);
135 }
136
ZSTD_freeDCtx(ZSTD_DCtx * dctx)137 size_t ZSTD_freeDCtx(ZSTD_DCtx *dctx)
138 {
139 if (dctx == NULL)
140 return 0; /* support free on NULL */
141 ZSTD_free(dctx, dctx->customMem);
142 return 0; /* reserved as a potential error code in the future */
143 }
144
ZSTD_copyDCtx(ZSTD_DCtx * dstDCtx,const ZSTD_DCtx * srcDCtx)145 void ZSTD_copyDCtx(ZSTD_DCtx *dstDCtx, const ZSTD_DCtx *srcDCtx)
146 {
147 size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
148 memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
149 }
150
151 static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict);
152
153 /*-*************************************************************
154 * Decompression section
155 ***************************************************************/
156
157 /*! ZSTD_isFrame() :
158 * Tells if the content of `buffer` starts with a valid Frame Identifier.
159 * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
160 * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
161 * Note 3 : Skippable Frame Identifiers are considered valid. */
ZSTD_isFrame(const void * buffer,size_t size)162 unsigned ZSTD_isFrame(const void *buffer, size_t size)
163 {
164 if (size < 4)
165 return 0;
166 {
167 U32 const magic = ZSTD_readLE32(buffer);
168 if (magic == ZSTD_MAGICNUMBER)
169 return 1;
170 if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START)
171 return 1;
172 }
173 return 0;
174 }
175
176 /** ZSTD_frameHeaderSize() :
177 * srcSize must be >= ZSTD_frameHeaderSize_prefix.
178 * @return : size of the Frame Header */
ZSTD_frameHeaderSize(const void * src,size_t srcSize)179 static size_t ZSTD_frameHeaderSize(const void *src, size_t srcSize)
180 {
181 if (srcSize < ZSTD_frameHeaderSize_prefix)
182 return ERROR(srcSize_wrong);
183 {
184 BYTE const fhd = ((const BYTE *)src)[4];
185 U32 const dictID = fhd & 3;
186 U32 const singleSegment = (fhd >> 5) & 1;
187 U32 const fcsId = fhd >> 6;
188 return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId] + (singleSegment && !fcsId);
189 }
190 }
191
192 /** ZSTD_getFrameParams() :
193 * decode Frame Header, or require larger `srcSize`.
194 * @return : 0, `fparamsPtr` is correctly filled,
195 * >0, `srcSize` is too small, result is expected `srcSize`,
196 * or an error code, which can be tested using ZSTD_isError() */
ZSTD_getFrameParams(ZSTD_frameParams * fparamsPtr,const void * src,size_t srcSize)197 size_t ZSTD_getFrameParams(ZSTD_frameParams *fparamsPtr, const void *src, size_t srcSize)
198 {
199 const BYTE *ip = (const BYTE *)src;
200
201 if (srcSize < ZSTD_frameHeaderSize_prefix)
202 return ZSTD_frameHeaderSize_prefix;
203 if (ZSTD_readLE32(src) != ZSTD_MAGICNUMBER) {
204 if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
205 if (srcSize < ZSTD_skippableHeaderSize)
206 return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
207 memset(fparamsPtr, 0, sizeof(*fparamsPtr));
208 fparamsPtr->frameContentSize = ZSTD_readLE32((const char *)src + 4);
209 fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
210 return 0;
211 }
212 return ERROR(prefix_unknown);
213 }
214
215 /* ensure there is enough `srcSize` to fully read/decode frame header */
216 {
217 size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
218 if (srcSize < fhsize)
219 return fhsize;
220 }
221
222 {
223 BYTE const fhdByte = ip[4];
224 size_t pos = 5;
225 U32 const dictIDSizeCode = fhdByte & 3;
226 U32 const checksumFlag = (fhdByte >> 2) & 1;
227 U32 const singleSegment = (fhdByte >> 5) & 1;
228 U32 const fcsID = fhdByte >> 6;
229 U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
230 U32 windowSize = 0;
231 U32 dictID = 0;
232 U64 frameContentSize = 0;
233 if ((fhdByte & 0x08) != 0)
234 return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
235 if (!singleSegment) {
236 BYTE const wlByte = ip[pos++];
237 U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
238 if (windowLog > ZSTD_WINDOWLOG_MAX)
239 return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */
240 windowSize = (1U << windowLog);
241 windowSize += (windowSize >> 3) * (wlByte & 7);
242 }
243
244 switch (dictIDSizeCode) {
245 default: /* impossible */
246 case 0: break;
247 case 1:
248 dictID = ip[pos];
249 pos++;
250 break;
251 case 2:
252 dictID = ZSTD_readLE16(ip + pos);
253 pos += 2;
254 break;
255 case 3:
256 dictID = ZSTD_readLE32(ip + pos);
257 pos += 4;
258 break;
259 }
260 switch (fcsID) {
261 default: /* impossible */
262 case 0:
263 if (singleSegment)
264 frameContentSize = ip[pos];
265 break;
266 case 1: frameContentSize = ZSTD_readLE16(ip + pos) + 256; break;
267 case 2: frameContentSize = ZSTD_readLE32(ip + pos); break;
268 case 3: frameContentSize = ZSTD_readLE64(ip + pos); break;
269 }
270 if (!windowSize)
271 windowSize = (U32)frameContentSize;
272 if (windowSize > windowSizeMax)
273 return ERROR(frameParameter_windowTooLarge);
274 fparamsPtr->frameContentSize = frameContentSize;
275 fparamsPtr->windowSize = windowSize;
276 fparamsPtr->dictID = dictID;
277 fparamsPtr->checksumFlag = checksumFlag;
278 }
279 return 0;
280 }
281
282 /** ZSTD_getFrameContentSize() :
283 * compatible with legacy mode
284 * @return : decompressed size of the single frame pointed to be `src` if known, otherwise
285 * - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
286 * - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
ZSTD_getFrameContentSize(const void * src,size_t srcSize)287 unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
288 {
289 {
290 ZSTD_frameParams fParams;
291 if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0)
292 return ZSTD_CONTENTSIZE_ERROR;
293 if (fParams.windowSize == 0) {
294 /* Either skippable or empty frame, size == 0 either way */
295 return 0;
296 } else if (fParams.frameContentSize != 0) {
297 return fParams.frameContentSize;
298 } else {
299 return ZSTD_CONTENTSIZE_UNKNOWN;
300 }
301 }
302 }
303
304 /** ZSTD_findDecompressedSize() :
305 * compatible with legacy mode
306 * `srcSize` must be the exact length of some number of ZSTD compressed and/or
307 * skippable frames
308 * @return : decompressed size of the frames contained */
ZSTD_findDecompressedSize(const void * src,size_t srcSize)309 unsigned long long ZSTD_findDecompressedSize(const void *src, size_t srcSize)
310 {
311 {
312 unsigned long long totalDstSize = 0;
313 while (srcSize >= ZSTD_frameHeaderSize_prefix) {
314 const U32 magicNumber = ZSTD_readLE32(src);
315
316 if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
317 size_t skippableSize;
318 if (srcSize < ZSTD_skippableHeaderSize)
319 return ERROR(srcSize_wrong);
320 skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize;
321 if (srcSize < skippableSize) {
322 return ZSTD_CONTENTSIZE_ERROR;
323 }
324
325 src = (const BYTE *)src + skippableSize;
326 srcSize -= skippableSize;
327 continue;
328 }
329
330 {
331 unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
332 if (ret >= ZSTD_CONTENTSIZE_ERROR)
333 return ret;
334
335 /* check for overflow */
336 if (totalDstSize + ret < totalDstSize)
337 return ZSTD_CONTENTSIZE_ERROR;
338 totalDstSize += ret;
339 }
340 {
341 size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
342 if (ZSTD_isError(frameSrcSize)) {
343 return ZSTD_CONTENTSIZE_ERROR;
344 }
345
346 src = (const BYTE *)src + frameSrcSize;
347 srcSize -= frameSrcSize;
348 }
349 }
350
351 if (srcSize) {
352 return ZSTD_CONTENTSIZE_ERROR;
353 }
354
355 return totalDstSize;
356 }
357 }
358
359 /** ZSTD_decodeFrameHeader() :
360 * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
361 * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
ZSTD_decodeFrameHeader(ZSTD_DCtx * dctx,const void * src,size_t headerSize)362 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx *dctx, const void *src, size_t headerSize)
363 {
364 size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
365 if (ZSTD_isError(result))
366 return result; /* invalid header */
367 if (result > 0)
368 return ERROR(srcSize_wrong); /* headerSize too small */
369 if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
370 return ERROR(dictionary_wrong);
371 if (dctx->fParams.checksumFlag)
372 xxh64_reset(&dctx->xxhState, 0);
373 return 0;
374 }
375
376 typedef struct {
377 blockType_e blockType;
378 U32 lastBlock;
379 U32 origSize;
380 } blockProperties_t;
381
382 /*! ZSTD_getcBlockSize() :
383 * Provides the size of compressed block from block header `src` */
ZSTD_getcBlockSize(const void * src,size_t srcSize,blockProperties_t * bpPtr)384 size_t ZSTD_getcBlockSize(const void *src, size_t srcSize, blockProperties_t *bpPtr)
385 {
386 if (srcSize < ZSTD_blockHeaderSize)
387 return ERROR(srcSize_wrong);
388 {
389 U32 const cBlockHeader = ZSTD_readLE24(src);
390 U32 const cSize = cBlockHeader >> 3;
391 bpPtr->lastBlock = cBlockHeader & 1;
392 bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
393 bpPtr->origSize = cSize; /* only useful for RLE */
394 if (bpPtr->blockType == bt_rle)
395 return 1;
396 if (bpPtr->blockType == bt_reserved)
397 return ERROR(corruption_detected);
398 return cSize;
399 }
400 }
401
ZSTD_copyRawBlock(void * dst,size_t dstCapacity,const void * src,size_t srcSize)402 static size_t ZSTD_copyRawBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
403 {
404 if (srcSize > dstCapacity)
405 return ERROR(dstSize_tooSmall);
406 memcpy(dst, src, srcSize);
407 return srcSize;
408 }
409
ZSTD_setRleBlock(void * dst,size_t dstCapacity,const void * src,size_t srcSize,size_t regenSize)410 static size_t ZSTD_setRleBlock(void *dst, size_t dstCapacity, const void *src, size_t srcSize, size_t regenSize)
411 {
412 if (srcSize != 1)
413 return ERROR(srcSize_wrong);
414 if (regenSize > dstCapacity)
415 return ERROR(dstSize_tooSmall);
416 memset(dst, *(const BYTE *)src, regenSize);
417 return regenSize;
418 }
419
420 /*! ZSTD_decodeLiteralsBlock() :
421 @return : nb of bytes read from src (< srcSize ) */
ZSTD_decodeLiteralsBlock(ZSTD_DCtx * dctx,const void * src,size_t srcSize)422 size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx *dctx, const void *src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
423 {
424 if (srcSize < MIN_CBLOCK_SIZE)
425 return ERROR(corruption_detected);
426
427 {
428 const BYTE *const istart = (const BYTE *)src;
429 symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
430
431 switch (litEncType) {
432 case set_repeat:
433 if (dctx->litEntropy == 0)
434 return ERROR(dictionary_corrupted);
435 /* fall-through */
436 case set_compressed:
437 if (srcSize < 5)
438 return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
439 {
440 size_t lhSize, litSize, litCSize;
441 U32 singleStream = 0;
442 U32 const lhlCode = (istart[0] >> 2) & 3;
443 U32 const lhc = ZSTD_readLE32(istart);
444 switch (lhlCode) {
445 case 0:
446 case 1:
447 default: /* note : default is impossible, since lhlCode into [0..3] */
448 /* 2 - 2 - 10 - 10 */
449 singleStream = !lhlCode;
450 lhSize = 3;
451 litSize = (lhc >> 4) & 0x3FF;
452 litCSize = (lhc >> 14) & 0x3FF;
453 break;
454 case 2:
455 /* 2 - 2 - 14 - 14 */
456 lhSize = 4;
457 litSize = (lhc >> 4) & 0x3FFF;
458 litCSize = lhc >> 18;
459 break;
460 case 3:
461 /* 2 - 2 - 18 - 18 */
462 lhSize = 5;
463 litSize = (lhc >> 4) & 0x3FFFF;
464 litCSize = (lhc >> 22) + (istart[4] << 10);
465 break;
466 }
467 if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX)
468 return ERROR(corruption_detected);
469 if (litCSize + lhSize > srcSize)
470 return ERROR(corruption_detected);
471
472 if (HUF_isError(
473 (litEncType == set_repeat)
474 ? (singleStream ? HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr)
475 : HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart + lhSize, litCSize, dctx->HUFptr))
476 : (singleStream
477 ? HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize,
478 dctx->entropy.workspace, sizeof(dctx->entropy.workspace))
479 : HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart + lhSize, litCSize,
480 dctx->entropy.workspace, sizeof(dctx->entropy.workspace)))))
481 return ERROR(corruption_detected);
482
483 dctx->litPtr = dctx->litBuffer;
484 dctx->litSize = litSize;
485 dctx->litEntropy = 1;
486 if (litEncType == set_compressed)
487 dctx->HUFptr = dctx->entropy.hufTable;
488 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
489 return litCSize + lhSize;
490 }
491
492 case set_basic: {
493 size_t litSize, lhSize;
494 U32 const lhlCode = ((istart[0]) >> 2) & 3;
495 switch (lhlCode) {
496 case 0:
497 case 2:
498 default: /* note : default is impossible, since lhlCode into [0..3] */
499 lhSize = 1;
500 litSize = istart[0] >> 3;
501 break;
502 case 1:
503 lhSize = 2;
504 litSize = ZSTD_readLE16(istart) >> 4;
505 break;
506 case 3:
507 lhSize = 3;
508 litSize = ZSTD_readLE24(istart) >> 4;
509 break;
510 }
511
512 if (lhSize + litSize + WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
513 if (litSize + lhSize > srcSize)
514 return ERROR(corruption_detected);
515 memcpy(dctx->litBuffer, istart + lhSize, litSize);
516 dctx->litPtr = dctx->litBuffer;
517 dctx->litSize = litSize;
518 memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
519 return lhSize + litSize;
520 }
521 /* direct reference into compressed stream */
522 dctx->litPtr = istart + lhSize;
523 dctx->litSize = litSize;
524 return lhSize + litSize;
525 }
526
527 case set_rle: {
528 U32 const lhlCode = ((istart[0]) >> 2) & 3;
529 size_t litSize, lhSize;
530 switch (lhlCode) {
531 case 0:
532 case 2:
533 default: /* note : default is impossible, since lhlCode into [0..3] */
534 lhSize = 1;
535 litSize = istart[0] >> 3;
536 break;
537 case 1:
538 lhSize = 2;
539 litSize = ZSTD_readLE16(istart) >> 4;
540 break;
541 case 3:
542 lhSize = 3;
543 litSize = ZSTD_readLE24(istart) >> 4;
544 if (srcSize < 4)
545 return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
546 break;
547 }
548 if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX)
549 return ERROR(corruption_detected);
550 memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
551 dctx->litPtr = dctx->litBuffer;
552 dctx->litSize = litSize;
553 return lhSize + 1;
554 }
555 default:
556 return ERROR(corruption_detected); /* impossible */
557 }
558 }
559 }
560
561 typedef union {
562 FSE_decode_t realData;
563 U32 alignedBy4;
564 } FSE_decode_t4;
565
566 static const FSE_decode_t4 LL_defaultDTable[(1 << LL_DEFAULTNORMLOG) + 1] = {
567 {{LL_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */
568 {{0, 0, 4}}, /* 0 : base, symbol, bits */
569 {{16, 0, 4}},
570 {{32, 1, 5}},
571 {{0, 3, 5}},
572 {{0, 4, 5}},
573 {{0, 6, 5}},
574 {{0, 7, 5}},
575 {{0, 9, 5}},
576 {{0, 10, 5}},
577 {{0, 12, 5}},
578 {{0, 14, 6}},
579 {{0, 16, 5}},
580 {{0, 18, 5}},
581 {{0, 19, 5}},
582 {{0, 21, 5}},
583 {{0, 22, 5}},
584 {{0, 24, 5}},
585 {{32, 25, 5}},
586 {{0, 26, 5}},
587 {{0, 27, 6}},
588 {{0, 29, 6}},
589 {{0, 31, 6}},
590 {{32, 0, 4}},
591 {{0, 1, 4}},
592 {{0, 2, 5}},
593 {{32, 4, 5}},
594 {{0, 5, 5}},
595 {{32, 7, 5}},
596 {{0, 8, 5}},
597 {{32, 10, 5}},
598 {{0, 11, 5}},
599 {{0, 13, 6}},
600 {{32, 16, 5}},
601 {{0, 17, 5}},
602 {{32, 19, 5}},
603 {{0, 20, 5}},
604 {{32, 22, 5}},
605 {{0, 23, 5}},
606 {{0, 25, 4}},
607 {{16, 25, 4}},
608 {{32, 26, 5}},
609 {{0, 28, 6}},
610 {{0, 30, 6}},
611 {{48, 0, 4}},
612 {{16, 1, 4}},
613 {{32, 2, 5}},
614 {{32, 3, 5}},
615 {{32, 5, 5}},
616 {{32, 6, 5}},
617 {{32, 8, 5}},
618 {{32, 9, 5}},
619 {{32, 11, 5}},
620 {{32, 12, 5}},
621 {{0, 15, 6}},
622 {{32, 17, 5}},
623 {{32, 18, 5}},
624 {{32, 20, 5}},
625 {{32, 21, 5}},
626 {{32, 23, 5}},
627 {{32, 24, 5}},
628 {{0, 35, 6}},
629 {{0, 34, 6}},
630 {{0, 33, 6}},
631 {{0, 32, 6}},
632 }; /* LL_defaultDTable */
633
634 static const FSE_decode_t4 ML_defaultDTable[(1 << ML_DEFAULTNORMLOG) + 1] = {
635 {{ML_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */
636 {{0, 0, 6}}, /* 0 : base, symbol, bits */
637 {{0, 1, 4}},
638 {{32, 2, 5}},
639 {{0, 3, 5}},
640 {{0, 5, 5}},
641 {{0, 6, 5}},
642 {{0, 8, 5}},
643 {{0, 10, 6}},
644 {{0, 13, 6}},
645 {{0, 16, 6}},
646 {{0, 19, 6}},
647 {{0, 22, 6}},
648 {{0, 25, 6}},
649 {{0, 28, 6}},
650 {{0, 31, 6}},
651 {{0, 33, 6}},
652 {{0, 35, 6}},
653 {{0, 37, 6}},
654 {{0, 39, 6}},
655 {{0, 41, 6}},
656 {{0, 43, 6}},
657 {{0, 45, 6}},
658 {{16, 1, 4}},
659 {{0, 2, 4}},
660 {{32, 3, 5}},
661 {{0, 4, 5}},
662 {{32, 6, 5}},
663 {{0, 7, 5}},
664 {{0, 9, 6}},
665 {{0, 12, 6}},
666 {{0, 15, 6}},
667 {{0, 18, 6}},
668 {{0, 21, 6}},
669 {{0, 24, 6}},
670 {{0, 27, 6}},
671 {{0, 30, 6}},
672 {{0, 32, 6}},
673 {{0, 34, 6}},
674 {{0, 36, 6}},
675 {{0, 38, 6}},
676 {{0, 40, 6}},
677 {{0, 42, 6}},
678 {{0, 44, 6}},
679 {{32, 1, 4}},
680 {{48, 1, 4}},
681 {{16, 2, 4}},
682 {{32, 4, 5}},
683 {{32, 5, 5}},
684 {{32, 7, 5}},
685 {{32, 8, 5}},
686 {{0, 11, 6}},
687 {{0, 14, 6}},
688 {{0, 17, 6}},
689 {{0, 20, 6}},
690 {{0, 23, 6}},
691 {{0, 26, 6}},
692 {{0, 29, 6}},
693 {{0, 52, 6}},
694 {{0, 51, 6}},
695 {{0, 50, 6}},
696 {{0, 49, 6}},
697 {{0, 48, 6}},
698 {{0, 47, 6}},
699 {{0, 46, 6}},
700 }; /* ML_defaultDTable */
701
702 static const FSE_decode_t4 OF_defaultDTable[(1 << OF_DEFAULTNORMLOG) + 1] = {
703 {{OF_DEFAULTNORMLOG, 1, 1}}, /* header : tableLog, fastMode, fastMode */
704 {{0, 0, 5}}, /* 0 : base, symbol, bits */
705 {{0, 6, 4}},
706 {{0, 9, 5}},
707 {{0, 15, 5}},
708 {{0, 21, 5}},
709 {{0, 3, 5}},
710 {{0, 7, 4}},
711 {{0, 12, 5}},
712 {{0, 18, 5}},
713 {{0, 23, 5}},
714 {{0, 5, 5}},
715 {{0, 8, 4}},
716 {{0, 14, 5}},
717 {{0, 20, 5}},
718 {{0, 2, 5}},
719 {{16, 7, 4}},
720 {{0, 11, 5}},
721 {{0, 17, 5}},
722 {{0, 22, 5}},
723 {{0, 4, 5}},
724 {{16, 8, 4}},
725 {{0, 13, 5}},
726 {{0, 19, 5}},
727 {{0, 1, 5}},
728 {{16, 6, 4}},
729 {{0, 10, 5}},
730 {{0, 16, 5}},
731 {{0, 28, 5}},
732 {{0, 27, 5}},
733 {{0, 26, 5}},
734 {{0, 25, 5}},
735 {{0, 24, 5}},
736 }; /* OF_defaultDTable */
737
738 /*! ZSTD_buildSeqTable() :
739 @return : nb bytes read from src,
740 or an error code if it fails, testable with ZSTD_isError()
741 */
ZSTD_buildSeqTable(FSE_DTable * DTableSpace,const FSE_DTable ** DTablePtr,symbolEncodingType_e type,U32 max,U32 maxLog,const void * src,size_t srcSize,const FSE_decode_t4 * defaultTable,U32 flagRepeatTable,void * workspace,size_t workspaceSize)742 static size_t ZSTD_buildSeqTable(FSE_DTable *DTableSpace, const FSE_DTable **DTablePtr, symbolEncodingType_e type, U32 max, U32 maxLog, const void *src,
743 size_t srcSize, const FSE_decode_t4 *defaultTable, U32 flagRepeatTable, void *workspace, size_t workspaceSize)
744 {
745 const void *const tmpPtr = defaultTable; /* bypass strict aliasing */
746 switch (type) {
747 case set_rle:
748 if (!srcSize)
749 return ERROR(srcSize_wrong);
750 if ((*(const BYTE *)src) > max)
751 return ERROR(corruption_detected);
752 FSE_buildDTable_rle(DTableSpace, *(const BYTE *)src);
753 *DTablePtr = DTableSpace;
754 return 1;
755 case set_basic: *DTablePtr = (const FSE_DTable *)tmpPtr; return 0;
756 case set_repeat:
757 if (!flagRepeatTable)
758 return ERROR(corruption_detected);
759 return 0;
760 default: /* impossible */
761 case set_compressed: {
762 U32 tableLog;
763 S16 *norm = (S16 *)workspace;
764 size_t const spaceUsed32 = ALIGN(sizeof(S16) * (MaxSeq + 1), sizeof(U32)) >> 2;
765
766 if ((spaceUsed32 << 2) > workspaceSize)
767 return ERROR(GENERIC);
768 workspace = (U32 *)workspace + spaceUsed32;
769 workspaceSize -= (spaceUsed32 << 2);
770 {
771 size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
772 if (FSE_isError(headerSize))
773 return ERROR(corruption_detected);
774 if (tableLog > maxLog)
775 return ERROR(corruption_detected);
776 FSE_buildDTable_wksp(DTableSpace, norm, max, tableLog, workspace, workspaceSize);
777 *DTablePtr = DTableSpace;
778 return headerSize;
779 }
780 }
781 }
782 }
783
ZSTD_decodeSeqHeaders(ZSTD_DCtx * dctx,int * nbSeqPtr,const void * src,size_t srcSize)784 size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx *dctx, int *nbSeqPtr, const void *src, size_t srcSize)
785 {
786 const BYTE *const istart = (const BYTE *const)src;
787 const BYTE *const iend = istart + srcSize;
788 const BYTE *ip = istart;
789
790 /* check */
791 if (srcSize < MIN_SEQUENCES_SIZE)
792 return ERROR(srcSize_wrong);
793
794 /* SeqHead */
795 {
796 int nbSeq = *ip++;
797 if (!nbSeq) {
798 *nbSeqPtr = 0;
799 return 1;
800 }
801 if (nbSeq > 0x7F) {
802 if (nbSeq == 0xFF) {
803 if (ip + 2 > iend)
804 return ERROR(srcSize_wrong);
805 nbSeq = ZSTD_readLE16(ip) + LONGNBSEQ, ip += 2;
806 } else {
807 if (ip >= iend)
808 return ERROR(srcSize_wrong);
809 nbSeq = ((nbSeq - 0x80) << 8) + *ip++;
810 }
811 }
812 *nbSeqPtr = nbSeq;
813 }
814
815 /* FSE table descriptors */
816 if (ip + 4 > iend)
817 return ERROR(srcSize_wrong); /* minimum possible size */
818 {
819 symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
820 symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
821 symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
822 ip++;
823
824 /* Build DTables */
825 {
826 size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr, LLtype, MaxLL, LLFSELog, ip, iend - ip,
827 LL_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace));
828 if (ZSTD_isError(llhSize))
829 return ERROR(corruption_detected);
830 ip += llhSize;
831 }
832 {
833 size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr, OFtype, MaxOff, OffFSELog, ip, iend - ip,
834 OF_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace));
835 if (ZSTD_isError(ofhSize))
836 return ERROR(corruption_detected);
837 ip += ofhSize;
838 }
839 {
840 size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr, MLtype, MaxML, MLFSELog, ip, iend - ip,
841 ML_defaultDTable, dctx->fseEntropy, dctx->entropy.workspace, sizeof(dctx->entropy.workspace));
842 if (ZSTD_isError(mlhSize))
843 return ERROR(corruption_detected);
844 ip += mlhSize;
845 }
846 }
847
848 return ip - istart;
849 }
850
851 typedef struct {
852 size_t litLength;
853 size_t matchLength;
854 size_t offset;
855 const BYTE *match;
856 } seq_t;
857
858 typedef struct {
859 BIT_DStream_t DStream;
860 FSE_DState_t stateLL;
861 FSE_DState_t stateOffb;
862 FSE_DState_t stateML;
863 size_t prevOffset[ZSTD_REP_NUM];
864 const BYTE *base;
865 size_t pos;
866 uPtrDiff gotoDict;
867 } seqState_t;
868
869 FORCE_NOINLINE
ZSTD_execSequenceLast7(BYTE * op,BYTE * const oend,seq_t sequence,const BYTE ** litPtr,const BYTE * const litLimit,const BYTE * const base,const BYTE * const vBase,const BYTE * const dictEnd)870 size_t ZSTD_execSequenceLast7(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
871 const BYTE *const vBase, const BYTE *const dictEnd)
872 {
873 BYTE *const oLitEnd = op + sequence.litLength;
874 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
875 BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
876 BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
877 const BYTE *const iLitEnd = *litPtr + sequence.litLength;
878 const BYTE *match = oLitEnd - sequence.offset;
879
880 /* check */
881 if (oMatchEnd > oend)
882 return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
883 if (iLitEnd > litLimit)
884 return ERROR(corruption_detected); /* over-read beyond lit buffer */
885 if (oLitEnd <= oend_w)
886 return ERROR(GENERIC); /* Precondition */
887
888 /* copy literals */
889 if (op < oend_w) {
890 ZSTD_wildcopy(op, *litPtr, oend_w - op);
891 *litPtr += oend_w - op;
892 op = oend_w;
893 }
894 while (op < oLitEnd)
895 *op++ = *(*litPtr)++;
896
897 /* copy Match */
898 if (sequence.offset > (size_t)(oLitEnd - base)) {
899 /* offset beyond prefix */
900 if (sequence.offset > (size_t)(oLitEnd - vBase))
901 return ERROR(corruption_detected);
902 match = dictEnd - (base - match);
903 if (match + sequence.matchLength <= dictEnd) {
904 memmove(oLitEnd, match, sequence.matchLength);
905 return sequenceLength;
906 }
907 /* span extDict & currPrefixSegment */
908 {
909 size_t const length1 = dictEnd - match;
910 memmove(oLitEnd, match, length1);
911 op = oLitEnd + length1;
912 sequence.matchLength -= length1;
913 match = base;
914 }
915 }
916 while (op < oMatchEnd)
917 *op++ = *match++;
918 return sequenceLength;
919 }
920
ZSTD_decodeSequence(seqState_t * seqState)921 static seq_t ZSTD_decodeSequence(seqState_t *seqState)
922 {
923 seq_t seq;
924
925 U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
926 U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
927 U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
928
929 U32 const llBits = LL_bits[llCode];
930 U32 const mlBits = ML_bits[mlCode];
931 U32 const ofBits = ofCode;
932 U32 const totalBits = llBits + mlBits + ofBits;
933
934 static const U32 LL_base[MaxLL + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18,
935 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
936
937 static const U32 ML_base[MaxML + 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
938 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41,
939 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
940
941 static const U32 OF_base[MaxOff + 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD,
942 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD,
943 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
944
945 /* sequence */
946 {
947 size_t offset;
948 if (!ofCode)
949 offset = 0;
950 else {
951 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
952 if (ZSTD_32bits())
953 BIT_reloadDStream(&seqState->DStream);
954 }
955
956 if (ofCode <= 1) {
957 offset += (llCode == 0);
958 if (offset) {
959 size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
960 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
961 if (offset != 1)
962 seqState->prevOffset[2] = seqState->prevOffset[1];
963 seqState->prevOffset[1] = seqState->prevOffset[0];
964 seqState->prevOffset[0] = offset = temp;
965 } else {
966 offset = seqState->prevOffset[0];
967 }
968 } else {
969 seqState->prevOffset[2] = seqState->prevOffset[1];
970 seqState->prevOffset[1] = seqState->prevOffset[0];
971 seqState->prevOffset[0] = offset;
972 }
973 seq.offset = offset;
974 }
975
976 seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
977 if (ZSTD_32bits() && (mlBits + llBits > 24))
978 BIT_reloadDStream(&seqState->DStream);
979
980 seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
981 if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog)))
982 BIT_reloadDStream(&seqState->DStream);
983
984 /* ANS state update */
985 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
986 FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
987 if (ZSTD_32bits())
988 BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
989 FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
990
991 seq.match = NULL;
992
993 return seq;
994 }
995
996 FORCE_INLINE
ZSTD_execSequence(BYTE * op,BYTE * const oend,seq_t sequence,const BYTE ** litPtr,const BYTE * const litLimit,const BYTE * const base,const BYTE * const vBase,const BYTE * const dictEnd)997 size_t ZSTD_execSequence(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
998 const BYTE *const vBase, const BYTE *const dictEnd)
999 {
1000 BYTE *const oLitEnd = op + sequence.litLength;
1001 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1002 BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1003 BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
1004 const BYTE *const iLitEnd = *litPtr + sequence.litLength;
1005 const BYTE *match = oLitEnd - sequence.offset;
1006
1007 /* check */
1008 if (oMatchEnd > oend)
1009 return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1010 if (iLitEnd > litLimit)
1011 return ERROR(corruption_detected); /* over-read beyond lit buffer */
1012 if (oLitEnd > oend_w)
1013 return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1014
1015 /* copy Literals */
1016 ZSTD_copy8(op, *litPtr);
1017 if (sequence.litLength > 8)
1018 ZSTD_wildcopy(op + 8, (*litPtr) + 8,
1019 sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1020 op = oLitEnd;
1021 *litPtr = iLitEnd; /* update for next sequence */
1022
1023 /* copy Match */
1024 if (sequence.offset > (size_t)(oLitEnd - base)) {
1025 /* offset beyond prefix */
1026 if (sequence.offset > (size_t)(oLitEnd - vBase))
1027 return ERROR(corruption_detected);
1028 match = dictEnd + (match - base);
1029 if (match + sequence.matchLength <= dictEnd) {
1030 memmove(oLitEnd, match, sequence.matchLength);
1031 return sequenceLength;
1032 }
1033 /* span extDict & currPrefixSegment */
1034 {
1035 size_t const length1 = dictEnd - match;
1036 memmove(oLitEnd, match, length1);
1037 op = oLitEnd + length1;
1038 sequence.matchLength -= length1;
1039 match = base;
1040 if (op > oend_w || sequence.matchLength < MINMATCH) {
1041 U32 i;
1042 for (i = 0; i < sequence.matchLength; ++i)
1043 op[i] = match[i];
1044 return sequenceLength;
1045 }
1046 }
1047 }
1048 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1049
1050 /* match within prefix */
1051 if (sequence.offset < 8) {
1052 /* close range match, overlap */
1053 static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
1054 static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
1055 int const sub2 = dec64table[sequence.offset];
1056 op[0] = match[0];
1057 op[1] = match[1];
1058 op[2] = match[2];
1059 op[3] = match[3];
1060 match += dec32table[sequence.offset];
1061 ZSTD_copy4(op + 4, match);
1062 match -= sub2;
1063 } else {
1064 ZSTD_copy8(op, match);
1065 }
1066 op += 8;
1067 match += 8;
1068
1069 if (oMatchEnd > oend - (16 - MINMATCH)) {
1070 if (op < oend_w) {
1071 ZSTD_wildcopy(op, match, oend_w - op);
1072 match += oend_w - op;
1073 op = oend_w;
1074 }
1075 while (op < oMatchEnd)
1076 *op++ = *match++;
1077 } else {
1078 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */
1079 }
1080 return sequenceLength;
1081 }
1082
ZSTD_decompressSequences(ZSTD_DCtx * dctx,void * dst,size_t maxDstSize,const void * seqStart,size_t seqSize)1083 static size_t ZSTD_decompressSequences(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize)
1084 {
1085 const BYTE *ip = (const BYTE *)seqStart;
1086 const BYTE *const iend = ip + seqSize;
1087 BYTE *const ostart = (BYTE * const)dst;
1088 BYTE *const oend = ostart + maxDstSize;
1089 BYTE *op = ostart;
1090 const BYTE *litPtr = dctx->litPtr;
1091 const BYTE *const litEnd = litPtr + dctx->litSize;
1092 const BYTE *const base = (const BYTE *)(dctx->base);
1093 const BYTE *const vBase = (const BYTE *)(dctx->vBase);
1094 const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd);
1095 int nbSeq;
1096
1097 /* Build Decoding Tables */
1098 {
1099 size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1100 if (ZSTD_isError(seqHSize))
1101 return seqHSize;
1102 ip += seqHSize;
1103 }
1104
1105 /* Regen sequences */
1106 if (nbSeq) {
1107 seqState_t seqState;
1108 dctx->fseEntropy = 1;
1109 {
1110 U32 i;
1111 for (i = 0; i < ZSTD_REP_NUM; i++)
1112 seqState.prevOffset[i] = dctx->entropy.rep[i];
1113 }
1114 CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected);
1115 FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1116 FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1117 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1118
1119 for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq;) {
1120 nbSeq--;
1121 {
1122 seq_t const sequence = ZSTD_decodeSequence(&seqState);
1123 size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
1124 if (ZSTD_isError(oneSeqSize))
1125 return oneSeqSize;
1126 op += oneSeqSize;
1127 }
1128 }
1129
1130 /* check if reached exact end */
1131 if (nbSeq)
1132 return ERROR(corruption_detected);
1133 /* save reps for next block */
1134 {
1135 U32 i;
1136 for (i = 0; i < ZSTD_REP_NUM; i++)
1137 dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]);
1138 }
1139 }
1140
1141 /* last literal segment */
1142 {
1143 size_t const lastLLSize = litEnd - litPtr;
1144 if (lastLLSize > (size_t)(oend - op))
1145 return ERROR(dstSize_tooSmall);
1146 memcpy(op, litPtr, lastLLSize);
1147 op += lastLLSize;
1148 }
1149
1150 return op - ostart;
1151 }
1152
ZSTD_decodeSequenceLong_generic(seqState_t * seqState,int const longOffsets)1153 FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t *seqState, int const longOffsets)
1154 {
1155 seq_t seq;
1156
1157 U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
1158 U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
1159 U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
1160
1161 U32 const llBits = LL_bits[llCode];
1162 U32 const mlBits = ML_bits[mlCode];
1163 U32 const ofBits = ofCode;
1164 U32 const totalBits = llBits + mlBits + ofBits;
1165
1166 static const U32 LL_base[MaxLL + 1] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18,
1167 20, 22, 24, 28, 32, 40, 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000};
1168
1169 static const U32 ML_base[MaxML + 1] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
1170 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41,
1171 43, 47, 51, 59, 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803, 0x1003, 0x2003, 0x4003, 0x8003, 0x10003};
1172
1173 static const U32 OF_base[MaxOff + 1] = {0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D, 0xFD, 0x1FD,
1174 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD, 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD,
1175 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD, 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD};
1176
1177 /* sequence */
1178 {
1179 size_t offset;
1180 if (!ofCode)
1181 offset = 0;
1182 else {
1183 if (longOffsets) {
1184 int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
1185 offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
1186 if (ZSTD_32bits() || extraBits)
1187 BIT_reloadDStream(&seqState->DStream);
1188 if (extraBits)
1189 offset += BIT_readBitsFast(&seqState->DStream, extraBits);
1190 } else {
1191 offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1192 if (ZSTD_32bits())
1193 BIT_reloadDStream(&seqState->DStream);
1194 }
1195 }
1196
1197 if (ofCode <= 1) {
1198 offset += (llCode == 0);
1199 if (offset) {
1200 size_t temp = (offset == 3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1201 temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
1202 if (offset != 1)
1203 seqState->prevOffset[2] = seqState->prevOffset[1];
1204 seqState->prevOffset[1] = seqState->prevOffset[0];
1205 seqState->prevOffset[0] = offset = temp;
1206 } else {
1207 offset = seqState->prevOffset[0];
1208 }
1209 } else {
1210 seqState->prevOffset[2] = seqState->prevOffset[1];
1211 seqState->prevOffset[1] = seqState->prevOffset[0];
1212 seqState->prevOffset[0] = offset;
1213 }
1214 seq.offset = offset;
1215 }
1216
1217 seq.matchLength = ML_base[mlCode] + ((mlCode > 31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
1218 if (ZSTD_32bits() && (mlBits + llBits > 24))
1219 BIT_reloadDStream(&seqState->DStream);
1220
1221 seq.litLength = LL_base[llCode] + ((llCode > 15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
1222 if (ZSTD_32bits() || (totalBits > 64 - 7 - (LLFSELog + MLFSELog + OffFSELog)))
1223 BIT_reloadDStream(&seqState->DStream);
1224
1225 {
1226 size_t const pos = seqState->pos + seq.litLength;
1227 seq.match = seqState->base + pos - seq.offset; /* single memory segment */
1228 if (seq.offset > pos)
1229 seq.match += seqState->gotoDict; /* separate memory segment */
1230 seqState->pos = pos + seq.matchLength;
1231 }
1232
1233 /* ANS state update */
1234 FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
1235 FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
1236 if (ZSTD_32bits())
1237 BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1238 FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
1239
1240 return seq;
1241 }
1242
ZSTD_decodeSequenceLong(seqState_t * seqState,unsigned const windowSize)1243 static seq_t ZSTD_decodeSequenceLong(seqState_t *seqState, unsigned const windowSize)
1244 {
1245 if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
1246 return ZSTD_decodeSequenceLong_generic(seqState, 1);
1247 } else {
1248 return ZSTD_decodeSequenceLong_generic(seqState, 0);
1249 }
1250 }
1251
1252 FORCE_INLINE
ZSTD_execSequenceLong(BYTE * op,BYTE * const oend,seq_t sequence,const BYTE ** litPtr,const BYTE * const litLimit,const BYTE * const base,const BYTE * const vBase,const BYTE * const dictEnd)1253 size_t ZSTD_execSequenceLong(BYTE *op, BYTE *const oend, seq_t sequence, const BYTE **litPtr, const BYTE *const litLimit, const BYTE *const base,
1254 const BYTE *const vBase, const BYTE *const dictEnd)
1255 {
1256 BYTE *const oLitEnd = op + sequence.litLength;
1257 size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1258 BYTE *const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1259 BYTE *const oend_w = oend - WILDCOPY_OVERLENGTH;
1260 const BYTE *const iLitEnd = *litPtr + sequence.litLength;
1261 const BYTE *match = sequence.match;
1262
1263 /* check */
1264 if (oMatchEnd > oend)
1265 return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1266 if (iLitEnd > litLimit)
1267 return ERROR(corruption_detected); /* over-read beyond lit buffer */
1268 if (oLitEnd > oend_w)
1269 return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1270
1271 /* copy Literals */
1272 ZSTD_copy8(op, *litPtr);
1273 if (sequence.litLength > 8)
1274 ZSTD_wildcopy(op + 8, (*litPtr) + 8,
1275 sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1276 op = oLitEnd;
1277 *litPtr = iLitEnd; /* update for next sequence */
1278
1279 /* copy Match */
1280 if (sequence.offset > (size_t)(oLitEnd - base)) {
1281 /* offset beyond prefix */
1282 if (sequence.offset > (size_t)(oLitEnd - vBase))
1283 return ERROR(corruption_detected);
1284 if (match + sequence.matchLength <= dictEnd) {
1285 memmove(oLitEnd, match, sequence.matchLength);
1286 return sequenceLength;
1287 }
1288 /* span extDict & currPrefixSegment */
1289 {
1290 size_t const length1 = dictEnd - match;
1291 memmove(oLitEnd, match, length1);
1292 op = oLitEnd + length1;
1293 sequence.matchLength -= length1;
1294 match = base;
1295 if (op > oend_w || sequence.matchLength < MINMATCH) {
1296 U32 i;
1297 for (i = 0; i < sequence.matchLength; ++i)
1298 op[i] = match[i];
1299 return sequenceLength;
1300 }
1301 }
1302 }
1303 /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1304
1305 /* match within prefix */
1306 if (sequence.offset < 8) {
1307 /* close range match, overlap */
1308 static const U32 dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4}; /* added */
1309 static const int dec64table[] = {8, 8, 8, 7, 8, 9, 10, 11}; /* subtracted */
1310 int const sub2 = dec64table[sequence.offset];
1311 op[0] = match[0];
1312 op[1] = match[1];
1313 op[2] = match[2];
1314 op[3] = match[3];
1315 match += dec32table[sequence.offset];
1316 ZSTD_copy4(op + 4, match);
1317 match -= sub2;
1318 } else {
1319 ZSTD_copy8(op, match);
1320 }
1321 op += 8;
1322 match += 8;
1323
1324 if (oMatchEnd > oend - (16 - MINMATCH)) {
1325 if (op < oend_w) {
1326 ZSTD_wildcopy(op, match, oend_w - op);
1327 match += oend_w - op;
1328 op = oend_w;
1329 }
1330 while (op < oMatchEnd)
1331 *op++ = *match++;
1332 } else {
1333 ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength - 8); /* works even if matchLength < 8 */
1334 }
1335 return sequenceLength;
1336 }
1337
ZSTD_decompressSequencesLong(ZSTD_DCtx * dctx,void * dst,size_t maxDstSize,const void * seqStart,size_t seqSize)1338 static size_t ZSTD_decompressSequencesLong(ZSTD_DCtx *dctx, void *dst, size_t maxDstSize, const void *seqStart, size_t seqSize)
1339 {
1340 const BYTE *ip = (const BYTE *)seqStart;
1341 const BYTE *const iend = ip + seqSize;
1342 BYTE *const ostart = (BYTE * const)dst;
1343 BYTE *const oend = ostart + maxDstSize;
1344 BYTE *op = ostart;
1345 const BYTE *litPtr = dctx->litPtr;
1346 const BYTE *const litEnd = litPtr + dctx->litSize;
1347 const BYTE *const base = (const BYTE *)(dctx->base);
1348 const BYTE *const vBase = (const BYTE *)(dctx->vBase);
1349 const BYTE *const dictEnd = (const BYTE *)(dctx->dictEnd);
1350 unsigned const windowSize = dctx->fParams.windowSize;
1351 int nbSeq;
1352
1353 /* Build Decoding Tables */
1354 {
1355 size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1356 if (ZSTD_isError(seqHSize))
1357 return seqHSize;
1358 ip += seqHSize;
1359 }
1360
1361 /* Regen sequences */
1362 if (nbSeq) {
1363 #define STORED_SEQS 4
1364 #define STOSEQ_MASK (STORED_SEQS - 1)
1365 #define ADVANCED_SEQS 4
1366 seq_t *sequences = (seq_t *)dctx->entropy.workspace;
1367 int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
1368 seqState_t seqState;
1369 int seqNb;
1370 ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.workspace) >= sizeof(seq_t) * STORED_SEQS);
1371 dctx->fseEntropy = 1;
1372 {
1373 U32 i;
1374 for (i = 0; i < ZSTD_REP_NUM; i++)
1375 seqState.prevOffset[i] = dctx->entropy.rep[i];
1376 }
1377 seqState.base = base;
1378 seqState.pos = (size_t)(op - base);
1379 seqState.gotoDict = (uPtrDiff)dictEnd - (uPtrDiff)base; /* cast to avoid undefined behaviour */
1380 CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend - ip), corruption_detected);
1381 FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1382 FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1383 FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1384
1385 /* prepare in advance */
1386 for (seqNb = 0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb < seqAdvance; seqNb++) {
1387 sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, windowSize);
1388 }
1389 if (seqNb < seqAdvance)
1390 return ERROR(corruption_detected);
1391
1392 /* decode and decompress */
1393 for (; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb < nbSeq; seqNb++) {
1394 seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, windowSize);
1395 size_t const oneSeqSize =
1396 ZSTD_execSequenceLong(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
1397 if (ZSTD_isError(oneSeqSize))
1398 return oneSeqSize;
1399 ZSTD_PREFETCH(sequence.match);
1400 sequences[seqNb & STOSEQ_MASK] = sequence;
1401 op += oneSeqSize;
1402 }
1403 if (seqNb < nbSeq)
1404 return ERROR(corruption_detected);
1405
1406 /* finish queue */
1407 seqNb -= seqAdvance;
1408 for (; seqNb < nbSeq; seqNb++) {
1409 size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
1410 if (ZSTD_isError(oneSeqSize))
1411 return oneSeqSize;
1412 op += oneSeqSize;
1413 }
1414
1415 /* save reps for next block */
1416 {
1417 U32 i;
1418 for (i = 0; i < ZSTD_REP_NUM; i++)
1419 dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]);
1420 }
1421 }
1422
1423 /* last literal segment */
1424 {
1425 size_t const lastLLSize = litEnd - litPtr;
1426 if (lastLLSize > (size_t)(oend - op))
1427 return ERROR(dstSize_tooSmall);
1428 memcpy(op, litPtr, lastLLSize);
1429 op += lastLLSize;
1430 }
1431
1432 return op - ostart;
1433 }
1434
ZSTD_decompressBlock_internal(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize)1435 static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
1436 { /* blockType == blockCompressed */
1437 const BYTE *ip = (const BYTE *)src;
1438
1439 if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX)
1440 return ERROR(srcSize_wrong);
1441
1442 /* Decode literals section */
1443 {
1444 size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
1445 if (ZSTD_isError(litCSize))
1446 return litCSize;
1447 ip += litCSize;
1448 srcSize -= litCSize;
1449 }
1450 if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
1451 /* likely because of register pressure */
1452 /* if that's the correct cause, then 32-bits ARM should be affected differently */
1453 /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
1454 if (dctx->fParams.windowSize > (1 << 23))
1455 return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
1456 return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
1457 }
1458
ZSTD_checkContinuity(ZSTD_DCtx * dctx,const void * dst)1459 static void ZSTD_checkContinuity(ZSTD_DCtx *dctx, const void *dst)
1460 {
1461 if (dst != dctx->previousDstEnd) { /* not contiguous */
1462 dctx->dictEnd = dctx->previousDstEnd;
1463 dctx->vBase = (const char *)dst - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base));
1464 dctx->base = dst;
1465 dctx->previousDstEnd = dst;
1466 }
1467 }
1468
ZSTD_decompressBlock(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize)1469 size_t ZSTD_decompressBlock(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
1470 {
1471 size_t dSize;
1472 ZSTD_checkContinuity(dctx, dst);
1473 dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
1474 dctx->previousDstEnd = (char *)dst + dSize;
1475 return dSize;
1476 }
1477
1478 /** ZSTD_insertBlock() :
1479 insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
ZSTD_insertBlock(ZSTD_DCtx * dctx,const void * blockStart,size_t blockSize)1480 size_t ZSTD_insertBlock(ZSTD_DCtx *dctx, const void *blockStart, size_t blockSize)
1481 {
1482 ZSTD_checkContinuity(dctx, blockStart);
1483 dctx->previousDstEnd = (const char *)blockStart + blockSize;
1484 return blockSize;
1485 }
1486
ZSTD_generateNxBytes(void * dst,size_t dstCapacity,BYTE byte,size_t length)1487 size_t ZSTD_generateNxBytes(void *dst, size_t dstCapacity, BYTE byte, size_t length)
1488 {
1489 if (length > dstCapacity)
1490 return ERROR(dstSize_tooSmall);
1491 memset(dst, byte, length);
1492 return length;
1493 }
1494
1495 /** ZSTD_findFrameCompressedSize() :
1496 * compatible with legacy mode
1497 * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
1498 * `srcSize` must be at least as large as the frame contained
1499 * @return : the compressed size of the frame starting at `src` */
ZSTD_findFrameCompressedSize(const void * src,size_t srcSize)1500 size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
1501 {
1502 if (srcSize >= ZSTD_skippableHeaderSize && (ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1503 return ZSTD_skippableHeaderSize + ZSTD_readLE32((const BYTE *)src + 4);
1504 } else {
1505 const BYTE *ip = (const BYTE *)src;
1506 const BYTE *const ipstart = ip;
1507 size_t remainingSize = srcSize;
1508 ZSTD_frameParams fParams;
1509
1510 size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize);
1511 if (ZSTD_isError(headerSize))
1512 return headerSize;
1513
1514 /* Frame Header */
1515 {
1516 size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
1517 if (ZSTD_isError(ret))
1518 return ret;
1519 if (ret > 0)
1520 return ERROR(srcSize_wrong);
1521 }
1522
1523 ip += headerSize;
1524 remainingSize -= headerSize;
1525
1526 /* Loop on each block */
1527 while (1) {
1528 blockProperties_t blockProperties;
1529 size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
1530 if (ZSTD_isError(cBlockSize))
1531 return cBlockSize;
1532
1533 if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
1534 return ERROR(srcSize_wrong);
1535
1536 ip += ZSTD_blockHeaderSize + cBlockSize;
1537 remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
1538
1539 if (blockProperties.lastBlock)
1540 break;
1541 }
1542
1543 if (fParams.checksumFlag) { /* Frame content checksum */
1544 if (remainingSize < 4)
1545 return ERROR(srcSize_wrong);
1546 ip += 4;
1547 remainingSize -= 4;
1548 }
1549
1550 return ip - ipstart;
1551 }
1552 }
1553
1554 /*! ZSTD_decompressFrame() :
1555 * @dctx must be properly initialized */
ZSTD_decompressFrame(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void ** srcPtr,size_t * srcSizePtr)1556 static size_t ZSTD_decompressFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void **srcPtr, size_t *srcSizePtr)
1557 {
1558 const BYTE *ip = (const BYTE *)(*srcPtr);
1559 BYTE *const ostart = (BYTE * const)dst;
1560 BYTE *const oend = ostart + dstCapacity;
1561 BYTE *op = ostart;
1562 size_t remainingSize = *srcSizePtr;
1563
1564 /* check */
1565 if (remainingSize < ZSTD_frameHeaderSize_min + ZSTD_blockHeaderSize)
1566 return ERROR(srcSize_wrong);
1567
1568 /* Frame Header */
1569 {
1570 size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
1571 if (ZSTD_isError(frameHeaderSize))
1572 return frameHeaderSize;
1573 if (remainingSize < frameHeaderSize + ZSTD_blockHeaderSize)
1574 return ERROR(srcSize_wrong);
1575 CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
1576 ip += frameHeaderSize;
1577 remainingSize -= frameHeaderSize;
1578 }
1579
1580 /* Loop on each block */
1581 while (1) {
1582 size_t decodedSize;
1583 blockProperties_t blockProperties;
1584 size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
1585 if (ZSTD_isError(cBlockSize))
1586 return cBlockSize;
1587
1588 ip += ZSTD_blockHeaderSize;
1589 remainingSize -= ZSTD_blockHeaderSize;
1590 if (cBlockSize > remainingSize)
1591 return ERROR(srcSize_wrong);
1592
1593 switch (blockProperties.blockType) {
1594 case bt_compressed: decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend - op, ip, cBlockSize); break;
1595 case bt_raw: decodedSize = ZSTD_copyRawBlock(op, oend - op, ip, cBlockSize); break;
1596 case bt_rle: decodedSize = ZSTD_generateNxBytes(op, oend - op, *ip, blockProperties.origSize); break;
1597 case bt_reserved:
1598 default: return ERROR(corruption_detected);
1599 }
1600
1601 if (ZSTD_isError(decodedSize))
1602 return decodedSize;
1603 if (dctx->fParams.checksumFlag)
1604 xxh64_update(&dctx->xxhState, op, decodedSize);
1605 op += decodedSize;
1606 ip += cBlockSize;
1607 remainingSize -= cBlockSize;
1608 if (blockProperties.lastBlock)
1609 break;
1610 }
1611
1612 if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1613 U32 const checkCalc = (U32)xxh64_digest(&dctx->xxhState);
1614 U32 checkRead;
1615 if (remainingSize < 4)
1616 return ERROR(checksum_wrong);
1617 checkRead = ZSTD_readLE32(ip);
1618 if (checkRead != checkCalc)
1619 return ERROR(checksum_wrong);
1620 ip += 4;
1621 remainingSize -= 4;
1622 }
1623
1624 /* Allow caller to get size read */
1625 *srcPtr = ip;
1626 *srcSizePtr = remainingSize;
1627 return op - ostart;
1628 }
1629
1630 static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict);
1631 static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict);
1632
ZSTD_decompressMultiFrame(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize,const void * dict,size_t dictSize,const ZSTD_DDict * ddict)1633 static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize,
1634 const ZSTD_DDict *ddict)
1635 {
1636 void *const dststart = dst;
1637
1638 if (ddict) {
1639 if (dict) {
1640 /* programmer error, these two cases should be mutually exclusive */
1641 return ERROR(GENERIC);
1642 }
1643
1644 dict = ZSTD_DDictDictContent(ddict);
1645 dictSize = ZSTD_DDictDictSize(ddict);
1646 }
1647
1648 while (srcSize >= ZSTD_frameHeaderSize_prefix) {
1649 U32 magicNumber;
1650
1651 magicNumber = ZSTD_readLE32(src);
1652 if (magicNumber != ZSTD_MAGICNUMBER) {
1653 if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1654 size_t skippableSize;
1655 if (srcSize < ZSTD_skippableHeaderSize)
1656 return ERROR(srcSize_wrong);
1657 skippableSize = ZSTD_readLE32((const BYTE *)src + 4) + ZSTD_skippableHeaderSize;
1658 if (srcSize < skippableSize) {
1659 return ERROR(srcSize_wrong);
1660 }
1661
1662 src = (const BYTE *)src + skippableSize;
1663 srcSize -= skippableSize;
1664 continue;
1665 } else {
1666 return ERROR(prefix_unknown);
1667 }
1668 }
1669
1670 if (ddict) {
1671 /* we were called from ZSTD_decompress_usingDDict */
1672 ZSTD_refDDict(dctx, ddict);
1673 } else {
1674 /* this will initialize correctly with no dict if dict == NULL, so
1675 * use this in all cases but ddict */
1676 CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
1677 }
1678 ZSTD_checkContinuity(dctx, dst);
1679
1680 {
1681 const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity, &src, &srcSize);
1682 if (ZSTD_isError(res))
1683 return res;
1684 /* don't need to bounds check this, ZSTD_decompressFrame will have
1685 * already */
1686 dst = (BYTE *)dst + res;
1687 dstCapacity -= res;
1688 }
1689 }
1690
1691 if (srcSize)
1692 return ERROR(srcSize_wrong); /* input not entirely consumed */
1693
1694 return (BYTE *)dst - (BYTE *)dststart;
1695 }
1696
ZSTD_decompress_usingDict(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize,const void * dict,size_t dictSize)1697 size_t ZSTD_decompress_usingDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const void *dict, size_t dictSize)
1698 {
1699 return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
1700 }
1701
ZSTD_decompressDCtx(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize)1702 size_t ZSTD_decompressDCtx(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
1703 {
1704 return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
1705 }
1706
1707 /*-**************************************
1708 * Advanced Streaming Decompression API
1709 * Bufferless and synchronous
1710 ****************************************/
ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx * dctx)1711 size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx *dctx) { return dctx->expected; }
1712
ZSTD_nextInputType(ZSTD_DCtx * dctx)1713 ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx *dctx)
1714 {
1715 switch (dctx->stage) {
1716 default: /* should not happen */
1717 case ZSTDds_getFrameHeaderSize:
1718 case ZSTDds_decodeFrameHeader: return ZSTDnit_frameHeader;
1719 case ZSTDds_decodeBlockHeader: return ZSTDnit_blockHeader;
1720 case ZSTDds_decompressBlock: return ZSTDnit_block;
1721 case ZSTDds_decompressLastBlock: return ZSTDnit_lastBlock;
1722 case ZSTDds_checkChecksum: return ZSTDnit_checksum;
1723 case ZSTDds_decodeSkippableHeader:
1724 case ZSTDds_skipFrame: return ZSTDnit_skippableFrame;
1725 }
1726 }
1727
ZSTD_isSkipFrame(ZSTD_DCtx * dctx)1728 int ZSTD_isSkipFrame(ZSTD_DCtx *dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
1729
1730 /** ZSTD_decompressContinue() :
1731 * @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1732 * or an error code, which can be tested using ZSTD_isError() */
ZSTD_decompressContinue(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize)1733 size_t ZSTD_decompressContinue(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize)
1734 {
1735 /* Sanity check */
1736 if (srcSize != dctx->expected)
1737 return ERROR(srcSize_wrong);
1738 if (dstCapacity)
1739 ZSTD_checkContinuity(dctx, dst);
1740
1741 switch (dctx->stage) {
1742 case ZSTDds_getFrameHeaderSize:
1743 if (srcSize != ZSTD_frameHeaderSize_prefix)
1744 return ERROR(srcSize_wrong); /* impossible */
1745 if ((ZSTD_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1746 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1747 dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
1748 dctx->stage = ZSTDds_decodeSkippableHeader;
1749 return 0;
1750 }
1751 dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
1752 if (ZSTD_isError(dctx->headerSize))
1753 return dctx->headerSize;
1754 memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
1755 if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
1756 dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
1757 dctx->stage = ZSTDds_decodeFrameHeader;
1758 return 0;
1759 }
1760 dctx->expected = 0; /* not necessary to copy more */
1761
1762 case ZSTDds_decodeFrameHeader:
1763 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1764 CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
1765 dctx->expected = ZSTD_blockHeaderSize;
1766 dctx->stage = ZSTDds_decodeBlockHeader;
1767 return 0;
1768
1769 case ZSTDds_decodeBlockHeader: {
1770 blockProperties_t bp;
1771 size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1772 if (ZSTD_isError(cBlockSize))
1773 return cBlockSize;
1774 dctx->expected = cBlockSize;
1775 dctx->bType = bp.blockType;
1776 dctx->rleSize = bp.origSize;
1777 if (cBlockSize) {
1778 dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
1779 return 0;
1780 }
1781 /* empty block */
1782 if (bp.lastBlock) {
1783 if (dctx->fParams.checksumFlag) {
1784 dctx->expected = 4;
1785 dctx->stage = ZSTDds_checkChecksum;
1786 } else {
1787 dctx->expected = 0; /* end of frame */
1788 dctx->stage = ZSTDds_getFrameHeaderSize;
1789 }
1790 } else {
1791 dctx->expected = 3; /* go directly to next header */
1792 dctx->stage = ZSTDds_decodeBlockHeader;
1793 }
1794 return 0;
1795 }
1796 case ZSTDds_decompressLastBlock:
1797 case ZSTDds_decompressBlock: {
1798 size_t rSize;
1799 switch (dctx->bType) {
1800 case bt_compressed: rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize); break;
1801 case bt_raw: rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize); break;
1802 case bt_rle: rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize); break;
1803 case bt_reserved: /* should never happen */
1804 default: return ERROR(corruption_detected);
1805 }
1806 if (ZSTD_isError(rSize))
1807 return rSize;
1808 if (dctx->fParams.checksumFlag)
1809 xxh64_update(&dctx->xxhState, dst, rSize);
1810
1811 if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1812 if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1813 dctx->expected = 4;
1814 dctx->stage = ZSTDds_checkChecksum;
1815 } else {
1816 dctx->expected = 0; /* ends here */
1817 dctx->stage = ZSTDds_getFrameHeaderSize;
1818 }
1819 } else {
1820 dctx->stage = ZSTDds_decodeBlockHeader;
1821 dctx->expected = ZSTD_blockHeaderSize;
1822 dctx->previousDstEnd = (char *)dst + rSize;
1823 }
1824 return rSize;
1825 }
1826 case ZSTDds_checkChecksum: {
1827 U32 const h32 = (U32)xxh64_digest(&dctx->xxhState);
1828 U32 const check32 = ZSTD_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
1829 if (check32 != h32)
1830 return ERROR(checksum_wrong);
1831 dctx->expected = 0;
1832 dctx->stage = ZSTDds_getFrameHeaderSize;
1833 return 0;
1834 }
1835 case ZSTDds_decodeSkippableHeader: {
1836 memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
1837 dctx->expected = ZSTD_readLE32(dctx->headerBuffer + 4);
1838 dctx->stage = ZSTDds_skipFrame;
1839 return 0;
1840 }
1841 case ZSTDds_skipFrame: {
1842 dctx->expected = 0;
1843 dctx->stage = ZSTDds_getFrameHeaderSize;
1844 return 0;
1845 }
1846 default:
1847 return ERROR(GENERIC); /* impossible */
1848 }
1849 }
1850
ZSTD_refDictContent(ZSTD_DCtx * dctx,const void * dict,size_t dictSize)1851 static size_t ZSTD_refDictContent(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
1852 {
1853 dctx->dictEnd = dctx->previousDstEnd;
1854 dctx->vBase = (const char *)dict - ((const char *)(dctx->previousDstEnd) - (const char *)(dctx->base));
1855 dctx->base = dict;
1856 dctx->previousDstEnd = (const char *)dict + dictSize;
1857 return 0;
1858 }
1859
1860 /* ZSTD_loadEntropy() :
1861 * dict : must point at beginning of a valid zstd dictionary
1862 * @return : size of entropy tables read */
ZSTD_loadEntropy(ZSTD_entropyTables_t * entropy,const void * const dict,size_t const dictSize)1863 static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t *entropy, const void *const dict, size_t const dictSize)
1864 {
1865 const BYTE *dictPtr = (const BYTE *)dict;
1866 const BYTE *const dictEnd = dictPtr + dictSize;
1867
1868 if (dictSize <= 8)
1869 return ERROR(dictionary_corrupted);
1870 dictPtr += 8; /* skip header = magic + dictID */
1871
1872 {
1873 size_t const hSize = HUF_readDTableX4_wksp(entropy->hufTable, dictPtr, dictEnd - dictPtr, entropy->workspace, sizeof(entropy->workspace));
1874 if (HUF_isError(hSize))
1875 return ERROR(dictionary_corrupted);
1876 dictPtr += hSize;
1877 }
1878
1879 {
1880 short offcodeNCount[MaxOff + 1];
1881 U32 offcodeMaxValue = MaxOff, offcodeLog;
1882 size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd - dictPtr);
1883 if (FSE_isError(offcodeHeaderSize))
1884 return ERROR(dictionary_corrupted);
1885 if (offcodeLog > OffFSELog)
1886 return ERROR(dictionary_corrupted);
1887 CHECK_E(FSE_buildDTable_wksp(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted);
1888 dictPtr += offcodeHeaderSize;
1889 }
1890
1891 {
1892 short matchlengthNCount[MaxML + 1];
1893 unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1894 size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd - dictPtr);
1895 if (FSE_isError(matchlengthHeaderSize))
1896 return ERROR(dictionary_corrupted);
1897 if (matchlengthLog > MLFSELog)
1898 return ERROR(dictionary_corrupted);
1899 CHECK_E(FSE_buildDTable_wksp(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted);
1900 dictPtr += matchlengthHeaderSize;
1901 }
1902
1903 {
1904 short litlengthNCount[MaxLL + 1];
1905 unsigned litlengthMaxValue = MaxLL, litlengthLog;
1906 size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd - dictPtr);
1907 if (FSE_isError(litlengthHeaderSize))
1908 return ERROR(dictionary_corrupted);
1909 if (litlengthLog > LLFSELog)
1910 return ERROR(dictionary_corrupted);
1911 CHECK_E(FSE_buildDTable_wksp(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog, entropy->workspace, sizeof(entropy->workspace)), dictionary_corrupted);
1912 dictPtr += litlengthHeaderSize;
1913 }
1914
1915 if (dictPtr + 12 > dictEnd)
1916 return ERROR(dictionary_corrupted);
1917 {
1918 int i;
1919 size_t const dictContentSize = (size_t)(dictEnd - (dictPtr + 12));
1920 for (i = 0; i < 3; i++) {
1921 U32 const rep = ZSTD_readLE32(dictPtr);
1922 dictPtr += 4;
1923 if (rep == 0 || rep >= dictContentSize)
1924 return ERROR(dictionary_corrupted);
1925 entropy->rep[i] = rep;
1926 }
1927 }
1928
1929 return dictPtr - (const BYTE *)dict;
1930 }
1931
ZSTD_decompress_insertDictionary(ZSTD_DCtx * dctx,const void * dict,size_t dictSize)1932 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
1933 {
1934 if (dictSize < 8)
1935 return ZSTD_refDictContent(dctx, dict, dictSize);
1936 {
1937 U32 const magic = ZSTD_readLE32(dict);
1938 if (magic != ZSTD_DICT_MAGIC) {
1939 return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
1940 }
1941 }
1942 dctx->dictID = ZSTD_readLE32((const char *)dict + 4);
1943
1944 /* load entropy tables */
1945 {
1946 size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
1947 if (ZSTD_isError(eSize))
1948 return ERROR(dictionary_corrupted);
1949 dict = (const char *)dict + eSize;
1950 dictSize -= eSize;
1951 }
1952 dctx->litEntropy = dctx->fseEntropy = 1;
1953
1954 /* reference dictionary content */
1955 return ZSTD_refDictContent(dctx, dict, dictSize);
1956 }
1957
ZSTD_decompressBegin_usingDict(ZSTD_DCtx * dctx,const void * dict,size_t dictSize)1958 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx *dctx, const void *dict, size_t dictSize)
1959 {
1960 CHECK_F(ZSTD_decompressBegin(dctx));
1961 if (dict && dictSize)
1962 CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
1963 return 0;
1964 }
1965
1966 /* ====== ZSTD_DDict ====== */
1967
1968 struct ZSTD_DDict_s {
1969 void *dictBuffer;
1970 const void *dictContent;
1971 size_t dictSize;
1972 ZSTD_entropyTables_t entropy;
1973 U32 dictID;
1974 U32 entropyPresent;
1975 ZSTD_customMem cMem;
1976 }; /* typedef'd to ZSTD_DDict within "zstd.h" */
1977
ZSTD_DDictWorkspaceBound(void)1978 size_t ZSTD_DDictWorkspaceBound(void) { return ZSTD_ALIGN(sizeof(ZSTD_stack)) + ZSTD_ALIGN(sizeof(ZSTD_DDict)); }
1979
ZSTD_DDictDictContent(const ZSTD_DDict * ddict)1980 static const void *ZSTD_DDictDictContent(const ZSTD_DDict *ddict) { return ddict->dictContent; }
1981
ZSTD_DDictDictSize(const ZSTD_DDict * ddict)1982 static size_t ZSTD_DDictDictSize(const ZSTD_DDict *ddict) { return ddict->dictSize; }
1983
ZSTD_refDDict(ZSTD_DCtx * dstDCtx,const ZSTD_DDict * ddict)1984 static void ZSTD_refDDict(ZSTD_DCtx *dstDCtx, const ZSTD_DDict *ddict)
1985 {
1986 ZSTD_decompressBegin(dstDCtx); /* init */
1987 if (ddict) { /* support refDDict on NULL */
1988 dstDCtx->dictID = ddict->dictID;
1989 dstDCtx->base = ddict->dictContent;
1990 dstDCtx->vBase = ddict->dictContent;
1991 dstDCtx->dictEnd = (const BYTE *)ddict->dictContent + ddict->dictSize;
1992 dstDCtx->previousDstEnd = dstDCtx->dictEnd;
1993 if (ddict->entropyPresent) {
1994 dstDCtx->litEntropy = 1;
1995 dstDCtx->fseEntropy = 1;
1996 dstDCtx->LLTptr = ddict->entropy.LLTable;
1997 dstDCtx->MLTptr = ddict->entropy.MLTable;
1998 dstDCtx->OFTptr = ddict->entropy.OFTable;
1999 dstDCtx->HUFptr = ddict->entropy.hufTable;
2000 dstDCtx->entropy.rep[0] = ddict->entropy.rep[0];
2001 dstDCtx->entropy.rep[1] = ddict->entropy.rep[1];
2002 dstDCtx->entropy.rep[2] = ddict->entropy.rep[2];
2003 } else {
2004 dstDCtx->litEntropy = 0;
2005 dstDCtx->fseEntropy = 0;
2006 }
2007 }
2008 }
2009
ZSTD_loadEntropy_inDDict(ZSTD_DDict * ddict)2010 static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict *ddict)
2011 {
2012 ddict->dictID = 0;
2013 ddict->entropyPresent = 0;
2014 if (ddict->dictSize < 8)
2015 return 0;
2016 {
2017 U32 const magic = ZSTD_readLE32(ddict->dictContent);
2018 if (magic != ZSTD_DICT_MAGIC)
2019 return 0; /* pure content mode */
2020 }
2021 ddict->dictID = ZSTD_readLE32((const char *)ddict->dictContent + 4);
2022
2023 /* load entropy tables */
2024 CHECK_E(ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted);
2025 ddict->entropyPresent = 1;
2026 return 0;
2027 }
2028
ZSTD_createDDict_advanced(const void * dict,size_t dictSize,unsigned byReference,ZSTD_customMem customMem)2029 static ZSTD_DDict *ZSTD_createDDict_advanced(const void *dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
2030 {
2031 if (!customMem.customAlloc || !customMem.customFree)
2032 return NULL;
2033
2034 {
2035 ZSTD_DDict *const ddict = (ZSTD_DDict *)ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
2036 if (!ddict)
2037 return NULL;
2038 ddict->cMem = customMem;
2039
2040 if ((byReference) || (!dict) || (!dictSize)) {
2041 ddict->dictBuffer = NULL;
2042 ddict->dictContent = dict;
2043 } else {
2044 void *const internalBuffer = ZSTD_malloc(dictSize, customMem);
2045 if (!internalBuffer) {
2046 ZSTD_freeDDict(ddict);
2047 return NULL;
2048 }
2049 memcpy(internalBuffer, dict, dictSize);
2050 ddict->dictBuffer = internalBuffer;
2051 ddict->dictContent = internalBuffer;
2052 }
2053 ddict->dictSize = dictSize;
2054 ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
2055 /* parse dictionary content */
2056 {
2057 size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
2058 if (ZSTD_isError(errorCode)) {
2059 ZSTD_freeDDict(ddict);
2060 return NULL;
2061 }
2062 }
2063
2064 return ddict;
2065 }
2066 }
2067
2068 /*! ZSTD_initDDict() :
2069 * Create a digested dictionary, to start decompression without startup delay.
2070 * `dict` content is copied inside DDict.
2071 * Consequently, `dict` can be released after `ZSTD_DDict` creation */
ZSTD_initDDict(const void * dict,size_t dictSize,void * workspace,size_t workspaceSize)2072 ZSTD_DDict *ZSTD_initDDict(const void *dict, size_t dictSize, void *workspace, size_t workspaceSize)
2073 {
2074 ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
2075 return ZSTD_createDDict_advanced(dict, dictSize, 1, stackMem);
2076 }
2077
ZSTD_freeDDict(ZSTD_DDict * ddict)2078 size_t ZSTD_freeDDict(ZSTD_DDict *ddict)
2079 {
2080 if (ddict == NULL)
2081 return 0; /* support free on NULL */
2082 {
2083 ZSTD_customMem const cMem = ddict->cMem;
2084 ZSTD_free(ddict->dictBuffer, cMem);
2085 ZSTD_free(ddict, cMem);
2086 return 0;
2087 }
2088 }
2089
2090 /*! ZSTD_getDictID_fromDict() :
2091 * Provides the dictID stored within dictionary.
2092 * if @return == 0, the dictionary is not conformant with Zstandard specification.
2093 * It can still be loaded, but as a content-only dictionary. */
ZSTD_getDictID_fromDict(const void * dict,size_t dictSize)2094 unsigned ZSTD_getDictID_fromDict(const void *dict, size_t dictSize)
2095 {
2096 if (dictSize < 8)
2097 return 0;
2098 if (ZSTD_readLE32(dict) != ZSTD_DICT_MAGIC)
2099 return 0;
2100 return ZSTD_readLE32((const char *)dict + 4);
2101 }
2102
2103 /*! ZSTD_getDictID_fromDDict() :
2104 * Provides the dictID of the dictionary loaded into `ddict`.
2105 * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
2106 * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
ZSTD_getDictID_fromDDict(const ZSTD_DDict * ddict)2107 unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict *ddict)
2108 {
2109 if (ddict == NULL)
2110 return 0;
2111 return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
2112 }
2113
2114 /*! ZSTD_getDictID_fromFrame() :
2115 * Provides the dictID required to decompressed the frame stored within `src`.
2116 * If @return == 0, the dictID could not be decoded.
2117 * This could for one of the following reasons :
2118 * - The frame does not require a dictionary to be decoded (most common case).
2119 * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
2120 * Note : this use case also happens when using a non-conformant dictionary.
2121 * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
2122 * - This is not a Zstandard frame.
2123 * When identifying the exact failure cause, it's possible to used ZSTD_getFrameParams(), which will provide a more precise error code. */
ZSTD_getDictID_fromFrame(const void * src,size_t srcSize)2124 unsigned ZSTD_getDictID_fromFrame(const void *src, size_t srcSize)
2125 {
2126 ZSTD_frameParams zfp = {0, 0, 0, 0};
2127 size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
2128 if (ZSTD_isError(hError))
2129 return 0;
2130 return zfp.dictID;
2131 }
2132
2133 /*! ZSTD_decompress_usingDDict() :
2134 * Decompression using a pre-digested Dictionary
2135 * Use dictionary without significant overhead. */
ZSTD_decompress_usingDDict(ZSTD_DCtx * dctx,void * dst,size_t dstCapacity,const void * src,size_t srcSize,const ZSTD_DDict * ddict)2136 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx *dctx, void *dst, size_t dstCapacity, const void *src, size_t srcSize, const ZSTD_DDict *ddict)
2137 {
2138 /* pass content and size in case legacy frames are encountered */
2139 return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, NULL, 0, ddict);
2140 }
2141
2142 /*=====================================
2143 * Streaming decompression
2144 *====================================*/
2145
2146 typedef enum { zdss_init, zdss_loadHeader, zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
2147
2148 /* *** Resource management *** */
2149 struct ZSTD_DStream_s {
2150 ZSTD_DCtx *dctx;
2151 ZSTD_DDict *ddictLocal;
2152 const ZSTD_DDict *ddict;
2153 ZSTD_frameParams fParams;
2154 ZSTD_dStreamStage stage;
2155 char *inBuff;
2156 size_t inBuffSize;
2157 size_t inPos;
2158 size_t maxWindowSize;
2159 char *outBuff;
2160 size_t outBuffSize;
2161 size_t outStart;
2162 size_t outEnd;
2163 size_t blockSize;
2164 BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
2165 size_t lhSize;
2166 ZSTD_customMem customMem;
2167 void *legacyContext;
2168 U32 previousLegacyVersion;
2169 U32 legacyVersion;
2170 U32 hostageByte;
2171 }; /* typedef'd to ZSTD_DStream within "zstd.h" */
2172
ZSTD_DStreamWorkspaceBound(size_t maxWindowSize)2173 size_t ZSTD_DStreamWorkspaceBound(size_t maxWindowSize)
2174 {
2175 size_t const blockSize = MIN(maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
2176 size_t const inBuffSize = blockSize;
2177 size_t const outBuffSize = maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
2178 return ZSTD_DCtxWorkspaceBound() + ZSTD_ALIGN(sizeof(ZSTD_DStream)) + ZSTD_ALIGN(inBuffSize) + ZSTD_ALIGN(outBuffSize);
2179 }
2180
ZSTD_createDStream_advanced(ZSTD_customMem customMem)2181 static ZSTD_DStream *ZSTD_createDStream_advanced(ZSTD_customMem customMem)
2182 {
2183 ZSTD_DStream *zds;
2184
2185 if (!customMem.customAlloc || !customMem.customFree)
2186 return NULL;
2187
2188 zds = (ZSTD_DStream *)ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
2189 if (zds == NULL)
2190 return NULL;
2191 memset(zds, 0, sizeof(ZSTD_DStream));
2192 memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
2193 zds->dctx = ZSTD_createDCtx_advanced(customMem);
2194 if (zds->dctx == NULL) {
2195 ZSTD_freeDStream(zds);
2196 return NULL;
2197 }
2198 zds->stage = zdss_init;
2199 zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
2200 return zds;
2201 }
2202
ZSTD_initDStream(size_t maxWindowSize,void * workspace,size_t workspaceSize)2203 ZSTD_DStream *ZSTD_initDStream(size_t maxWindowSize, void *workspace, size_t workspaceSize)
2204 {
2205 ZSTD_customMem const stackMem = ZSTD_initStack(workspace, workspaceSize);
2206 ZSTD_DStream *zds = ZSTD_createDStream_advanced(stackMem);
2207 if (!zds) {
2208 return NULL;
2209 }
2210
2211 zds->maxWindowSize = maxWindowSize;
2212 zds->stage = zdss_loadHeader;
2213 zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
2214 ZSTD_freeDDict(zds->ddictLocal);
2215 zds->ddictLocal = NULL;
2216 zds->ddict = zds->ddictLocal;
2217 zds->legacyVersion = 0;
2218 zds->hostageByte = 0;
2219
2220 {
2221 size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
2222 size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
2223
2224 zds->inBuff = (char *)ZSTD_malloc(blockSize, zds->customMem);
2225 zds->inBuffSize = blockSize;
2226 zds->outBuff = (char *)ZSTD_malloc(neededOutSize, zds->customMem);
2227 zds->outBuffSize = neededOutSize;
2228 if (zds->inBuff == NULL || zds->outBuff == NULL) {
2229 ZSTD_freeDStream(zds);
2230 return NULL;
2231 }
2232 }
2233 return zds;
2234 }
2235
ZSTD_initDStream_usingDDict(size_t maxWindowSize,const ZSTD_DDict * ddict,void * workspace,size_t workspaceSize)2236 ZSTD_DStream *ZSTD_initDStream_usingDDict(size_t maxWindowSize, const ZSTD_DDict *ddict, void *workspace, size_t workspaceSize)
2237 {
2238 ZSTD_DStream *zds = ZSTD_initDStream(maxWindowSize, workspace, workspaceSize);
2239 if (zds) {
2240 zds->ddict = ddict;
2241 }
2242 return zds;
2243 }
2244
ZSTD_freeDStream(ZSTD_DStream * zds)2245 size_t ZSTD_freeDStream(ZSTD_DStream *zds)
2246 {
2247 if (zds == NULL)
2248 return 0; /* support free on null */
2249 {
2250 ZSTD_customMem const cMem = zds->customMem;
2251 ZSTD_freeDCtx(zds->dctx);
2252 zds->dctx = NULL;
2253 ZSTD_freeDDict(zds->ddictLocal);
2254 zds->ddictLocal = NULL;
2255 ZSTD_free(zds->inBuff, cMem);
2256 zds->inBuff = NULL;
2257 ZSTD_free(zds->outBuff, cMem);
2258 zds->outBuff = NULL;
2259 ZSTD_free(zds, cMem);
2260 return 0;
2261 }
2262 }
2263
2264 /* *** Initialization *** */
2265
ZSTD_DStreamInSize(void)2266 size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
ZSTD_DStreamOutSize(void)2267 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
2268
ZSTD_resetDStream(ZSTD_DStream * zds)2269 size_t ZSTD_resetDStream(ZSTD_DStream *zds)
2270 {
2271 zds->stage = zdss_loadHeader;
2272 zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
2273 zds->legacyVersion = 0;
2274 zds->hostageByte = 0;
2275 return ZSTD_frameHeaderSize_prefix;
2276 }
2277
2278 /* ***** Decompression ***** */
2279
ZSTD_limitCopy(void * dst,size_t dstCapacity,const void * src,size_t srcSize)2280 ZSTD_STATIC size_t ZSTD_limitCopy(void *dst, size_t dstCapacity, const void *src, size_t srcSize)
2281 {
2282 size_t const length = MIN(dstCapacity, srcSize);
2283 memcpy(dst, src, length);
2284 return length;
2285 }
2286
ZSTD_decompressStream(ZSTD_DStream * zds,ZSTD_outBuffer * output,ZSTD_inBuffer * input)2287 size_t ZSTD_decompressStream(ZSTD_DStream *zds, ZSTD_outBuffer *output, ZSTD_inBuffer *input)
2288 {
2289 const char *const istart = (const char *)(input->src) + input->pos;
2290 const char *const iend = (const char *)(input->src) + input->size;
2291 const char *ip = istart;
2292 char *const ostart = (char *)(output->dst) + output->pos;
2293 char *const oend = (char *)(output->dst) + output->size;
2294 char *op = ostart;
2295 U32 someMoreWork = 1;
2296
2297 while (someMoreWork) {
2298 switch (zds->stage) {
2299 case zdss_init:
2300 ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
2301 /* fall-through */
2302
2303 case zdss_loadHeader: {
2304 size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
2305 if (ZSTD_isError(hSize))
2306 return hSize;
2307 if (hSize != 0) { /* need more input */
2308 size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
2309 if (toLoad > (size_t)(iend - ip)) { /* not enough input to load full header */
2310 memcpy(zds->headerBuffer + zds->lhSize, ip, iend - ip);
2311 zds->lhSize += iend - ip;
2312 input->pos = input->size;
2313 return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) +
2314 ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
2315 }
2316 memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad);
2317 zds->lhSize = hSize;
2318 ip += toLoad;
2319 break;
2320 }
2321
2322 /* check for single-pass mode opportunity */
2323 if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
2324 && (U64)(size_t)(oend - op) >= zds->fParams.frameContentSize) {
2325 size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend - istart);
2326 if (cSize <= (size_t)(iend - istart)) {
2327 size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend - op, istart, cSize, zds->ddict);
2328 if (ZSTD_isError(decompressedSize))
2329 return decompressedSize;
2330 ip = istart + cSize;
2331 op += decompressedSize;
2332 zds->dctx->expected = 0;
2333 zds->stage = zdss_init;
2334 someMoreWork = 0;
2335 break;
2336 }
2337 }
2338
2339 /* Consume header */
2340 ZSTD_refDDict(zds->dctx, zds->ddict);
2341 {
2342 size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
2343 CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
2344 {
2345 size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2346 CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer + h1Size, h2Size));
2347 }
2348 }
2349
2350 zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2351 if (zds->fParams.windowSize > zds->maxWindowSize)
2352 return ERROR(frameParameter_windowTooLarge);
2353
2354 /* Buffers are preallocated, but double check */
2355 {
2356 size_t const blockSize = MIN(zds->maxWindowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
2357 size_t const neededOutSize = zds->maxWindowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
2358 if (zds->inBuffSize < blockSize) {
2359 return ERROR(GENERIC);
2360 }
2361 if (zds->outBuffSize < neededOutSize) {
2362 return ERROR(GENERIC);
2363 }
2364 zds->blockSize = blockSize;
2365 }
2366 zds->stage = zdss_read;
2367 }
2368 /* pass-through */
2369
2370 case zdss_read: {
2371 size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2372 if (neededInSize == 0) { /* end of frame */
2373 zds->stage = zdss_init;
2374 someMoreWork = 0;
2375 break;
2376 }
2377 if ((size_t)(iend - ip) >= neededInSize) { /* decode directly from src */
2378 const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
2379 size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart,
2380 (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart), ip, neededInSize);
2381 if (ZSTD_isError(decodedSize))
2382 return decodedSize;
2383 ip += neededInSize;
2384 if (!decodedSize && !isSkipFrame)
2385 break; /* this was just a header */
2386 zds->outEnd = zds->outStart + decodedSize;
2387 zds->stage = zdss_flush;
2388 break;
2389 }
2390 if (ip == iend) {
2391 someMoreWork = 0;
2392 break;
2393 } /* no more input */
2394 zds->stage = zdss_load;
2395 /* pass-through */
2396 }
2397
2398 case zdss_load: {
2399 size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2400 size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
2401 size_t loadedSize;
2402 if (toLoad > zds->inBuffSize - zds->inPos)
2403 return ERROR(corruption_detected); /* should never happen */
2404 loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend - ip);
2405 ip += loadedSize;
2406 zds->inPos += loadedSize;
2407 if (loadedSize < toLoad) {
2408 someMoreWork = 0;
2409 break;
2410 } /* not enough input, wait for more */
2411
2412 /* decode loaded input */
2413 {
2414 const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
2415 size_t const decodedSize = ZSTD_decompressContinue(zds->dctx, zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
2416 zds->inBuff, neededInSize);
2417 if (ZSTD_isError(decodedSize))
2418 return decodedSize;
2419 zds->inPos = 0; /* input is consumed */
2420 if (!decodedSize && !isSkipFrame) {
2421 zds->stage = zdss_read;
2422 break;
2423 } /* this was just a header */
2424 zds->outEnd = zds->outStart + decodedSize;
2425 zds->stage = zdss_flush;
2426 /* pass-through */
2427 }
2428 }
2429
2430 case zdss_flush: {
2431 size_t const toFlushSize = zds->outEnd - zds->outStart;
2432 size_t const flushedSize = ZSTD_limitCopy(op, oend - op, zds->outBuff + zds->outStart, toFlushSize);
2433 op += flushedSize;
2434 zds->outStart += flushedSize;
2435 if (flushedSize == toFlushSize) { /* flush completed */
2436 zds->stage = zdss_read;
2437 if (zds->outStart + zds->blockSize > zds->outBuffSize)
2438 zds->outStart = zds->outEnd = 0;
2439 break;
2440 }
2441 /* cannot complete flush */
2442 someMoreWork = 0;
2443 break;
2444 }
2445 default:
2446 return ERROR(GENERIC); /* impossible */
2447 }
2448 }
2449
2450 /* result */
2451 input->pos += (size_t)(ip - istart);
2452 output->pos += (size_t)(op - ostart);
2453 {
2454 size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
2455 if (!nextSrcSizeHint) { /* frame fully decoded */
2456 if (zds->outEnd == zds->outStart) { /* output fully flushed */
2457 if (zds->hostageByte) {
2458 if (input->pos >= input->size) {
2459 zds->stage = zdss_read;
2460 return 1;
2461 } /* can't release hostage (not present) */
2462 input->pos++; /* release hostage */
2463 }
2464 return 0;
2465 }
2466 if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
2467 input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
2468 zds->hostageByte = 1;
2469 }
2470 return 1;
2471 }
2472 nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
2473 if (zds->inPos > nextSrcSizeHint)
2474 return ERROR(GENERIC); /* should never happen */
2475 nextSrcSizeHint -= zds->inPos; /* already loaded*/
2476 return nextSrcSizeHint;
2477 }
2478 }
2479
2480 EXPORT_SYMBOL(ZSTD_DCtxWorkspaceBound);
2481 EXPORT_SYMBOL(ZSTD_initDCtx);
2482 EXPORT_SYMBOL(ZSTD_decompressDCtx);
2483 EXPORT_SYMBOL(ZSTD_decompress_usingDict);
2484
2485 EXPORT_SYMBOL(ZSTD_DDictWorkspaceBound);
2486 EXPORT_SYMBOL(ZSTD_initDDict);
2487 EXPORT_SYMBOL(ZSTD_decompress_usingDDict);
2488
2489 EXPORT_SYMBOL(ZSTD_DStreamWorkspaceBound);
2490 EXPORT_SYMBOL(ZSTD_initDStream);
2491 EXPORT_SYMBOL(ZSTD_initDStream_usingDDict);
2492 EXPORT_SYMBOL(ZSTD_resetDStream);
2493 EXPORT_SYMBOL(ZSTD_decompressStream);
2494 EXPORT_SYMBOL(ZSTD_DStreamInSize);
2495 EXPORT_SYMBOL(ZSTD_DStreamOutSize);
2496
2497 EXPORT_SYMBOL(ZSTD_findFrameCompressedSize);
2498 EXPORT_SYMBOL(ZSTD_getFrameContentSize);
2499 EXPORT_SYMBOL(ZSTD_findDecompressedSize);
2500
2501 EXPORT_SYMBOL(ZSTD_isFrame);
2502 EXPORT_SYMBOL(ZSTD_getDictID_fromDict);
2503 EXPORT_SYMBOL(ZSTD_getDictID_fromDDict);
2504 EXPORT_SYMBOL(ZSTD_getDictID_fromFrame);
2505
2506 EXPORT_SYMBOL(ZSTD_getFrameParams);
2507 EXPORT_SYMBOL(ZSTD_decompressBegin);
2508 EXPORT_SYMBOL(ZSTD_decompressBegin_usingDict);
2509 EXPORT_SYMBOL(ZSTD_copyDCtx);
2510 EXPORT_SYMBOL(ZSTD_nextSrcSizeToDecompress);
2511 EXPORT_SYMBOL(ZSTD_decompressContinue);
2512 EXPORT_SYMBOL(ZSTD_nextInputType);
2513
2514 EXPORT_SYMBOL(ZSTD_decompressBlock);
2515 EXPORT_SYMBOL(ZSTD_insertBlock);
2516