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