Home | History | Annotate | Line # | Download | only in decompress
      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 }
   2408