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