git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.6 / lib / decompress / zstd_decompress.c
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  * You may select, at your option, one of the above-listed licenses.
9  */
10
11
12 /* ***************************************************************
13 *  Tuning parameters
14 *****************************************************************/
15 /*!
16  * HEAPMODE :
17  * Select how default decompression function ZSTD_decompress() allocates its context,
18  * on stack (0), or into heap (1, default; requires malloc()).
19  * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected.
20  */
21 #ifndef ZSTD_HEAPMODE
22 #  define ZSTD_HEAPMODE 1
23 #endif
24
25 /*!
26 *  LEGACY_SUPPORT :
27 *  if set to 1+, ZSTD_decompress() can decode older formats (v0.1+)
28 */
29 #ifndef ZSTD_LEGACY_SUPPORT
30 #  define ZSTD_LEGACY_SUPPORT 0
31 #endif
32
33 /*!
34  *  MAXWINDOWSIZE_DEFAULT :
35  *  maximum window size accepted by DStream __by default__.
36  *  Frames requiring more memory will be rejected.
37  *  It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize().
38  */
39 #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
40 #  define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
41 #endif
42
43 /*!
44  *  NO_FORWARD_PROGRESS_MAX :
45  *  maximum allowed nb of calls to ZSTD_decompressStream()
46  *  without any forward progress
47  *  (defined as: no byte read from input, and no byte flushed to output)
48  *  before triggering an error.
49  */
50 #ifndef ZSTD_NO_FORWARD_PROGRESS_MAX
51 #  define ZSTD_NO_FORWARD_PROGRESS_MAX 16
52 #endif
53
54
55 /*-*******************************************************
56 *  Dependencies
57 *********************************************************/
58 #include "../common/zstd_deps.h"   /* ZSTD_memcpy, ZSTD_memmove, ZSTD_memset */
59 #include "../common/allocations.h"  /* ZSTD_customMalloc, ZSTD_customCalloc, ZSTD_customFree */
60 #include "../common/error_private.h"
61 #include "../common/zstd_internal.h"  /* blockProperties_t */
62 #include "../common/mem.h"         /* low level memory routines */
63 #include "../common/bits.h"  /* ZSTD_highbit32 */
64 #define FSE_STATIC_LINKING_ONLY
65 #include "../common/fse.h"
66 #include "../common/huf.h"
67 #include "../common/xxhash.h" /* XXH64_reset, XXH64_update, XXH64_digest, XXH64 */
68 #include "zstd_decompress_internal.h"   /* ZSTD_DCtx */
69 #include "zstd_ddict.h"  /* ZSTD_DDictDictContent */
70 #include "zstd_decompress_block.h"   /* ZSTD_decompressBlock_internal */
71
72 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
73 #  include "../legacy/zstd_legacy.h"
74 #endif
75
76
77
78 /*************************************
79  * Multiple DDicts Hashset internals *
80  *************************************/
81
82 #define DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT 4
83 #define DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT 3  /* These two constants represent SIZE_MULT/COUNT_MULT load factor without using a float.
84                                                     * Currently, that means a 0.75 load factor.
85                                                     * So, if count * COUNT_MULT / size * SIZE_MULT != 0, then we've exceeded
86                                                     * the load factor of the ddict hash set.
87                                                     */
88
89 #define DDICT_HASHSET_TABLE_BASE_SIZE 64
90 #define DDICT_HASHSET_RESIZE_FACTOR 2
91
92 /* Hash function to determine starting position of dict insertion within the table
93  * Returns an index between [0, hashSet->ddictPtrTableSize]
94  */
95 static size_t ZSTD_DDictHashSet_getIndex(const ZSTD_DDictHashSet* hashSet, U32 dictID) {
96     const U64 hash = XXH64(&dictID, sizeof(U32), 0);
97     /* DDict ptr table size is a multiple of 2, use size - 1 as mask to get index within [0, hashSet->ddictPtrTableSize) */
98     return hash & (hashSet->ddictPtrTableSize - 1);
99 }
100
101 /* Adds DDict to a hashset without resizing it.
102  * If inserting a DDict with a dictID that already exists in the set, replaces the one in the set.
103  * Returns 0 if successful, or a zstd error code if something went wrong.
104  */
105 static size_t ZSTD_DDictHashSet_emplaceDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict) {
106     const U32 dictID = ZSTD_getDictID_fromDDict(ddict);
107     size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
108     const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
109     RETURN_ERROR_IF(hashSet->ddictPtrCount == hashSet->ddictPtrTableSize, GENERIC, "Hash set is full!");
110     DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
111     while (hashSet->ddictPtrTable[idx] != NULL) {
112         /* Replace existing ddict if inserting ddict with same dictID */
113         if (ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]) == dictID) {
114             DEBUGLOG(4, "DictID already exists, replacing rather than adding");
115             hashSet->ddictPtrTable[idx] = ddict;
116             return 0;
117         }
118         idx &= idxRangeMask;
119         idx++;
120     }
121     DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
122     hashSet->ddictPtrTable[idx] = ddict;
123     hashSet->ddictPtrCount++;
124     return 0;
125 }
126
127 /* Expands hash table by factor of DDICT_HASHSET_RESIZE_FACTOR and
128  * rehashes all values, allocates new table, frees old table.
129  * Returns 0 on success, otherwise a zstd error code.
130  */
131 static size_t ZSTD_DDictHashSet_expand(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
132     size_t newTableSize = hashSet->ddictPtrTableSize * DDICT_HASHSET_RESIZE_FACTOR;
133     const ZSTD_DDict** newTable = (const ZSTD_DDict**)ZSTD_customCalloc(sizeof(ZSTD_DDict*) * newTableSize, customMem);
134     const ZSTD_DDict** oldTable = hashSet->ddictPtrTable;
135     size_t oldTableSize = hashSet->ddictPtrTableSize;
136     size_t i;
137
138     DEBUGLOG(4, "Expanding DDict hash table! Old size: %zu new size: %zu", oldTableSize, newTableSize);
139     RETURN_ERROR_IF(!newTable, memory_allocation, "Expanded hashset allocation failed!");
140     hashSet->ddictPtrTable = newTable;
141     hashSet->ddictPtrTableSize = newTableSize;
142     hashSet->ddictPtrCount = 0;
143     for (i = 0; i < oldTableSize; ++i) {
144         if (oldTable[i] != NULL) {
145             FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, oldTable[i]), "");
146         }
147     }
148     ZSTD_customFree((void*)oldTable, customMem);
149     DEBUGLOG(4, "Finished re-hash");
150     return 0;
151 }
152
153 /* Fetches a DDict with the given dictID
154  * Returns the ZSTD_DDict* with the requested dictID. If it doesn't exist, then returns NULL.
155  */
156 static const ZSTD_DDict* ZSTD_DDictHashSet_getDDict(ZSTD_DDictHashSet* hashSet, U32 dictID) {
157     size_t idx = ZSTD_DDictHashSet_getIndex(hashSet, dictID);
158     const size_t idxRangeMask = hashSet->ddictPtrTableSize - 1;
159     DEBUGLOG(4, "Hashed index: for dictID: %u is %zu", dictID, idx);
160     for (;;) {
161         size_t currDictID = ZSTD_getDictID_fromDDict(hashSet->ddictPtrTable[idx]);
162         if (currDictID == dictID || currDictID == 0) {
163             /* currDictID == 0 implies a NULL ddict entry */
164             break;
165         } else {
166             idx &= idxRangeMask;    /* Goes to start of table when we reach the end */
167             idx++;
168         }
169     }
170     DEBUGLOG(4, "Final idx after probing for dictID %u is: %zu", dictID, idx);
171     return hashSet->ddictPtrTable[idx];
172 }
173
174 /* Allocates space for and returns a ddict hash set
175  * The hash set's ZSTD_DDict* table has all values automatically set to NULL to begin with.
176  * Returns NULL if allocation failed.
177  */
178 static ZSTD_DDictHashSet* ZSTD_createDDictHashSet(ZSTD_customMem customMem) {
179     ZSTD_DDictHashSet* ret = (ZSTD_DDictHashSet*)ZSTD_customMalloc(sizeof(ZSTD_DDictHashSet), customMem);
180     DEBUGLOG(4, "Allocating new hash set");
181     if (!ret)
182         return NULL;
183     ret->ddictPtrTable = (const ZSTD_DDict**)ZSTD_customCalloc(DDICT_HASHSET_TABLE_BASE_SIZE * sizeof(ZSTD_DDict*), customMem);
184     if (!ret->ddictPtrTable) {
185         ZSTD_customFree(ret, customMem);
186         return NULL;
187     }
188     ret->ddictPtrTableSize = DDICT_HASHSET_TABLE_BASE_SIZE;
189     ret->ddictPtrCount = 0;
190     return ret;
191 }
192
193 /* Frees the table of ZSTD_DDict* within a hashset, then frees the hashset itself.
194  * Note: The ZSTD_DDict* within the table are NOT freed.
195  */
196 static void ZSTD_freeDDictHashSet(ZSTD_DDictHashSet* hashSet, ZSTD_customMem customMem) {
197     DEBUGLOG(4, "Freeing ddict hash set");
198     if (hashSet && hashSet->ddictPtrTable) {
199         ZSTD_customFree((void*)hashSet->ddictPtrTable, customMem);
200     }
201     if (hashSet) {
202         ZSTD_customFree(hashSet, customMem);
203     }
204 }
205
206 /* Public function: Adds a DDict into the ZSTD_DDictHashSet, possibly triggering a resize of the hash set.
207  * Returns 0 on success, or a ZSTD error.
208  */
209 static size_t ZSTD_DDictHashSet_addDDict(ZSTD_DDictHashSet* hashSet, const ZSTD_DDict* ddict, ZSTD_customMem customMem) {
210     DEBUGLOG(4, "Adding dict ID: %u to hashset with - Count: %zu Tablesize: %zu", ZSTD_getDictID_fromDDict(ddict), hashSet->ddictPtrCount, hashSet->ddictPtrTableSize);
211     if (hashSet->ddictPtrCount * DDICT_HASHSET_MAX_LOAD_FACTOR_COUNT_MULT / hashSet->ddictPtrTableSize * DDICT_HASHSET_MAX_LOAD_FACTOR_SIZE_MULT != 0) {
212         FORWARD_IF_ERROR(ZSTD_DDictHashSet_expand(hashSet, customMem), "");
213     }
214     FORWARD_IF_ERROR(ZSTD_DDictHashSet_emplaceDDict(hashSet, ddict), "");
215     return 0;
216 }
217
218 /*-*************************************************************
219 *   Context management
220 ***************************************************************/
221 size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
222 {
223     if (dctx==NULL) return 0;   /* support sizeof NULL */
224     return sizeof(*dctx)
225            + ZSTD_sizeof_DDict(dctx->ddictLocal)
226            + dctx->inBuffSize + dctx->outBuffSize;
227 }
228
229 size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
230
231
232 static size_t ZSTD_startingInputLength(ZSTD_format_e format)
233 {
234     size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format);
235     /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
236     assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
237     return startingInputLength;
238 }
239
240 static void ZSTD_DCtx_resetParameters(ZSTD_DCtx* dctx)
241 {
242     assert(dctx->streamStage == zdss_init);
243     dctx->format = ZSTD_f_zstd1;
244     dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
245     dctx->outBufferMode = ZSTD_bm_buffered;
246     dctx->forceIgnoreChecksum = ZSTD_d_validateChecksum;
247     dctx->refMultipleDDicts = ZSTD_rmd_refSingleDDict;
248     dctx->disableHufAsm = 0;
249     dctx->maxBlockSizeParam = 0;
250 }
251
252 static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
253 {
254     dctx->staticSize  = 0;
255     dctx->ddict       = NULL;
256     dctx->ddictLocal  = NULL;
257     dctx->dictEnd     = NULL;
258     dctx->ddictIsCold = 0;
259     dctx->dictUses = ZSTD_dont_use;
260     dctx->inBuff      = NULL;
261     dctx->inBuffSize  = 0;
262     dctx->outBuffSize = 0;
263     dctx->streamStage = zdss_init;
264 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
265     dctx->legacyContext = NULL;
266     dctx->previousLegacyVersion = 0;
267 #endif
268     dctx->noForwardProgress = 0;
269     dctx->oversizedDuration = 0;
270     dctx->isFrameDecompression = 1;
271 #if DYNAMIC_BMI2
272     dctx->bmi2 = ZSTD_cpuSupportsBmi2();
273 #endif
274     dctx->ddictSet = NULL;
275     ZSTD_DCtx_resetParameters(dctx);
276 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
277     dctx->dictContentEndForFuzzing = NULL;
278 #endif
279 }
280
281 ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
282 {
283     ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;
284
285     if ((size_t)workspace & 7) return NULL;  /* 8-aligned */
286     if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL;  /* minimum size */
287
288     ZSTD_initDCtx_internal(dctx);
289     dctx->staticSize = workspaceSize;
290     dctx->inBuff = (char*)(dctx+1);
291     return dctx;
292 }
293
294 static ZSTD_DCtx* ZSTD_createDCtx_internal(ZSTD_customMem customMem) {
295     if ((!customMem.customAlloc) ^ (!customMem.customFree)) return NULL;
296
297     {   ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_customMalloc(sizeof(*dctx), customMem);
298         if (!dctx) return NULL;
299         dctx->customMem = customMem;
300         ZSTD_initDCtx_internal(dctx);
301         return dctx;
302     }
303 }
304
305 ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
306 {
307     return ZSTD_createDCtx_internal(customMem);
308 }
309
310 ZSTD_DCtx* ZSTD_createDCtx(void)
311 {
312     DEBUGLOG(3, "ZSTD_createDCtx");
313     return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
314 }
315
316 static void ZSTD_clearDict(ZSTD_DCtx* dctx)
317 {
318     ZSTD_freeDDict(dctx->ddictLocal);
319     dctx->ddictLocal = NULL;
320     dctx->ddict = NULL;
321     dctx->dictUses = ZSTD_dont_use;
322 }
323
324 size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
325 {
326     if (dctx==NULL) return 0;   /* support free on NULL */
327     RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
328     {   ZSTD_customMem const cMem = dctx->customMem;
329         ZSTD_clearDict(dctx);
330         ZSTD_customFree(dctx->inBuff, cMem);
331         dctx->inBuff = NULL;
332 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
333         if (dctx->legacyContext)
334             ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);
335 #endif
336         if (dctx->ddictSet) {
337             ZSTD_freeDDictHashSet(dctx->ddictSet, cMem);
338             dctx->ddictSet = NULL;
339         }
340         ZSTD_customFree(dctx, cMem);
341         return 0;
342     }
343 }
344
345 /* no longer useful */
346 void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
347 {
348     size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);
349     ZSTD_memcpy(dstDCtx, srcDCtx, toCopy);  /* no need to copy workspace */
350 }
351
352 /* Given a dctx with a digested frame params, re-selects the correct ZSTD_DDict based on
353  * the requested dict ID from the frame. If there exists a reference to the correct ZSTD_DDict, then
354  * accordingly sets the ddict to be used to decompress the frame.
355  *
356  * If no DDict is found, then no action is taken, and the ZSTD_DCtx::ddict remains as-is.
357  *
358  * ZSTD_d_refMultipleDDicts must be enabled for this function to be called.
359  */
360 static void ZSTD_DCtx_selectFrameDDict(ZSTD_DCtx* dctx) {
361     assert(dctx->refMultipleDDicts && dctx->ddictSet);
362     DEBUGLOG(4, "Adjusting DDict based on requested dict ID from frame");
363     if (dctx->ddict) {
364         const ZSTD_DDict* frameDDict = ZSTD_DDictHashSet_getDDict(dctx->ddictSet, dctx->fParams.dictID);
365         if (frameDDict) {
366             DEBUGLOG(4, "DDict found!");
367             ZSTD_clearDict(dctx);
368             dctx->dictID = dctx->fParams.dictID;
369             dctx->ddict = frameDDict;
370             dctx->dictUses = ZSTD_use_indefinitely;
371         }
372     }
373 }
374
375
376 /*-*************************************************************
377  *   Frame header decoding
378  ***************************************************************/
379
380 /*! ZSTD_isFrame() :
381  *  Tells if the content of `buffer` starts with a valid Frame Identifier.
382  *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
383  *  Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
384  *  Note 3 : Skippable Frame Identifiers are considered valid. */
385 unsigned ZSTD_isFrame(const void* buffer, size_t size)
386 {
387     if (size < ZSTD_FRAMEIDSIZE) return 0;
388     {   U32 const magic = MEM_readLE32(buffer);
389         if (magic == ZSTD_MAGICNUMBER) return 1;
390         if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
391     }
392 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
393     if (ZSTD_isLegacy(buffer, size)) return 1;
394 #endif
395     return 0;
396 }
397
398 /*! ZSTD_isSkippableFrame() :
399  *  Tells if the content of `buffer` starts with a valid Frame Identifier for a skippable frame.
400  *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
401  */
402 unsigned ZSTD_isSkippableFrame(const void* buffer, size_t size)
403 {
404     if (size < ZSTD_FRAMEIDSIZE) return 0;
405     {   U32 const magic = MEM_readLE32(buffer);
406         if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
407     }
408     return 0;
409 }
410
411 /** ZSTD_frameHeaderSize_internal() :
412  *  srcSize must be large enough to reach header size fields.
413  *  note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless.
414  * @return : size of the Frame Header
415  *           or an error code, which can be tested with ZSTD_isError() */
416 static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
417 {
418     size_t const minInputSize = ZSTD_startingInputLength(format);
419     RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong, "");
420
421     {   BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
422         U32 const dictID= fhd & 3;
423         U32 const singleSegment = (fhd >> 5) & 1;
424         U32 const fcsId = fhd >> 6;
425         return minInputSize + !singleSegment
426              + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
427              + (singleSegment && !fcsId);
428     }
429 }
430
431 /** ZSTD_frameHeaderSize() :
432  *  srcSize must be >= ZSTD_frameHeaderSize_prefix.
433  * @return : size of the Frame Header,
434  *           or an error code (if srcSize is too small) */
435 size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
436 {
437     return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
438 }
439
440
441 /** ZSTD_getFrameHeader_advanced() :
442  *  decode Frame Header, or require larger `srcSize`.
443  *  note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
444  * @return : 0, `zfhPtr` is correctly filled,
445  *          >0, `srcSize` is too small, value is wanted `srcSize` amount,
446 **           or an error code, which can be tested using ZSTD_isError() */
447 size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
448 {
449     const BYTE* ip = (const BYTE*)src;
450     size_t const minInputSize = ZSTD_startingInputLength(format);
451
452     DEBUGLOG(5, "ZSTD_getFrameHeader_advanced: minInputSize = %zu, srcSize = %zu", minInputSize, srcSize);
453
454     if (srcSize > 0) {
455         /* note : technically could be considered an assert(), since it's an invalid entry */
456         RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter : src==NULL, but srcSize>0");
457     }
458     if (srcSize < minInputSize) {
459         if (srcSize > 0 && format != ZSTD_f_zstd1_magicless) {
460             /* when receiving less than @minInputSize bytes,
461              * control these bytes at least correspond to a supported magic number
462              * in order to error out early if they don't.
463             **/
464             size_t const toCopy = MIN(4, srcSize);
465             unsigned char hbuf[4]; MEM_writeLE32(hbuf, ZSTD_MAGICNUMBER);
466             assert(src != NULL);
467             ZSTD_memcpy(hbuf, src, toCopy);
468             if ( MEM_readLE32(hbuf) != ZSTD_MAGICNUMBER ) {
469                 /* not a zstd frame : let's check if it's a skippable frame */
470                 MEM_writeLE32(hbuf, ZSTD_MAGIC_SKIPPABLE_START);
471                 ZSTD_memcpy(hbuf, src, toCopy);
472                 if ((MEM_readLE32(hbuf) & ZSTD_MAGIC_SKIPPABLE_MASK) != ZSTD_MAGIC_SKIPPABLE_START) {
473                     RETURN_ERROR(prefix_unknown,
474                                 "first bytes don't correspond to any supported magic number");
475         }   }   }
476         return minInputSize;
477     }
478
479     ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));   /* not strictly necessary, but static analyzers may not understand that zfhPtr will be read only if return value is zero, since they are 2 different signals */
480     if ( (format != ZSTD_f_zstd1_magicless)
481       && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
482         if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
483             /* skippable frame */
484             if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
485                 return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
486             ZSTD_memset(zfhPtr, 0, sizeof(*zfhPtr));
487             zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
488             zfhPtr->frameType = ZSTD_skippableFrame;
489             return 0;
490         }
491         RETURN_ERROR(prefix_unknown, "");
492     }
493
494     /* ensure there is enough `srcSize` to fully read/decode frame header */
495     {   size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);
496         if (srcSize < fhsize) return fhsize;
497         zfhPtr->headerSize = (U32)fhsize;
498     }
499
500     {   BYTE const fhdByte = ip[minInputSize-1];
501         size_t pos = minInputSize;
502         U32 const dictIDSizeCode = fhdByte&3;
503         U32 const checksumFlag = (fhdByte>>2)&1;
504         U32 const singleSegment = (fhdByte>>5)&1;
505         U32 const fcsID = fhdByte>>6;
506         U64 windowSize = 0;
507         U32 dictID = 0;
508         U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;
509         RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,
510                         "reserved bits, must be zero");
511
512         if (!singleSegment) {
513             BYTE const wlByte = ip[pos++];
514             U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
515             RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge, "");
516             windowSize = (1ULL << windowLog);
517             windowSize += (windowSize >> 3) * (wlByte&7);
518         }
519         switch(dictIDSizeCode)
520         {
521             default:
522                 assert(0);  /* impossible */
523                 ZSTD_FALLTHROUGH;
524             case 0 : break;
525             case 1 : dictID = ip[pos]; pos++; break;
526             case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
527             case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
528         }
529         switch(fcsID)
530         {
531             default:
532                 assert(0);  /* impossible */
533                 ZSTD_FALLTHROUGH;
534             case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
535             case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
536             case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
537             case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
538         }
539         if (singleSegment) windowSize = frameContentSize;
540
541         zfhPtr->frameType = ZSTD_frame;
542         zfhPtr->frameContentSize = frameContentSize;
543         zfhPtr->windowSize = windowSize;
544         zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
545         zfhPtr->dictID = dictID;
546         zfhPtr->checksumFlag = checksumFlag;
547     }
548     return 0;
549 }
550
551 /** ZSTD_getFrameHeader() :
552  *  decode Frame Header, or require larger `srcSize`.
553  *  note : this function does not consume input, it only reads it.
554  * @return : 0, `zfhPtr` is correctly filled,
555  *          >0, `srcSize` is too small, value is wanted `srcSize` amount,
556  *           or an error code, which can be tested using ZSTD_isError() */
557 size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
558 {
559     return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
560 }
561
562 /** ZSTD_getFrameContentSize() :
563  *  compatible with legacy mode
564  * @return : decompressed size of the single frame pointed to be `src` if known, otherwise
565  *         - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
566  *         - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
567 unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
568 {
569 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
570     if (ZSTD_isLegacy(src, srcSize)) {
571         unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize);
572         return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
573     }
574 #endif
575     {   ZSTD_frameHeader zfh;
576         if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)
577             return ZSTD_CONTENTSIZE_ERROR;
578         if (zfh.frameType == ZSTD_skippableFrame) {
579             return 0;
580         } else {
581             return zfh.frameContentSize;
582     }   }
583 }
584
585 static size_t readSkippableFrameSize(void const* src, size_t srcSize)
586 {
587     size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
588     U32 sizeU32;
589
590     RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
591
592     sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
593     RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
594                     frameParameter_unsupported, "");
595     {   size_t const skippableSize = skippableHeaderSize + sizeU32;
596         RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong, "");
597         return skippableSize;
598     }
599 }
600
601 /*! ZSTD_readSkippableFrame() :
602  * Retrieves content of a skippable frame, and writes it to dst buffer.
603  *
604  * The parameter magicVariant will receive the magicVariant that was supplied when the frame was written,
605  * i.e. magicNumber - ZSTD_MAGIC_SKIPPABLE_START.  This can be NULL if the caller is not interested
606  * in the magicVariant.
607  *
608  * Returns an error if destination buffer is not large enough, or if this is not a valid skippable frame.
609  *
610  * @return : number of bytes written or a ZSTD error.
611  */
612 size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity,
613                                unsigned* magicVariant,  /* optional, can be NULL */
614                          const void* src, size_t srcSize)
615 {
616     RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong, "");
617
618     {   U32 const magicNumber = MEM_readLE32(src);
619         size_t skippableFrameSize = readSkippableFrameSize(src, srcSize);
620         size_t skippableContentSize = skippableFrameSize - ZSTD_SKIPPABLEHEADERSIZE;
621
622         /* check input validity */
623         RETURN_ERROR_IF(!ZSTD_isSkippableFrame(src, srcSize), frameParameter_unsupported, "");
624         RETURN_ERROR_IF(skippableFrameSize < ZSTD_SKIPPABLEHEADERSIZE || skippableFrameSize > srcSize, srcSize_wrong, "");
625         RETURN_ERROR_IF(skippableContentSize > dstCapacity, dstSize_tooSmall, "");
626
627         /* deliver payload */
628         if (skippableContentSize > 0  && dst != NULL)
629             ZSTD_memcpy(dst, (const BYTE *)src + ZSTD_SKIPPABLEHEADERSIZE, skippableContentSize);
630         if (magicVariant != NULL)
631             *magicVariant = magicNumber - ZSTD_MAGIC_SKIPPABLE_START;
632         return skippableContentSize;
633     }
634 }
635
636 /** ZSTD_findDecompressedSize() :
637  *  `srcSize` must be the exact length of some number of ZSTD compressed and/or
638  *      skippable frames
639  *  note: compatible with legacy mode
640  * @return : decompressed size of the frames contained */
641 unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
642 {
643     unsigned long long totalDstSize = 0;
644
645     while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) {
646         U32 const magicNumber = MEM_readLE32(src);
647
648         if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
649             size_t const skippableSize = readSkippableFrameSize(src, srcSize);
650             if (ZSTD_isError(skippableSize)) return ZSTD_CONTENTSIZE_ERROR;
651             assert(skippableSize <= srcSize);
652
653             src = (const BYTE *)src + skippableSize;
654             srcSize -= skippableSize;
655             continue;
656         }
657
658         {   unsigned long long const fcs = ZSTD_getFrameContentSize(src, srcSize);
659             if (fcs >= ZSTD_CONTENTSIZE_ERROR) return fcs;
660
661             if (totalDstSize + fcs < totalDstSize)
662                 return ZSTD_CONTENTSIZE_ERROR; /* check for overflow */
663             totalDstSize += fcs;
664         }
665         /* skip to next frame */
666         {   size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
667             if (ZSTD_isError(frameSrcSize)) return ZSTD_CONTENTSIZE_ERROR;
668             assert(frameSrcSize <= srcSize);
669
670             src = (const BYTE *)src + frameSrcSize;
671             srcSize -= frameSrcSize;
672         }
673     }  /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
674
675     if (srcSize) return ZSTD_CONTENTSIZE_ERROR;
676
677     return totalDstSize;
678 }
679
680 /** ZSTD_getDecompressedSize() :
681  *  compatible with legacy mode
682  * @return : decompressed size if known, 0 otherwise
683              note : 0 can mean any of the following :
684                    - frame content is empty
685                    - decompressed size field is not present in frame header
686                    - frame header unknown / not supported
687                    - frame header not complete (`srcSize` too small) */
688 unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
689 {
690     unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
691     ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN);
692     return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;
693 }
694
695
696 /** ZSTD_decodeFrameHeader() :
697  * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
698  * If multiple DDict references are enabled, also will choose the correct DDict to use.
699  * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
700 static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
701 {
702     size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
703     if (ZSTD_isError(result)) return result;    /* invalid header */
704     RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
705
706     /* Reference DDict requested by frame if dctx references multiple ddicts */
707     if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts && dctx->ddictSet) {
708         ZSTD_DCtx_selectFrameDDict(dctx);
709     }
710
711 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
712     /* Skip the dictID check in fuzzing mode, because it makes the search
713      * harder.
714      */
715     RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
716                     dictionary_wrong, "");
717 #endif
718     dctx->validateChecksum = (dctx->fParams.checksumFlag && !dctx->forceIgnoreChecksum) ? 1 : 0;
719     if (dctx->validateChecksum) XXH64_reset(&dctx->xxhState, 0);
720     dctx->processedCSize += headerSize;
721     return 0;
722 }
723
724 static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
725 {
726     ZSTD_frameSizeInfo frameSizeInfo;
727     frameSizeInfo.compressedSize = ret;
728     frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
729     return frameSizeInfo;
730 }
731
732 static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize, ZSTD_format_e format)
733 {
734     ZSTD_frameSizeInfo frameSizeInfo;
735     ZSTD_memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
736
737 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
738     if (format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize))
739         return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
740 #endif
741
742     if (format == ZSTD_f_zstd1 && (srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
743         && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
744         frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
745         assert(ZSTD_isError(frameSizeInfo.compressedSize) ||
746                frameSizeInfo.compressedSize <= srcSize);
747         return frameSizeInfo;
748     } else {
749         const BYTE* ip = (const BYTE*)src;
750         const BYTE* const ipstart = ip;
751         size_t remainingSize = srcSize;
752         size_t nbBlocks = 0;
753         ZSTD_frameHeader zfh;
754
755         /* Extract Frame Header */
756         {   size_t const ret = ZSTD_getFrameHeader_advanced(&zfh, src, srcSize, format);
757             if (ZSTD_isError(ret))
758                 return ZSTD_errorFrameSizeInfo(ret);
759             if (ret > 0)
760                 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
761         }
762
763         ip += zfh.headerSize;
764         remainingSize -= zfh.headerSize;
765
766         /* Iterate over each block */
767         while (1) {
768             blockProperties_t blockProperties;
769             size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
770             if (ZSTD_isError(cBlockSize))
771                 return ZSTD_errorFrameSizeInfo(cBlockSize);
772
773             if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
774                 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
775
776             ip += ZSTD_blockHeaderSize + cBlockSize;
777             remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
778             nbBlocks++;
779
780             if (blockProperties.lastBlock) break;
781         }
782
783         /* Final frame content checksum */
784         if (zfh.checksumFlag) {
785             if (remainingSize < 4)
786                 return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
787             ip += 4;
788         }
789
790         frameSizeInfo.nbBlocks = nbBlocks;
791         frameSizeInfo.compressedSize = (size_t)(ip - ipstart);
792         frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
793                                         ? zfh.frameContentSize
794                                         : (unsigned long long)nbBlocks * zfh.blockSizeMax;
795         return frameSizeInfo;
796     }
797 }
798
799 static size_t ZSTD_findFrameCompressedSize_advanced(const void *src, size_t srcSize, ZSTD_format_e format) {
800     ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, format);
801     return frameSizeInfo.compressedSize;
802 }
803
804 /** ZSTD_findFrameCompressedSize() :
805  * See docs in zstd.h
806  * Note: compatible with legacy mode */
807 size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
808 {
809     return ZSTD_findFrameCompressedSize_advanced(src, srcSize, ZSTD_f_zstd1);
810 }
811
812 /** ZSTD_decompressBound() :
813  *  compatible with legacy mode
814  *  `src` must point to the start of a ZSTD frame or a skippeable frame
815  *  `srcSize` must be at least as large as the frame contained
816  *  @return : the maximum decompressed size of the compressed source
817  */
818 unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
819 {
820     unsigned long long bound = 0;
821     /* Iterate over each frame */
822     while (srcSize > 0) {
823         ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
824         size_t const compressedSize = frameSizeInfo.compressedSize;
825         unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
826         if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
827             return ZSTD_CONTENTSIZE_ERROR;
828         assert(srcSize >= compressedSize);
829         src = (const BYTE*)src + compressedSize;
830         srcSize -= compressedSize;
831         bound += decompressedBound;
832     }
833     return bound;
834 }
835
836 size_t ZSTD_decompressionMargin(void const* src, size_t srcSize)
837 {
838     size_t margin = 0;
839     unsigned maxBlockSize = 0;
840
841     /* Iterate over each frame */
842     while (srcSize > 0) {
843         ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize, ZSTD_f_zstd1);
844         size_t const compressedSize = frameSizeInfo.compressedSize;
845         unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
846         ZSTD_frameHeader zfh;
847
848         FORWARD_IF_ERROR(ZSTD_getFrameHeader(&zfh, src, srcSize), "");
849         if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
850             return ERROR(corruption_detected);
851
852         if (zfh.frameType == ZSTD_frame) {
853             /* Add the frame header to our margin */
854             margin += zfh.headerSize;
855             /* Add the checksum to our margin */
856             margin += zfh.checksumFlag ? 4 : 0;
857             /* Add 3 bytes per block */
858             margin += 3 * frameSizeInfo.nbBlocks;
859
860             /* Compute the max block size */
861             maxBlockSize = MAX(maxBlockSize, zfh.blockSizeMax);
862         } else {
863             assert(zfh.frameType == ZSTD_skippableFrame);
864             /* Add the entire skippable frame size to our margin. */
865             margin += compressedSize;
866         }
867
868         assert(srcSize >= compressedSize);
869         src = (const BYTE*)src + compressedSize;
870         srcSize -= compressedSize;
871     }
872
873     /* Add the max block size back to the margin. */
874     margin += maxBlockSize;
875
876     return margin;
877 }
878
879 /*-*************************************************************
880  *   Frame decoding
881  ***************************************************************/
882
883 /** ZSTD_insertBlock() :
884  *  insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
885 size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
886 {
887     DEBUGLOG(5, "ZSTD_insertBlock: %u bytes", (unsigned)blockSize);
888     ZSTD_checkContinuity(dctx, blockStart, blockSize);
889     dctx->previousDstEnd = (const char*)blockStart + blockSize;
890     return blockSize;
891 }
892
893
894 static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
895                           const void* src, size_t srcSize)
896 {
897     DEBUGLOG(5, "ZSTD_copyRawBlock");
898     RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall, "");
899     if (dst == NULL) {
900         if (srcSize == 0) return 0;
901         RETURN_ERROR(dstBuffer_null, "");
902     }
903     ZSTD_memmove(dst, src, srcSize);
904     return srcSize;
905 }
906
907 static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
908                                BYTE b,
909                                size_t regenSize)
910 {
911     RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall, "");
912     if (dst == NULL) {
913         if (regenSize == 0) return 0;
914         RETURN_ERROR(dstBuffer_null, "");
915     }
916     ZSTD_memset(dst, b, regenSize);
917     return regenSize;
918 }
919
920 static void ZSTD_DCtx_trace_end(ZSTD_DCtx const* dctx, U64 uncompressedSize, U64 compressedSize, unsigned streaming)
921 {
922 #if ZSTD_TRACE
923     if (dctx->traceCtx && ZSTD_trace_decompress_end != NULL) {
924         ZSTD_Trace trace;
925         ZSTD_memset(&trace, 0, sizeof(trace));
926         trace.version = ZSTD_VERSION_NUMBER;
927         trace.streaming = streaming;
928         if (dctx->ddict) {
929             trace.dictionaryID = ZSTD_getDictID_fromDDict(dctx->ddict);
930             trace.dictionarySize = ZSTD_DDict_dictSize(dctx->ddict);
931             trace.dictionaryIsCold = dctx->ddictIsCold;
932         }
933         trace.uncompressedSize = (size_t)uncompressedSize;
934         trace.compressedSize = (size_t)compressedSize;
935         trace.dctx = dctx;
936         ZSTD_trace_decompress_end(dctx->traceCtx, &trace);
937     }
938 #else
939     (void)dctx;
940     (void)uncompressedSize;
941     (void)compressedSize;
942     (void)streaming;
943 #endif
944 }
945
946
947 /*! ZSTD_decompressFrame() :
948  * @dctx must be properly initialized
949  *  will update *srcPtr and *srcSizePtr,
950  *  to make *srcPtr progress by one frame. */
951 static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
952                                    void* dst, size_t dstCapacity,
953                              const void** srcPtr, size_t *srcSizePtr)
954 {
955     const BYTE* const istart = (const BYTE*)(*srcPtr);
956     const BYTE* ip = istart;
957     BYTE* const ostart = (BYTE*)dst;
958     BYTE* const oend = dstCapacity != 0 ? ostart + dstCapacity : ostart;
959     BYTE* op = ostart;
960     size_t remainingSrcSize = *srcSizePtr;
961
962     DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr);
963
964     /* check */
965     RETURN_ERROR_IF(
966         remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize,
967         srcSize_wrong, "");
968
969     /* Frame Header */
970     {   size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal(
971                 ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format);
972         if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
973         RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
974                         srcSize_wrong, "");
975         FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) , "");
976         ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
977     }
978
979     /* Shrink the blockSizeMax if enabled */
980     if (dctx->maxBlockSizeParam != 0)
981         dctx->fParams.blockSizeMax = MIN(dctx->fParams.blockSizeMax, (unsigned)dctx->maxBlockSizeParam);
982
983     /* Loop on each block */
984     while (1) {
985         BYTE* oBlockEnd = oend;
986         size_t decodedSize;
987         blockProperties_t blockProperties;
988         size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
989         if (ZSTD_isError(cBlockSize)) return cBlockSize;
990
991         ip += ZSTD_blockHeaderSize;
992         remainingSrcSize -= ZSTD_blockHeaderSize;
993         RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong, "");
994
995         if (ip >= op && ip < oBlockEnd) {
996             /* We are decompressing in-place. Limit the output pointer so that we
997              * don't overwrite the block that we are currently reading. This will
998              * fail decompression if the input & output pointers aren't spaced
999              * far enough apart.
1000              *
1001              * This is important to set, even when the pointers are far enough
1002              * apart, because ZSTD_decompressBlock_internal() can decide to store
1003              * literals in the output buffer, after the block it is decompressing.
1004              * Since we don't want anything to overwrite our input, we have to tell
1005              * ZSTD_decompressBlock_internal to never write past ip.
1006              *
1007              * See ZSTD_allocateLiteralsBuffer() for reference.
1008              */
1009             oBlockEnd = op + (ip - op);
1010         }
1011
1012         switch(blockProperties.blockType)
1013         {
1014         case bt_compressed:
1015             assert(dctx->isFrameDecompression == 1);
1016             decodedSize = ZSTD_decompressBlock_internal(dctx, op, (size_t)(oBlockEnd-op), ip, cBlockSize, not_streaming);
1017             break;
1018         case bt_raw :
1019             /* Use oend instead of oBlockEnd because this function is safe to overlap. It uses memmove. */
1020             decodedSize = ZSTD_copyRawBlock(op, (size_t)(oend-op), ip, cBlockSize);
1021             break;
1022         case bt_rle :
1023             decodedSize = ZSTD_setRleBlock(op, (size_t)(oBlockEnd-op), *ip, blockProperties.origSize);
1024             break;
1025         case bt_reserved :
1026         default:
1027             RETURN_ERROR(corruption_detected, "invalid block type");
1028         }
1029         FORWARD_IF_ERROR(decodedSize, "Block decompression failure");
1030         DEBUGLOG(5, "Decompressed block of dSize = %u", (unsigned)decodedSize);
1031         if (dctx->validateChecksum) {
1032             XXH64_update(&dctx->xxhState, op, decodedSize);
1033         }
1034         if (decodedSize) /* support dst = NULL,0 */ {
1035             op += decodedSize;
1036         }
1037         assert(ip != NULL);
1038         ip += cBlockSize;
1039         remainingSrcSize -= cBlockSize;
1040         if (blockProperties.lastBlock) break;
1041     }
1042
1043     if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1044         RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
1045                         corruption_detected, "");
1046     }
1047     if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1048         RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong, "");
1049         if (!dctx->forceIgnoreChecksum) {
1050             U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
1051             U32 checkRead;
1052             checkRead = MEM_readLE32(ip);
1053             RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong, "");
1054         }
1055         ip += 4;
1056         remainingSrcSize -= 4;
1057     }
1058     ZSTD_DCtx_trace_end(dctx, (U64)(op-ostart), (U64)(ip-istart), /* streaming */ 0);
1059     /* Allow caller to get size read */
1060     DEBUGLOG(4, "ZSTD_decompressFrame: decompressed frame of size %zi, consuming %zi bytes of input", op-ostart, ip - (const BYTE*)*srcPtr);
1061     *srcPtr = ip;
1062     *srcSizePtr = remainingSrcSize;
1063     return (size_t)(op-ostart);
1064 }
1065
1066 static
1067 ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
1068 size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1069                                         void* dst, size_t dstCapacity,
1070                                   const void* src, size_t srcSize,
1071                                   const void* dict, size_t dictSize,
1072                                   const ZSTD_DDict* ddict)
1073 {
1074     void* const dststart = dst;
1075     int moreThan1Frame = 0;
1076
1077     DEBUGLOG(5, "ZSTD_decompressMultiFrame");
1078     assert(dict==NULL || ddict==NULL);  /* either dict or ddict set, not both */
1079
1080     if (ddict) {
1081         dict = ZSTD_DDict_dictContent(ddict);
1082         dictSize = ZSTD_DDict_dictSize(ddict);
1083     }
1084
1085     while (srcSize >= ZSTD_startingInputLength(dctx->format)) {
1086
1087 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1088         if (dctx->format == ZSTD_f_zstd1 && ZSTD_isLegacy(src, srcSize)) {
1089             size_t decodedSize;
1090             size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
1091             if (ZSTD_isError(frameSize)) return frameSize;
1092             RETURN_ERROR_IF(dctx->staticSize, memory_allocation,
1093                 "legacy support is not compatible with static dctx");
1094
1095             decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
1096             if (ZSTD_isError(decodedSize)) return decodedSize;
1097
1098             {
1099                 unsigned long long const expectedSize = ZSTD_getFrameContentSize(src, srcSize);
1100                 RETURN_ERROR_IF(expectedSize == ZSTD_CONTENTSIZE_ERROR, corruption_detected, "Corrupted frame header!");
1101                 if (expectedSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1102                     RETURN_ERROR_IF(expectedSize != decodedSize, corruption_detected,
1103                         "Frame header size does not match decoded size!");
1104                 }
1105             }
1106
1107             assert(decodedSize <= dstCapacity);
1108             dst = (BYTE*)dst + decodedSize;
1109             dstCapacity -= decodedSize;
1110
1111             src = (const BYTE*)src + frameSize;
1112             srcSize -= frameSize;
1113
1114             continue;
1115         }
1116 #endif
1117
1118         if (dctx->format == ZSTD_f_zstd1 && srcSize >= 4) {
1119             U32 const magicNumber = MEM_readLE32(src);
1120             DEBUGLOG(5, "reading magic number %08X", (unsigned)magicNumber);
1121             if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
1122                 /* skippable frame detected : skip it */
1123                 size_t const skippableSize = readSkippableFrameSize(src, srcSize);
1124                 FORWARD_IF_ERROR(skippableSize, "invalid skippable frame");
1125                 assert(skippableSize <= srcSize);
1126
1127                 src = (const BYTE *)src + skippableSize;
1128                 srcSize -= skippableSize;
1129                 continue; /* check next frame */
1130         }   }
1131
1132         if (ddict) {
1133             /* we were called from ZSTD_decompress_usingDDict */
1134             FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict), "");
1135         } else {
1136             /* this will initialize correctly with no dict if dict == NULL, so
1137              * use this in all cases but ddict */
1138             FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize), "");
1139         }
1140         ZSTD_checkContinuity(dctx, dst, dstCapacity);
1141
1142         {   const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
1143                                                     &src, &srcSize);
1144             RETURN_ERROR_IF(
1145                 (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
1146              && (moreThan1Frame==1),
1147                 srcSize_wrong,
1148                 "At least one frame successfully completed, "
1149                 "but following bytes are garbage: "
1150                 "it's more likely to be a srcSize error, "
1151                 "specifying more input bytes than size of frame(s). "
1152                 "Note: one could be unlucky, it might be a corruption error instead, "
1153                 "happening right at the place where we expect zstd magic bytes. "
1154                 "But this is _much_ less likely than a srcSize field error.");
1155             if (ZSTD_isError(res)) return res;
1156             assert(res <= dstCapacity);
1157             if (res != 0)
1158                 dst = (BYTE*)dst + res;
1159             dstCapacity -= res;
1160         }
1161         moreThan1Frame = 1;
1162     }  /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
1163
1164     RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
1165
1166     return (size_t)((BYTE*)dst - (BYTE*)dststart);
1167 }
1168
1169 size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1170                                  void* dst, size_t dstCapacity,
1171                            const void* src, size_t srcSize,
1172                            const void* dict, size_t dictSize)
1173 {
1174     return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
1175 }
1176
1177
1178 static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
1179 {
1180     switch (dctx->dictUses) {
1181     default:
1182         assert(0 /* Impossible */);
1183         ZSTD_FALLTHROUGH;
1184     case ZSTD_dont_use:
1185         ZSTD_clearDict(dctx);
1186         return NULL;
1187     case ZSTD_use_indefinitely:
1188         return dctx->ddict;
1189     case ZSTD_use_once:
1190         dctx->dictUses = ZSTD_dont_use;
1191         return dctx->ddict;
1192     }
1193 }
1194
1195 size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1196 {
1197     return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));
1198 }
1199
1200
1201 size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1202 {
1203 #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
1204     size_t regenSize;
1205     ZSTD_DCtx* const dctx =  ZSTD_createDCtx_internal(ZSTD_defaultCMem);
1206     RETURN_ERROR_IF(dctx==NULL, memory_allocation, "NULL pointer!");
1207     regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
1208     ZSTD_freeDCtx(dctx);
1209     return regenSize;
1210 #else   /* stack mode */
1211     ZSTD_DCtx dctx;
1212     ZSTD_initDCtx_internal(&dctx);
1213     return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
1214 #endif
1215 }
1216
1217
1218 /*-**************************************
1219 *   Advanced Streaming Decompression API
1220 *   Bufferless and synchronous
1221 ****************************************/
1222 size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
1223
1224 /**
1225  * Similar to ZSTD_nextSrcSizeToDecompress(), but when a block input can be streamed, we
1226  * allow taking a partial block as the input. Currently only raw uncompressed blocks can
1227  * be streamed.
1228  *
1229  * For blocks that can be streamed, this allows us to reduce the latency until we produce
1230  * output, and avoid copying the input.
1231  *
1232  * @param inputSize - The total amount of input that the caller currently has.
1233  */
1234 static size_t ZSTD_nextSrcSizeToDecompressWithInputSize(ZSTD_DCtx* dctx, size_t inputSize) {
1235     if (!(dctx->stage == ZSTDds_decompressBlock || dctx->stage == ZSTDds_decompressLastBlock))
1236         return dctx->expected;
1237     if (dctx->bType != bt_raw)
1238         return dctx->expected;
1239     return BOUNDED(1, inputSize, dctx->expected);
1240 }
1241
1242 ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
1243     switch(dctx->stage)
1244     {
1245     default:   /* should not happen */
1246         assert(0);
1247         ZSTD_FALLTHROUGH;
1248     case ZSTDds_getFrameHeaderSize:
1249         ZSTD_FALLTHROUGH;
1250     case ZSTDds_decodeFrameHeader:
1251         return ZSTDnit_frameHeader;
1252     case ZSTDds_decodeBlockHeader:
1253         return ZSTDnit_blockHeader;
1254     case ZSTDds_decompressBlock:
1255         return ZSTDnit_block;
1256     case ZSTDds_decompressLastBlock:
1257         return ZSTDnit_lastBlock;
1258     case ZSTDds_checkChecksum:
1259         return ZSTDnit_checksum;
1260     case ZSTDds_decodeSkippableHeader:
1261         ZSTD_FALLTHROUGH;
1262     case ZSTDds_skipFrame:
1263         return ZSTDnit_skippableFrame;
1264     }
1265 }
1266
1267 static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }
1268
1269 /** ZSTD_decompressContinue() :
1270  *  srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress())
1271  *  @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
1272  *            or an error code, which can be tested using ZSTD_isError() */
1273 size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1274 {
1275     DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
1276     /* Sanity check */
1277     RETURN_ERROR_IF(srcSize != ZSTD_nextSrcSizeToDecompressWithInputSize(dctx, srcSize), srcSize_wrong, "not allowed");
1278     ZSTD_checkContinuity(dctx, dst, dstCapacity);
1279
1280     dctx->processedCSize += srcSize;
1281
1282     switch (dctx->stage)
1283     {
1284     case ZSTDds_getFrameHeaderSize :
1285         assert(src != NULL);
1286         if (dctx->format == ZSTD_f_zstd1) {  /* allows header */
1287             assert(srcSize >= ZSTD_FRAMEIDSIZE);  /* to read skippable magic number */
1288             if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */
1289                 ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
1290                 dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize;  /* remaining to load to get full skippable frame header */
1291                 dctx->stage = ZSTDds_decodeSkippableHeader;
1292                 return 0;
1293         }   }
1294         dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);
1295         if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
1296         ZSTD_memcpy(dctx->headerBuffer, src, srcSize);
1297         dctx->expected = dctx->headerSize - srcSize;
1298         dctx->stage = ZSTDds_decodeFrameHeader;
1299         return 0;
1300
1301     case ZSTDds_decodeFrameHeader:
1302         assert(src != NULL);
1303         ZSTD_memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
1304         FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize), "");
1305         dctx->expected = ZSTD_blockHeaderSize;
1306         dctx->stage = ZSTDds_decodeBlockHeader;
1307         return 0;
1308
1309     case ZSTDds_decodeBlockHeader:
1310         {   blockProperties_t bp;
1311             size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
1312             if (ZSTD_isError(cBlockSize)) return cBlockSize;
1313             RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, "Block Size Exceeds Maximum");
1314             dctx->expected = cBlockSize;
1315             dctx->bType = bp.blockType;
1316             dctx->rleSize = bp.origSize;
1317             if (cBlockSize) {
1318                 dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
1319                 return 0;
1320             }
1321             /* empty block */
1322             if (bp.lastBlock) {
1323                 if (dctx->fParams.checksumFlag) {
1324                     dctx->expected = 4;
1325                     dctx->stage = ZSTDds_checkChecksum;
1326                 } else {
1327                     dctx->expected = 0; /* end of frame */
1328                     dctx->stage = ZSTDds_getFrameHeaderSize;
1329                 }
1330             } else {
1331                 dctx->expected = ZSTD_blockHeaderSize;  /* jump to next header */
1332                 dctx->stage = ZSTDds_decodeBlockHeader;
1333             }
1334             return 0;
1335         }
1336
1337     case ZSTDds_decompressLastBlock:
1338     case ZSTDds_decompressBlock:
1339         DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock");
1340         {   size_t rSize;
1341             switch(dctx->bType)
1342             {
1343             case bt_compressed:
1344                 DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
1345                 assert(dctx->isFrameDecompression == 1);
1346                 rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, is_streaming);
1347                 dctx->expected = 0;  /* Streaming not supported */
1348                 break;
1349             case bt_raw :
1350                 assert(srcSize <= dctx->expected);
1351                 rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
1352                 FORWARD_IF_ERROR(rSize, "ZSTD_copyRawBlock failed");
1353                 assert(rSize == srcSize);
1354                 dctx->expected -= rSize;
1355                 break;
1356             case bt_rle :
1357                 rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);
1358                 dctx->expected = 0;  /* Streaming not supported */
1359                 break;
1360             case bt_reserved :   /* should never happen */
1361             default:
1362                 RETURN_ERROR(corruption_detected, "invalid block type");
1363             }
1364             FORWARD_IF_ERROR(rSize, "");
1365             RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, "Decompressed Block Size Exceeds Maximum");
1366             DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
1367             dctx->decodedSize += rSize;
1368             if (dctx->validateChecksum) XXH64_update(&dctx->xxhState, dst, rSize);
1369             dctx->previousDstEnd = (char*)dst + rSize;
1370
1371             /* Stay on the same stage until we are finished streaming the block. */
1372             if (dctx->expected > 0) {
1373                 return rSize;
1374             }
1375
1376             if (dctx->stage == ZSTDds_decompressLastBlock) {   /* end of frame */
1377                 DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
1378                 RETURN_ERROR_IF(
1379                     dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
1380                  && dctx->decodedSize != dctx->fParams.frameContentSize,
1381                     corruption_detected, "");
1382                 if (dctx->fParams.checksumFlag) {  /* another round for frame checksum */
1383                     dctx->expected = 4;
1384                     dctx->stage = ZSTDds_checkChecksum;
1385                 } else {
1386                     ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
1387                     dctx->expected = 0;   /* ends here */
1388                     dctx->stage = ZSTDds_getFrameHeaderSize;
1389                 }
1390             } else {
1391                 dctx->stage = ZSTDds_decodeBlockHeader;
1392                 dctx->expected = ZSTD_blockHeaderSize;
1393             }
1394             return rSize;
1395         }
1396
1397     case ZSTDds_checkChecksum:
1398         assert(srcSize == 4);  /* guaranteed by dctx->expected */
1399         {
1400             if (dctx->validateChecksum) {
1401                 U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1402                 U32 const check32 = MEM_readLE32(src);
1403                 DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
1404                 RETURN_ERROR_IF(check32 != h32, checksum_wrong, "");
1405             }
1406             ZSTD_DCtx_trace_end(dctx, dctx->decodedSize, dctx->processedCSize, /* streaming */ 1);
1407             dctx->expected = 0;
1408             dctx->stage = ZSTDds_getFrameHeaderSize;
1409             return 0;
1410         }
1411
1412     case ZSTDds_decodeSkippableHeader:
1413         assert(src != NULL);
1414         assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
1415         assert(dctx->format != ZSTD_f_zstd1_magicless);
1416         ZSTD_memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize);   /* complete skippable header */
1417         dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE);   /* note : dctx->expected can grow seriously large, beyond local buffer size */
1418         dctx->stage = ZSTDds_skipFrame;
1419         return 0;
1420
1421     case ZSTDds_skipFrame:
1422         dctx->expected = 0;
1423         dctx->stage = ZSTDds_getFrameHeaderSize;
1424         return 0;
1425
1426     default:
1427         assert(0);   /* impossible */
1428         RETURN_ERROR(GENERIC, "impossible to reach");   /* some compilers require default to do something */
1429     }
1430 }
1431
1432
1433 static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1434 {
1435     dctx->dictEnd = dctx->previousDstEnd;
1436     dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
1437     dctx->prefixStart = dict;
1438     dctx->previousDstEnd = (const char*)dict + dictSize;
1439 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1440     dctx->dictContentBeginForFuzzing = dctx->prefixStart;
1441     dctx->dictContentEndForFuzzing = dctx->previousDstEnd;
1442 #endif
1443     return 0;
1444 }
1445
1446 /*! ZSTD_loadDEntropy() :
1447  *  dict : must point at beginning of a valid zstd dictionary.
1448  * @return : size of entropy tables read */
1449 size_t
1450 ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
1451                   const void* const dict, size_t const dictSize)
1452 {
1453     const BYTE* dictPtr = (const BYTE*)dict;
1454     const BYTE* const dictEnd = dictPtr + dictSize;
1455
1456     RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted, "dict is too small");
1457     assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY);   /* dict must be valid */
1458     dictPtr += 8;   /* skip header = magic + dictID */
1459
1460     ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable));
1461     ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable));
1462     ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE);
1463     {   void* const workspace = &entropy->LLTable;   /* use fse tables as temporary workspace; implies fse tables are grouped together */
1464         size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable);
1465 #ifdef HUF_FORCE_DECOMPRESS_X1
1466         /* in minimal huffman, we always use X1 variants */
1467         size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
1468                                                 dictPtr, dictEnd - dictPtr,
1469                                                 workspace, workspaceSize, /* flags */ 0);
1470 #else
1471         size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
1472                                                 dictPtr, (size_t)(dictEnd - dictPtr),
1473                                                 workspace, workspaceSize, /* flags */ 0);
1474 #endif
1475         RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted, "");
1476         dictPtr += hSize;
1477     }
1478
1479     {   short offcodeNCount[MaxOff+1];
1480         unsigned offcodeMaxValue = MaxOff, offcodeLog;
1481         size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, (size_t)(dictEnd-dictPtr));
1482         RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted, "");
1483         RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted, "");
1484         RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted, "");
1485         ZSTD_buildFSETable( entropy->OFTable,
1486                             offcodeNCount, offcodeMaxValue,
1487                             OF_base, OF_bits,
1488                             offcodeLog,
1489                             entropy->workspace, sizeof(entropy->workspace),
1490                             /* bmi2 */0);
1491         dictPtr += offcodeHeaderSize;
1492     }
1493
1494     {   short matchlengthNCount[MaxML+1];
1495         unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1496         size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
1497         RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted, "");
1498         RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted, "");
1499         RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted, "");
1500         ZSTD_buildFSETable( entropy->MLTable,
1501                             matchlengthNCount, matchlengthMaxValue,
1502                             ML_base, ML_bits,
1503                             matchlengthLog,
1504                             entropy->workspace, sizeof(entropy->workspace),
1505                             /* bmi2 */ 0);
1506         dictPtr += matchlengthHeaderSize;
1507     }
1508
1509     {   short litlengthNCount[MaxLL+1];
1510         unsigned litlengthMaxValue = MaxLL, litlengthLog;
1511         size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, (size_t)(dictEnd-dictPtr));
1512         RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted, "");
1513         RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted, "");
1514         RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted, "");
1515         ZSTD_buildFSETable( entropy->LLTable,
1516                             litlengthNCount, litlengthMaxValue,
1517                             LL_base, LL_bits,
1518                             litlengthLog,
1519                             entropy->workspace, sizeof(entropy->workspace),
1520                             /* bmi2 */ 0);
1521         dictPtr += litlengthHeaderSize;
1522     }
1523
1524     RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted, "");
1525     {   int i;
1526         size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
1527         for (i=0; i<3; i++) {
1528             U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
1529             RETURN_ERROR_IF(rep==0 || rep > dictContentSize,
1530                             dictionary_corrupted, "");
1531             entropy->rep[i] = rep;
1532     }   }
1533
1534     return (size_t)(dictPtr - (const BYTE*)dict);
1535 }
1536
1537 static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1538 {
1539     if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
1540     {   U32 const magic = MEM_readLE32(dict);
1541         if (magic != ZSTD_MAGIC_DICTIONARY) {
1542             return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */
1543     }   }
1544     dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
1545
1546     /* load entropy tables */
1547     {   size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
1548         RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted, "");
1549         dict = (const char*)dict + eSize;
1550         dictSize -= eSize;
1551     }
1552     dctx->litEntropy = dctx->fseEntropy = 1;
1553
1554     /* reference dictionary content */
1555     return ZSTD_refDictContent(dctx, dict, dictSize);
1556 }
1557
1558 size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1559 {
1560     assert(dctx != NULL);
1561 #if ZSTD_TRACE
1562     dctx->traceCtx = (ZSTD_trace_decompress_begin != NULL) ? ZSTD_trace_decompress_begin(dctx) : 0;
1563 #endif
1564     dctx->expected = ZSTD_startingInputLength(dctx->format);  /* dctx->format must be properly set */
1565     dctx->stage = ZSTDds_getFrameHeaderSize;
1566     dctx->processedCSize = 0;
1567     dctx->decodedSize = 0;
1568     dctx->previousDstEnd = NULL;
1569     dctx->prefixStart = NULL;
1570     dctx->virtualStart = NULL;
1571     dctx->dictEnd = NULL;
1572     dctx->entropy.hufTable[0] = (HUF_DTable)((ZSTD_HUFFDTABLE_CAPACITY_LOG)*0x1000001);  /* cover both little and big endian */
1573     dctx->litEntropy = dctx->fseEntropy = 0;
1574     dctx->dictID = 0;
1575     dctx->bType = bt_reserved;
1576     dctx->isFrameDecompression = 1;
1577     ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
1578     ZSTD_memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue));  /* initial repcodes */
1579     dctx->LLTptr = dctx->entropy.LLTable;
1580     dctx->MLTptr = dctx->entropy.MLTable;
1581     dctx->OFTptr = dctx->entropy.OFTable;
1582     dctx->HUFptr = dctx->entropy.hufTable;
1583     return 0;
1584 }
1585
1586 size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1587 {
1588     FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
1589     if (dict && dictSize)
1590         RETURN_ERROR_IF(
1591             ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
1592             dictionary_corrupted, "");
1593     return 0;
1594 }
1595
1596
1597 /* ======   ZSTD_DDict   ====== */
1598
1599 size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
1600 {
1601     DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict");
1602     assert(dctx != NULL);
1603     if (ddict) {
1604         const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);
1605         size_t const dictSize = ZSTD_DDict_dictSize(ddict);
1606         const void* const dictEnd = dictStart + dictSize;
1607         dctx->ddictIsCold = (dctx->dictEnd != dictEnd);
1608         DEBUGLOG(4, "DDict is %s",
1609                     dctx->ddictIsCold ? "~cold~" : "hot!");
1610     }
1611     FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) , "");
1612     if (ddict) {   /* NULL ddict is equivalent to no dictionary */
1613         ZSTD_copyDDictParameters(dctx, ddict);
1614     }
1615     return 0;
1616 }
1617
1618 /*! ZSTD_getDictID_fromDict() :
1619  *  Provides the dictID stored within dictionary.
1620  *  if @return == 0, the dictionary is not conformant with Zstandard specification.
1621  *  It can still be loaded, but as a content-only dictionary. */
1622 unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
1623 {
1624     if (dictSize < 8) return 0;
1625     if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
1626     return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
1627 }
1628
1629 /*! ZSTD_getDictID_fromFrame() :
1630  *  Provides the dictID required to decompress frame stored within `src`.
1631  *  If @return == 0, the dictID could not be decoded.
1632  *  This could for one of the following reasons :
1633  *  - The frame does not require a dictionary (most common case).
1634  *  - The frame was built with dictID intentionally removed.
1635  *    Needed dictionary is a hidden piece of information.
1636  *    Note : this use case also happens when using a non-conformant dictionary.
1637  *  - `srcSize` is too small, and as a result, frame header could not be decoded.
1638  *    Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
1639  *  - This is not a Zstandard frame.
1640  *  When identifying the exact failure cause, it's possible to use
1641  *  ZSTD_getFrameHeader(), which will provide a more precise error code. */
1642 unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
1643 {
1644     ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0, 0, 0 };
1645     size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);
1646     if (ZSTD_isError(hError)) return 0;
1647     return zfp.dictID;
1648 }
1649
1650
1651 /*! ZSTD_decompress_usingDDict() :
1652 *   Decompression using a pre-digested Dictionary
1653 *   Use dictionary without significant overhead. */
1654 size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
1655                                   void* dst, size_t dstCapacity,
1656                             const void* src, size_t srcSize,
1657                             const ZSTD_DDict* ddict)
1658 {
1659     /* pass content and size in case legacy frames are encountered */
1660     return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
1661                                      NULL, 0,
1662                                      ddict);
1663 }
1664
1665
1666 /*=====================================
1667 *   Streaming decompression
1668 *====================================*/
1669
1670 ZSTD_DStream* ZSTD_createDStream(void)
1671 {
1672     DEBUGLOG(3, "ZSTD_createDStream");
1673     return ZSTD_createDCtx_internal(ZSTD_defaultCMem);
1674 }
1675
1676 ZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)
1677 {
1678     return ZSTD_initStaticDCtx(workspace, workspaceSize);
1679 }
1680
1681 ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
1682 {
1683     return ZSTD_createDCtx_internal(customMem);
1684 }
1685
1686 size_t ZSTD_freeDStream(ZSTD_DStream* zds)
1687 {
1688     return ZSTD_freeDCtx(zds);
1689 }
1690
1691
1692 /* ***  Initialization  *** */
1693
1694 size_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; }
1695 size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
1696
1697 size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
1698                                    const void* dict, size_t dictSize,
1699                                          ZSTD_dictLoadMethod_e dictLoadMethod,
1700                                          ZSTD_dictContentType_e dictContentType)
1701 {
1702     RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1703     ZSTD_clearDict(dctx);
1704     if (dict && dictSize != 0) {
1705         dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
1706         RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation, "NULL pointer!");
1707         dctx->ddict = dctx->ddictLocal;
1708         dctx->dictUses = ZSTD_use_indefinitely;
1709     }
1710     return 0;
1711 }
1712
1713 size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1714 {
1715     return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
1716 }
1717
1718 size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1719 {
1720     return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
1721 }
1722
1723 size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
1724 {
1725     FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType), "");
1726     dctx->dictUses = ZSTD_use_once;
1727     return 0;
1728 }
1729
1730 size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)
1731 {
1732     return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent);
1733 }
1734
1735
1736 /* ZSTD_initDStream_usingDict() :
1737  * return : expected size, aka ZSTD_startingInputLength().
1738  * this function cannot fail */
1739 size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1740 {
1741     DEBUGLOG(4, "ZSTD_initDStream_usingDict");
1742     FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) , "");
1743     FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) , "");
1744     return ZSTD_startingInputLength(zds->format);
1745 }
1746
1747 /* note : this variant can't fail */
1748 size_t ZSTD_initDStream(ZSTD_DStream* zds)
1749 {
1750     DEBUGLOG(4, "ZSTD_initDStream");
1751     FORWARD_IF_ERROR(ZSTD_DCtx_reset(zds, ZSTD_reset_session_only), "");
1752     FORWARD_IF_ERROR(ZSTD_DCtx_refDDict(zds, NULL), "");
1753     return ZSTD_startingInputLength(zds->format);
1754 }
1755
1756 /* ZSTD_initDStream_usingDDict() :
1757  * ddict will just be referenced, and must outlive decompression session
1758  * this function cannot fail */
1759 size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
1760 {
1761     DEBUGLOG(4, "ZSTD_initDStream_usingDDict");
1762     FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) , "");
1763     FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) , "");
1764     return ZSTD_startingInputLength(dctx->format);
1765 }
1766
1767 /* ZSTD_resetDStream() :
1768  * return : expected size, aka ZSTD_startingInputLength().
1769  * this function cannot fail */
1770 size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
1771 {
1772     DEBUGLOG(4, "ZSTD_resetDStream");
1773     FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only), "");
1774     return ZSTD_startingInputLength(dctx->format);
1775 }
1776
1777
1778 size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
1779 {
1780     RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1781     ZSTD_clearDict(dctx);
1782     if (ddict) {
1783         dctx->ddict = ddict;
1784         dctx->dictUses = ZSTD_use_indefinitely;
1785         if (dctx->refMultipleDDicts == ZSTD_rmd_refMultipleDDicts) {
1786             if (dctx->ddictSet == NULL) {
1787                 dctx->ddictSet = ZSTD_createDDictHashSet(dctx->customMem);
1788                 if (!dctx->ddictSet) {
1789                     RETURN_ERROR(memory_allocation, "Failed to allocate memory for hash set!");
1790                 }
1791             }
1792             assert(!dctx->staticSize);  /* Impossible: ddictSet cannot have been allocated if static dctx */
1793             FORWARD_IF_ERROR(ZSTD_DDictHashSet_addDDict(dctx->ddictSet, ddict, dctx->customMem), "");
1794         }
1795     }
1796     return 0;
1797 }
1798
1799 /* ZSTD_DCtx_setMaxWindowSize() :
1800  * note : no direct equivalence in ZSTD_DCtx_setParameter,
1801  * since this version sets windowSize, and the other sets windowLog */
1802 size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
1803 {
1804     ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
1805     size_t const min = (size_t)1 << bounds.lowerBound;
1806     size_t const max = (size_t)1 << bounds.upperBound;
1807     RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1808     RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound, "");
1809     RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound, "");
1810     dctx->maxWindowSize = maxWindowSize;
1811     return 0;
1812 }
1813
1814 size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
1815 {
1816     return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, (int)format);
1817 }
1818
1819 ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
1820 {
1821     ZSTD_bounds bounds = { 0, 0, 0 };
1822     switch(dParam) {
1823         case ZSTD_d_windowLogMax:
1824             bounds.lowerBound = ZSTD_WINDOWLOG_ABSOLUTEMIN;
1825             bounds.upperBound = ZSTD_WINDOWLOG_MAX;
1826             return bounds;
1827         case ZSTD_d_format:
1828             bounds.lowerBound = (int)ZSTD_f_zstd1;
1829             bounds.upperBound = (int)ZSTD_f_zstd1_magicless;
1830             ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
1831             return bounds;
1832         case ZSTD_d_stableOutBuffer:
1833             bounds.lowerBound = (int)ZSTD_bm_buffered;
1834             bounds.upperBound = (int)ZSTD_bm_stable;
1835             return bounds;
1836         case ZSTD_d_forceIgnoreChecksum:
1837             bounds.lowerBound = (int)ZSTD_d_validateChecksum;
1838             bounds.upperBound = (int)ZSTD_d_ignoreChecksum;
1839             return bounds;
1840         case ZSTD_d_refMultipleDDicts:
1841             bounds.lowerBound = (int)ZSTD_rmd_refSingleDDict;
1842             bounds.upperBound = (int)ZSTD_rmd_refMultipleDDicts;
1843             return bounds;
1844         case ZSTD_d_disableHuffmanAssembly:
1845             bounds.lowerBound = 0;
1846             bounds.upperBound = 1;
1847             return bounds;
1848         case ZSTD_d_maxBlockSize:
1849             bounds.lowerBound = ZSTD_BLOCKSIZE_MAX_MIN;
1850             bounds.upperBound = ZSTD_BLOCKSIZE_MAX;
1851             return bounds;
1852
1853         default:;
1854     }
1855     bounds.error = ERROR(parameter_unsupported);
1856     return bounds;
1857 }
1858
1859 /* ZSTD_dParam_withinBounds:
1860  * @return 1 if value is within dParam bounds,
1861  * 0 otherwise */
1862 static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
1863 {
1864     ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam);
1865     if (ZSTD_isError(bounds.error)) return 0;
1866     if (value < bounds.lowerBound) return 0;
1867     if (value > bounds.upperBound) return 0;
1868     return 1;
1869 }
1870
1871 #define CHECK_DBOUNDS(p,v) {                \
1872     RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound, ""); \
1873 }
1874
1875 size_t ZSTD_DCtx_getParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int* value)
1876 {
1877     switch (param) {
1878         case ZSTD_d_windowLogMax:
1879             *value = (int)ZSTD_highbit32((U32)dctx->maxWindowSize);
1880             return 0;
1881         case ZSTD_d_format:
1882             *value = (int)dctx->format;
1883             return 0;
1884         case ZSTD_d_stableOutBuffer:
1885             *value = (int)dctx->outBufferMode;
1886             return 0;
1887         case ZSTD_d_forceIgnoreChecksum:
1888             *value = (int)dctx->forceIgnoreChecksum;
1889             return 0;
1890         case ZSTD_d_refMultipleDDicts:
1891             *value = (int)dctx->refMultipleDDicts;
1892             return 0;
1893         case ZSTD_d_disableHuffmanAssembly:
1894             *value = (int)dctx->disableHufAsm;
1895             return 0;
1896         case ZSTD_d_maxBlockSize:
1897             *value = dctx->maxBlockSizeParam;
1898             return 0;
1899         default:;
1900     }
1901     RETURN_ERROR(parameter_unsupported, "");
1902 }
1903
1904 size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
1905 {
1906     RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1907     switch(dParam) {
1908         case ZSTD_d_windowLogMax:
1909             if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
1910             CHECK_DBOUNDS(ZSTD_d_windowLogMax, value);
1911             dctx->maxWindowSize = ((size_t)1) << value;
1912             return 0;
1913         case ZSTD_d_format:
1914             CHECK_DBOUNDS(ZSTD_d_format, value);
1915             dctx->format = (ZSTD_format_e)value;
1916             return 0;
1917         case ZSTD_d_stableOutBuffer:
1918             CHECK_DBOUNDS(ZSTD_d_stableOutBuffer, value);
1919             dctx->outBufferMode = (ZSTD_bufferMode_e)value;
1920             return 0;
1921         case ZSTD_d_forceIgnoreChecksum:
1922             CHECK_DBOUNDS(ZSTD_d_forceIgnoreChecksum, value);
1923             dctx->forceIgnoreChecksum = (ZSTD_forceIgnoreChecksum_e)value;
1924             return 0;
1925         case ZSTD_d_refMultipleDDicts:
1926             CHECK_DBOUNDS(ZSTD_d_refMultipleDDicts, value);
1927             if (dctx->staticSize != 0) {
1928                 RETURN_ERROR(parameter_unsupported, "Static dctx does not support multiple DDicts!");
1929             }
1930             dctx->refMultipleDDicts = (ZSTD_refMultipleDDicts_e)value;
1931             return 0;
1932         case ZSTD_d_disableHuffmanAssembly:
1933             CHECK_DBOUNDS(ZSTD_d_disableHuffmanAssembly, value);
1934             dctx->disableHufAsm = value != 0;
1935             return 0;
1936         case ZSTD_d_maxBlockSize:
1937             if (value != 0) CHECK_DBOUNDS(ZSTD_d_maxBlockSize, value);
1938             dctx->maxBlockSizeParam = value;
1939             return 0;
1940         default:;
1941     }
1942     RETURN_ERROR(parameter_unsupported, "");
1943 }
1944
1945 size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
1946 {
1947     if ( (reset == ZSTD_reset_session_only)
1948       || (reset == ZSTD_reset_session_and_parameters) ) {
1949         dctx->streamStage = zdss_init;
1950         dctx->noForwardProgress = 0;
1951         dctx->isFrameDecompression = 1;
1952     }
1953     if ( (reset == ZSTD_reset_parameters)
1954       || (reset == ZSTD_reset_session_and_parameters) ) {
1955         RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong, "");
1956         ZSTD_clearDict(dctx);
1957         ZSTD_DCtx_resetParameters(dctx);
1958     }
1959     return 0;
1960 }
1961
1962
1963 size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
1964 {
1965     return ZSTD_sizeof_DCtx(dctx);
1966 }
1967
1968 static size_t ZSTD_decodingBufferSize_internal(unsigned long long windowSize, unsigned long long frameContentSize, size_t blockSizeMax)
1969 {
1970     size_t const blockSize = MIN((size_t)MIN(windowSize, ZSTD_BLOCKSIZE_MAX), blockSizeMax);
1971     /* We need blockSize + WILDCOPY_OVERLENGTH worth of buffer so that if a block
1972      * ends at windowSize + WILDCOPY_OVERLENGTH + 1 bytes, we can start writing
1973      * the block at the beginning of the output buffer, and maintain a full window.
1974      *
1975      * We need another blockSize worth of buffer so that we can store split
1976      * literals at the end of the block without overwriting the extDict window.
1977      */
1978     unsigned long long const neededRBSize = windowSize + (blockSize * 2) + (WILDCOPY_OVERLENGTH * 2);
1979     unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
1980     size_t const minRBSize = (size_t) neededSize;
1981     RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
1982                     frameParameter_windowTooLarge, "");
1983     return minRBSize;
1984 }
1985
1986 size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
1987 {
1988     return ZSTD_decodingBufferSize_internal(windowSize, frameContentSize, ZSTD_BLOCKSIZE_MAX);
1989 }
1990
1991 size_t ZSTD_estimateDStreamSize(size_t windowSize)
1992 {
1993     size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);
1994     size_t const inBuffSize = blockSize;  /* no block can be larger */
1995     size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);
1996     return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;
1997 }
1998
1999 size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
2000 {
2001     U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;   /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
2002     ZSTD_frameHeader zfh;
2003     size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
2004     if (ZSTD_isError(err)) return err;
2005     RETURN_ERROR_IF(err>0, srcSize_wrong, "");
2006     RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
2007                     frameParameter_windowTooLarge, "");
2008     return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
2009 }
2010
2011
2012 /* *****   Decompression   ***** */
2013
2014 static int ZSTD_DCtx_isOverflow(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
2015 {
2016     return (zds->inBuffSize + zds->outBuffSize) >= (neededInBuffSize + neededOutBuffSize) * ZSTD_WORKSPACETOOLARGE_FACTOR;
2017 }
2018
2019 static void ZSTD_DCtx_updateOversizedDuration(ZSTD_DStream* zds, size_t const neededInBuffSize, size_t const neededOutBuffSize)
2020 {
2021     if (ZSTD_DCtx_isOverflow(zds, neededInBuffSize, neededOutBuffSize))
2022         zds->oversizedDuration++;
2023     else
2024         zds->oversizedDuration = 0;
2025 }
2026
2027 static int ZSTD_DCtx_isOversizedTooLong(ZSTD_DStream* zds)
2028 {
2029     return zds->oversizedDuration >= ZSTD_WORKSPACETOOLARGE_MAXDURATION;
2030 }
2031
2032 /* Checks that the output buffer hasn't changed if ZSTD_obm_stable is used. */
2033 static size_t ZSTD_checkOutBuffer(ZSTD_DStream const* zds, ZSTD_outBuffer const* output)
2034 {
2035     ZSTD_outBuffer const expect = zds->expectedOutBuffer;
2036     /* No requirement when ZSTD_obm_stable is not enabled. */
2037     if (zds->outBufferMode != ZSTD_bm_stable)
2038         return 0;
2039     /* Any buffer is allowed in zdss_init, this must be the same for every other call until
2040      * the context is reset.
2041      */
2042     if (zds->streamStage == zdss_init)
2043         return 0;
2044     /* The buffer must match our expectation exactly. */
2045     if (expect.dst == output->dst && expect.pos == output->pos && expect.size == output->size)
2046         return 0;
2047     RETURN_ERROR(dstBuffer_wrong, "ZSTD_d_stableOutBuffer enabled but output differs!");
2048 }
2049
2050 /* Calls ZSTD_decompressContinue() with the right parameters for ZSTD_decompressStream()
2051  * and updates the stage and the output buffer state. This call is extracted so it can be
2052  * used both when reading directly from the ZSTD_inBuffer, and in buffered input mode.
2053  * NOTE: You must break after calling this function since the streamStage is modified.
2054  */
2055 static size_t ZSTD_decompressContinueStream(
2056             ZSTD_DStream* zds, char** op, char* oend,
2057             void const* src, size_t srcSize) {
2058     int const isSkipFrame = ZSTD_isSkipFrame(zds);
2059     if (zds->outBufferMode == ZSTD_bm_buffered) {
2060         size_t const dstSize = isSkipFrame ? 0 : zds->outBuffSize - zds->outStart;
2061         size_t const decodedSize = ZSTD_decompressContinue(zds,
2062                 zds->outBuff + zds->outStart, dstSize, src, srcSize);
2063         FORWARD_IF_ERROR(decodedSize, "");
2064         if (!decodedSize && !isSkipFrame) {
2065             zds->streamStage = zdss_read;
2066         } else {
2067             zds->outEnd = zds->outStart + decodedSize;
2068             zds->streamStage = zdss_flush;
2069         }
2070     } else {
2071         /* Write directly into the output buffer */
2072         size_t const dstSize = isSkipFrame ? 0 : (size_t)(oend - *op);
2073         size_t const decodedSize = ZSTD_decompressContinue(zds, *op, dstSize, src, srcSize);
2074         FORWARD_IF_ERROR(decodedSize, "");
2075         *op += decodedSize;
2076         /* Flushing is not needed. */
2077         zds->streamStage = zdss_read;
2078         assert(*op <= oend);
2079         assert(zds->outBufferMode == ZSTD_bm_stable);
2080     }
2081     return 0;
2082 }
2083
2084 size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
2085 {
2086     const char* const src = (const char*)input->src;
2087     const char* const istart = input->pos != 0 ? src + input->pos : src;
2088     const char* const iend = input->size != 0 ? src + input->size : src;
2089     const char* ip = istart;
2090     char* const dst = (char*)output->dst;
2091     char* const ostart = output->pos != 0 ? dst + output->pos : dst;
2092     char* const oend = output->size != 0 ? dst + output->size : dst;
2093     char* op = ostart;
2094     U32 someMoreWork = 1;
2095
2096     DEBUGLOG(5, "ZSTD_decompressStream");
2097     RETURN_ERROR_IF(
2098         input->pos > input->size,
2099         srcSize_wrong,
2100         "forbidden. in: pos: %u   vs size: %u",
2101         (U32)input->pos, (U32)input->size);
2102     RETURN_ERROR_IF(
2103         output->pos > output->size,
2104         dstSize_tooSmall,
2105         "forbidden. out: pos: %u   vs size: %u",
2106         (U32)output->pos, (U32)output->size);
2107     DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
2108     FORWARD_IF_ERROR(ZSTD_checkOutBuffer(zds, output), "");
2109
2110     while (someMoreWork) {
2111         switch(zds->streamStage)
2112         {
2113         case zdss_init :
2114             DEBUGLOG(5, "stage zdss_init => transparent reset ");
2115             zds->streamStage = zdss_loadHeader;
2116             zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
2117 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2118             zds->legacyVersion = 0;
2119 #endif
2120             zds->hostageByte = 0;
2121             zds->expectedOutBuffer = *output;
2122             ZSTD_FALLTHROUGH;
2123
2124         case zdss_loadHeader :
2125             DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
2126 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2127             if (zds->legacyVersion) {
2128                 RETURN_ERROR_IF(zds->staticSize, memory_allocation,
2129                     "legacy support is incompatible with static dctx");
2130                 {   size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
2131                     if (hint==0) zds->streamStage = zdss_init;
2132                     return hint;
2133             }   }
2134 #endif
2135             {   size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
2136                 if (zds->refMultipleDDicts && zds->ddictSet) {
2137                     ZSTD_DCtx_selectFrameDDict(zds);
2138                 }
2139                 if (ZSTD_isError(hSize)) {
2140 #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2141                     U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
2142                     if (legacyVersion) {
2143                         ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);
2144                         const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;
2145                         size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;
2146                         DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion);
2147                         RETURN_ERROR_IF(zds->staticSize, memory_allocation,
2148                             "legacy support is incompatible with static dctx");
2149                         FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
2150                                     zds->previousLegacyVersion, legacyVersion,
2151                                     dict, dictSize), "");
2152                         zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
2153                         {   size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
2154                             if (hint==0) zds->streamStage = zdss_init;   /* or stay in stage zdss_loadHeader */
2155                             return hint;
2156                     }   }
2157 #endif
2158                     return hSize;   /* error */
2159                 }
2160                 if (hSize != 0) {   /* need more input */
2161                     size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */
2162                     size_t const remainingInput = (size_t)(iend-ip);
2163                     assert(iend >= ip);
2164                     if (toLoad > remainingInput) {   /* not enough input to load full header */
2165                         if (remainingInput > 0) {
2166                             ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);
2167                             zds->lhSize += remainingInput;
2168                         }
2169                         input->pos = input->size;
2170                         /* check first few bytes */
2171                         FORWARD_IF_ERROR(
2172                             ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format),
2173                             "First few bytes detected incorrect" );
2174                         /* return hint input size */
2175                         return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize;   /* remaining header bytes + next block header */
2176                     }
2177                     assert(ip != NULL);
2178                     ZSTD_memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
2179                     break;
2180             }   }
2181
2182             /* check for single-pass mode opportunity */
2183             if (zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2184                 && zds->fParams.frameType != ZSTD_skippableFrame
2185                 && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
2186                 size_t const cSize = ZSTD_findFrameCompressedSize_advanced(istart, (size_t)(iend-istart), zds->format);
2187                 if (cSize <= (size_t)(iend-istart)) {
2188                     /* shortcut : using single-pass mode */
2189                     size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, (size_t)(oend-op), istart, cSize, ZSTD_getDDict(zds));
2190                     if (ZSTD_isError(decompressedSize)) return decompressedSize;
2191                     DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()");
2192                     assert(istart != NULL);
2193                     ip = istart + cSize;
2194                     op = op ? op + decompressedSize : op; /* can occur if frameContentSize = 0 (empty frame) */
2195                     zds->expected = 0;
2196                     zds->streamStage = zdss_init;
2197                     someMoreWork = 0;
2198                     break;
2199             }   }
2200
2201             /* Check output buffer is large enough for ZSTD_odm_stable. */
2202             if (zds->outBufferMode == ZSTD_bm_stable
2203                 && zds->fParams.frameType != ZSTD_skippableFrame
2204                 && zds->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
2205                 && (U64)(size_t)(oend-op) < zds->fParams.frameContentSize) {
2206                 RETURN_ERROR(dstSize_tooSmall, "ZSTD_obm_stable passed but ZSTD_outBuffer is too small");
2207             }
2208
2209             /* Consume header (see ZSTDds_decodeFrameHeader) */
2210             DEBUGLOG(4, "Consume header");
2211             FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)), "");
2212
2213             if (zds->format == ZSTD_f_zstd1
2214                 && (MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {  /* skippable frame */
2215                 zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
2216                 zds->stage = ZSTDds_skipFrame;
2217             } else {
2218                 FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize), "");
2219                 zds->expected = ZSTD_blockHeaderSize;
2220                 zds->stage = ZSTDds_decodeBlockHeader;
2221             }
2222
2223             /* control buffer memory usage */
2224             DEBUGLOG(4, "Control max memory usage (%u KB <= max %u KB)",
2225                         (U32)(zds->fParams.windowSize >>10),
2226                         (U32)(zds->maxWindowSize >> 10) );
2227             zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2228             RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
2229                             frameParameter_windowTooLarge, "");
2230             if (zds->maxBlockSizeParam != 0)
2231                 zds->fParams.blockSizeMax = MIN(zds->fParams.blockSizeMax, (unsigned)zds->maxBlockSizeParam);
2232
2233             /* Adapt buffer sizes to frame header instructions */
2234             {   size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
2235                 size_t const neededOutBuffSize = zds->outBufferMode == ZSTD_bm_buffered
2236                         ? ZSTD_decodingBufferSize_internal(zds->fParams.windowSize, zds->fParams.frameContentSize, zds->fParams.blockSizeMax)
2237                         : 0;
2238
2239                 ZSTD_DCtx_updateOversizedDuration(zds, neededInBuffSize, neededOutBuffSize);
2240
2241                 {   int const tooSmall = (zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize);
2242                     int const tooLarge = ZSTD_DCtx_isOversizedTooLong(zds);
2243
2244                     if (tooSmall || tooLarge) {
2245                         size_t const bufferSize = neededInBuffSize + neededOutBuffSize;
2246                         DEBUGLOG(4, "inBuff  : from %u to %u",
2247                                     (U32)zds->inBuffSize, (U32)neededInBuffSize);
2248                         DEBUGLOG(4, "outBuff : from %u to %u",
2249                                     (U32)zds->outBuffSize, (U32)neededOutBuffSize);
2250                         if (zds->staticSize) {  /* static DCtx */
2251                             DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
2252                             assert(zds->staticSize >= sizeof(ZSTD_DCtx));  /* controlled at init */
2253                             RETURN_ERROR_IF(
2254                                 bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
2255                                 memory_allocation, "");
2256                         } else {
2257                             ZSTD_customFree(zds->inBuff, zds->customMem);
2258                             zds->inBuffSize = 0;
2259                             zds->outBuffSize = 0;
2260                             zds->inBuff = (char*)ZSTD_customMalloc(bufferSize, zds->customMem);
2261                             RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation, "");
2262                         }
2263                         zds->inBuffSize = neededInBuffSize;
2264                         zds->outBuff = zds->inBuff + zds->inBuffSize;
2265                         zds->outBuffSize = neededOutBuffSize;
2266             }   }   }
2267             zds->streamStage = zdss_read;
2268             ZSTD_FALLTHROUGH;
2269
2270         case zdss_read:
2271             DEBUGLOG(5, "stage zdss_read");
2272             {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip));
2273                 DEBUGLOG(5, "neededInSize = %u", (U32)neededInSize);
2274                 if (neededInSize==0) {  /* end of frame */
2275                     zds->streamStage = zdss_init;
2276                     someMoreWork = 0;
2277                     break;
2278                 }
2279                 if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */
2280                     FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, ip, neededInSize), "");
2281                     assert(ip != NULL);
2282                     ip += neededInSize;
2283                     /* Function modifies the stage so we must break */
2284                     break;
2285             }   }
2286             if (ip==iend) { someMoreWork = 0; break; }   /* no more input */
2287             zds->streamStage = zdss_load;
2288             ZSTD_FALLTHROUGH;
2289
2290         case zdss_load:
2291             {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
2292                 size_t const toLoad = neededInSize - zds->inPos;
2293                 int const isSkipFrame = ZSTD_isSkipFrame(zds);
2294                 size_t loadedSize;
2295                 /* At this point we shouldn't be decompressing a block that we can stream. */
2296                 assert(neededInSize == ZSTD_nextSrcSizeToDecompressWithInputSize(zds, (size_t)(iend - ip)));
2297                 if (isSkipFrame) {
2298                     loadedSize = MIN(toLoad, (size_t)(iend-ip));
2299                 } else {
2300                     RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
2301                                     corruption_detected,
2302                                     "should never happen");
2303                     loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, (size_t)(iend-ip));
2304                 }
2305                 if (loadedSize != 0) {
2306                     /* ip may be NULL */
2307                     ip += loadedSize;
2308                     zds->inPos += loadedSize;
2309                 }
2310                 if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */
2311
2312                 /* decode loaded input */
2313                 zds->inPos = 0;   /* input is consumed */
2314                 FORWARD_IF_ERROR(ZSTD_decompressContinueStream(zds, &op, oend, zds->inBuff, neededInSize), "");
2315                 /* Function modifies the stage so we must break */
2316                 break;
2317             }
2318         case zdss_flush:
2319             {
2320                 size_t const toFlushSize = zds->outEnd - zds->outStart;
2321                 size_t const flushedSize = ZSTD_limitCopy(op, (size_t)(oend-op), zds->outBuff + zds->outStart, toFlushSize);
2322
2323                 op = op ? op + flushedSize : op;
2324
2325                 zds->outStart += flushedSize;
2326                 if (flushedSize == toFlushSize) {  /* flush completed */
2327                     zds->streamStage = zdss_read;
2328                     if ( (zds->outBuffSize < zds->fParams.frameContentSize)
2329                         && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {
2330                         DEBUGLOG(5, "restart filling outBuff from beginning (left:%i, needed:%u)",
2331                                 (int)(zds->outBuffSize - zds->outStart),
2332                                 (U32)zds->fParams.blockSizeMax);
2333                         zds->outStart = zds->outEnd = 0;
2334                     }
2335                     break;
2336             }   }
2337             /* cannot complete flush */
2338             someMoreWork = 0;
2339             break;
2340
2341         default:
2342             assert(0);    /* impossible */
2343             RETURN_ERROR(GENERIC, "impossible to reach");   /* some compilers require default to do something */
2344     }   }
2345
2346     /* result */
2347     input->pos = (size_t)(ip - (const char*)(input->src));
2348     output->pos = (size_t)(op - (char*)(output->dst));
2349
2350     /* Update the expected output buffer for ZSTD_obm_stable. */
2351     zds->expectedOutBuffer = *output;
2352
2353     if ((ip==istart) && (op==ostart)) {  /* no forward progress */
2354         zds->noForwardProgress ++;
2355         if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
2356             RETURN_ERROR_IF(op==oend, noForwardProgress_destFull, "");
2357             RETURN_ERROR_IF(ip==iend, noForwardProgress_inputEmpty, "");
2358             assert(0);
2359         }
2360     } else {
2361         zds->noForwardProgress = 0;
2362     }
2363     {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
2364         if (!nextSrcSizeHint) {   /* frame fully decoded */
2365             if (zds->outEnd == zds->outStart) {  /* output fully flushed */
2366                 if (zds->hostageByte) {
2367                     if (input->pos >= input->size) {
2368                         /* can't release hostage (not present) */
2369                         zds->streamStage = zdss_read;
2370                         return 1;
2371                     }
2372                     input->pos++;  /* release hostage */
2373                 }   /* zds->hostageByte */
2374                 return 0;
2375             }  /* zds->outEnd == zds->outStart */
2376             if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
2377                 input->pos--;   /* note : pos > 0, otherwise, impossible to finish reading last block */
2378                 zds->hostageByte=1;
2379             }
2380             return 1;
2381         }  /* nextSrcSizeHint==0 */
2382         nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block);   /* preload header of next block */
2383         assert(zds->inPos <= nextSrcSizeHint);
2384         nextSrcSizeHint -= zds->inPos;   /* part already loaded*/
2385         return nextSrcSizeHint;
2386     }
2387 }
2388
2389 size_t ZSTD_decompressStream_simpleArgs (
2390                             ZSTD_DCtx* dctx,
2391                             void* dst, size_t dstCapacity, size_t* dstPos,
2392                       const void* src, size_t srcSize, size_t* srcPos)
2393 {
2394     ZSTD_outBuffer output;
2395     ZSTD_inBuffer  input;
2396     output.dst = dst;
2397     output.size = dstCapacity;
2398     output.pos = *dstPos;
2399     input.src = src;
2400     input.size = srcSize;
2401     input.pos = *srcPos;
2402     {   size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
2403         *dstPos = output.pos;
2404         *srcPos = input.pos;
2405         return cErr;
2406     }
2407 }