zstdlib 0.12.0-x64-mingw32 → 0.13.0-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +7 -0
- data/Rakefile +1 -1
- data/ext/zstdlib_c/extconf.rb +1 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/allocations.h +1 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/bitstream.h +49 -29
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/compiler.h +114 -22
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/cpu.h +36 -0
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/debug.c +6 -0
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/debug.h +20 -11
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/error_private.h +45 -36
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/fse.h +3 -2
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/fse_decompress.c +19 -17
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/huf.h +14 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/mem.h +0 -9
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/pool.c +1 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/pool.h +1 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/portability_macros.h +2 -0
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/threading.c +8 -2
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/xxhash.c +5 -11
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/xxhash.h +2341 -1007
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/zstd_internal.h +5 -5
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/fse_compress.c +8 -7
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/huf_compress.c +54 -25
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress.c +282 -161
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_internal.h +29 -27
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_superblock.c +224 -113
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_cwksp.h +19 -13
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_double_fast.c +17 -5
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_double_fast.h +11 -0
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_fast.c +14 -6
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_lazy.c +129 -87
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_lazy.h +103 -28
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_ldm.c +8 -2
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_opt.c +216 -112
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_opt.h +31 -7
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstdmt_compress.c +94 -79
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/huf_decompress.c +188 -126
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/huf_decompress_amd64.S +38 -19
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_decompress.c +84 -32
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_decompress_block.c +231 -208
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_decompress_block.h +1 -1
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_decompress_internal.h +2 -0
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/zstd.h +129 -60
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzclose.c +1 -3
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzlib.c +20 -73
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzread.c +17 -58
- data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzwrite.c +18 -58
- data/lib/2.4/zstdlib_c.so +0 -0
- data/lib/2.5/zstdlib_c.so +0 -0
- data/lib/2.6/zstdlib_c.so +0 -0
- data/lib/2.7/zstdlib_c.so +0 -0
- data/lib/3.0/zstdlib_c.so +0 -0
- metadata +75 -75
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/bits.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/entropy_common.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/error_private.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/threading.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/zstd_common.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/zstd_deps.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/common/zstd_trace.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/clevels.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/hist.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/hist.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_literals.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_literals.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_sequences.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_sequences.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_compress_superblock.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_fast.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_ldm.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstd_ldm_geartab.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/compress/zstdmt_compress.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_ddict.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/decompress/zstd_ddict.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/zdict.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/lib/zstd_errors.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzcompatibility.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/gzguts.h +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/zstd_zlibwrapper.c +0 -0
- /data/ext/zstdlib_c/{zstd-1.5.5 → zstd-1.5.6}/zlibWrapper/zstd_zlibwrapper.h +0 -0
| @@ -51,6 +51,13 @@ static void ZSTD_copy4(void* dst, const void* src) { ZSTD_memcpy(dst, src, 4); } | |
| 51 51 | 
             
             *   Block decoding
         | 
| 52 52 | 
             
             ***************************************************************/
         | 
| 53 53 |  | 
| 54 | 
            +
            static size_t ZSTD_blockSizeMax(ZSTD_DCtx const* dctx)
         | 
| 55 | 
            +
            {
         | 
| 56 | 
            +
                size_t const blockSizeMax = dctx->isFrameDecompression ? dctx->fParams.blockSizeMax : ZSTD_BLOCKSIZE_MAX;
         | 
| 57 | 
            +
                assert(blockSizeMax <= ZSTD_BLOCKSIZE_MAX);
         | 
| 58 | 
            +
                return blockSizeMax;
         | 
| 59 | 
            +
            }
         | 
| 60 | 
            +
             | 
| 54 61 | 
             
            /*! ZSTD_getcBlockSize() :
         | 
| 55 62 | 
             
             *  Provides the size of compressed block from block header `src` */
         | 
| 56 63 | 
             
            size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
         | 
| @@ -73,41 +80,49 @@ size_t ZSTD_getcBlockSize(const void* src, size_t srcSize, | |
| 73 80 | 
             
            static void ZSTD_allocateLiteralsBuffer(ZSTD_DCtx* dctx, void* const dst, const size_t dstCapacity, const size_t litSize,
         | 
| 74 81 | 
             
                const streaming_operation streaming, const size_t expectedWriteSize, const unsigned splitImmediately)
         | 
| 75 82 | 
             
            {
         | 
| 76 | 
            -
                 | 
| 77 | 
            -
                 | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 83 | 
            +
                size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);
         | 
| 84 | 
            +
                assert(litSize <= blockSizeMax);
         | 
| 85 | 
            +
                assert(dctx->isFrameDecompression || streaming == not_streaming);
         | 
| 86 | 
            +
                assert(expectedWriteSize <= blockSizeMax);
         | 
| 87 | 
            +
                if (streaming == not_streaming && dstCapacity > blockSizeMax + WILDCOPY_OVERLENGTH + litSize + WILDCOPY_OVERLENGTH) {
         | 
| 88 | 
            +
                    /* If we aren't streaming, we can just put the literals after the output
         | 
| 89 | 
            +
                     * of the current block. We don't need to worry about overwriting the
         | 
| 90 | 
            +
                     * extDict of our window, because it doesn't exist.
         | 
| 91 | 
            +
                     * So if we have space after the end of the block, just put it there.
         | 
| 92 | 
            +
                     */
         | 
| 93 | 
            +
                    dctx->litBuffer = (BYTE*)dst + blockSizeMax + WILDCOPY_OVERLENGTH;
         | 
| 80 94 | 
             
                    dctx->litBufferEnd = dctx->litBuffer + litSize;
         | 
| 81 95 | 
             
                    dctx->litBufferLocation = ZSTD_in_dst;
         | 
| 82 | 
            -
                }
         | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 96 | 
            +
                } else if (litSize <= ZSTD_LITBUFFEREXTRASIZE) {
         | 
| 97 | 
            +
                    /* Literals fit entirely within the extra buffer, put them there to avoid
         | 
| 98 | 
            +
                     * having to split the literals.
         | 
| 99 | 
            +
                     */
         | 
| 100 | 
            +
                    dctx->litBuffer = dctx->litExtraBuffer;
         | 
| 101 | 
            +
                    dctx->litBufferEnd = dctx->litBuffer + litSize;
         | 
| 102 | 
            +
                    dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 103 | 
            +
                } else {
         | 
| 104 | 
            +
                    assert(blockSizeMax > ZSTD_LITBUFFEREXTRASIZE);
         | 
| 105 | 
            +
                    /* Literals must be split between the output block and the extra lit
         | 
| 106 | 
            +
                     * buffer. We fill the extra lit buffer with the tail of the literals,
         | 
| 107 | 
            +
                     * and put the rest of the literals at the end of the block, with
         | 
| 108 | 
            +
                     * WILDCOPY_OVERLENGTH of buffer room to allow for overreads.
         | 
| 109 | 
            +
                     * This MUST not write more than our maxBlockSize beyond dst, because in
         | 
| 110 | 
            +
                     * streaming mode, that could overwrite part of our extDict window.
         | 
| 111 | 
            +
                     */
         | 
| 86 112 | 
             
                    if (splitImmediately) {
         | 
| 87 113 | 
             
                        /* won't fit in litExtraBuffer, so it will be split between end of dst and extra buffer */
         | 
| 88 114 | 
             
                        dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
         | 
| 89 115 | 
             
                        dctx->litBufferEnd = dctx->litBuffer + litSize - ZSTD_LITBUFFEREXTRASIZE;
         | 
| 90 | 
            -
                    }
         | 
| 91 | 
            -
                    else {
         | 
| 116 | 
            +
                    } else {
         | 
| 92 117 | 
             
                        /* initially this will be stored entirely in dst during huffman decoding, it will partially be shifted to litExtraBuffer after */
         | 
| 93 118 | 
             
                        dctx->litBuffer = (BYTE*)dst + expectedWriteSize - litSize;
         | 
| 94 119 | 
             
                        dctx->litBufferEnd = (BYTE*)dst + expectedWriteSize;
         | 
| 95 120 | 
             
                    }
         | 
| 96 121 | 
             
                    dctx->litBufferLocation = ZSTD_split;
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                else
         | 
| 99 | 
            -
                {
         | 
| 100 | 
            -
                    /* fits entirely within litExtraBuffer, so no split is necessary */
         | 
| 101 | 
            -
                    dctx->litBuffer = dctx->litExtraBuffer;
         | 
| 102 | 
            -
                    dctx->litBufferEnd = dctx->litBuffer + litSize;
         | 
| 103 | 
            -
                    dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 122 | 
            +
                    assert(dctx->litBufferEnd <= (BYTE*)dst + expectedWriteSize);
         | 
| 104 123 | 
             
                }
         | 
| 105 124 | 
             
            }
         | 
| 106 125 |  | 
| 107 | 
            -
            /* Hidden declaration for fullbench */
         | 
| 108 | 
            -
            size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
         | 
| 109 | 
            -
                                      const void* src, size_t srcSize,
         | 
| 110 | 
            -
                                      void* dst, size_t dstCapacity, const streaming_operation streaming);
         | 
| 111 126 | 
             
            /*! ZSTD_decodeLiteralsBlock() :
         | 
| 112 127 | 
             
             * Where it is possible to do so without being stomped by the output during decompression, the literals block will be stored
         | 
| 113 128 | 
             
             * in the dstBuffer.  If there is room to do so, it will be stored in full in the excess dst space after where the current
         | 
| @@ -116,7 +131,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 116 131 | 
             
             *
         | 
| 117 132 | 
             
             * @return : nb of bytes read from src (< srcSize )
         | 
| 118 133 | 
             
             *  note : symbol not declared but exposed for fullbench */
         | 
| 119 | 
            -
            size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
         | 
| 134 | 
            +
            static size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
         | 
| 120 135 | 
             
                                      const void* src, size_t srcSize,   /* note : srcSize < BLOCKSIZE */
         | 
| 121 136 | 
             
                                      void* dst, size_t dstCapacity, const streaming_operation streaming)
         | 
| 122 137 | 
             
            {
         | 
| @@ -125,6 +140,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 125 140 |  | 
| 126 141 | 
             
                {   const BYTE* const istart = (const BYTE*) src;
         | 
| 127 142 | 
             
                    symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
         | 
| 143 | 
            +
                    size_t const blockSizeMax = ZSTD_blockSizeMax(dctx);
         | 
| 128 144 |  | 
| 129 145 | 
             
                    switch(litEncType)
         | 
| 130 146 | 
             
                    {
         | 
| @@ -140,7 +156,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 140 156 | 
             
                            U32 const lhlCode = (istart[0] >> 2) & 3;
         | 
| 141 157 | 
             
                            U32 const lhc = MEM_readLE32(istart);
         | 
| 142 158 | 
             
                            size_t hufSuccess;
         | 
| 143 | 
            -
                            size_t expectedWriteSize = MIN( | 
| 159 | 
            +
                            size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
         | 
| 144 160 | 
             
                            int const flags = 0
         | 
| 145 161 | 
             
                                | (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)
         | 
| 146 162 | 
             
                                | (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);
         | 
| @@ -167,7 +183,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 167 183 | 
             
                                break;
         | 
| 168 184 | 
             
                            }
         | 
| 169 185 | 
             
                            RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
         | 
| 170 | 
            -
                            RETURN_ERROR_IF(litSize >  | 
| 186 | 
            +
                            RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
         | 
| 171 187 | 
             
                            if (!singleStream)
         | 
| 172 188 | 
             
                                RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
         | 
| 173 189 | 
             
                                    "Not enough literals (%zu) for the 4-streams mode (min %u)",
         | 
| @@ -214,10 +230,12 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 214 230 | 
             
                            }
         | 
| 215 231 | 
             
                            if (dctx->litBufferLocation == ZSTD_split)
         | 
| 216 232 | 
             
                            {
         | 
| 233 | 
            +
                                assert(litSize > ZSTD_LITBUFFEREXTRASIZE);
         | 
| 217 234 | 
             
                                ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
         | 
| 218 235 | 
             
                                ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
         | 
| 219 236 | 
             
                                dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
         | 
| 220 237 | 
             
                                dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
         | 
| 238 | 
            +
                                assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax);
         | 
| 221 239 | 
             
                            }
         | 
| 222 240 |  | 
| 223 241 | 
             
                            RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
         | 
| @@ -232,7 +250,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 232 250 | 
             
                    case set_basic:
         | 
| 233 251 | 
             
                        {   size_t litSize, lhSize;
         | 
| 234 252 | 
             
                            U32 const lhlCode = ((istart[0]) >> 2) & 3;
         | 
| 235 | 
            -
                            size_t expectedWriteSize = MIN( | 
| 253 | 
            +
                            size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
         | 
| 236 254 | 
             
                            switch(lhlCode)
         | 
| 237 255 | 
             
                            {
         | 
| 238 256 | 
             
                            case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
         | 
| @@ -251,6 +269,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 251 269 | 
             
                            }
         | 
| 252 270 |  | 
| 253 271 | 
             
                            RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
         | 
| 272 | 
            +
                            RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
         | 
| 254 273 | 
             
                            RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
         | 
| 255 274 | 
             
                            ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
         | 
| 256 275 | 
             
                            if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */
         | 
| @@ -279,7 +298,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 279 298 | 
             
                    case set_rle:
         | 
| 280 299 | 
             
                        {   U32 const lhlCode = ((istart[0]) >> 2) & 3;
         | 
| 281 300 | 
             
                            size_t litSize, lhSize;
         | 
| 282 | 
            -
                            size_t expectedWriteSize = MIN( | 
| 301 | 
            +
                            size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
         | 
| 283 302 | 
             
                            switch(lhlCode)
         | 
| 284 303 | 
             
                            {
         | 
| 285 304 | 
             
                            case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */
         | 
| @@ -298,7 +317,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 298 317 | 
             
                                break;
         | 
| 299 318 | 
             
                            }
         | 
| 300 319 | 
             
                            RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
         | 
| 301 | 
            -
                            RETURN_ERROR_IF(litSize >  | 
| 320 | 
            +
                            RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
         | 
| 302 321 | 
             
                            RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
         | 
| 303 322 | 
             
                            ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
         | 
| 304 323 | 
             
                            if (dctx->litBufferLocation == ZSTD_split)
         | 
| @@ -320,6 +339,18 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx, | |
| 320 339 | 
             
                }
         | 
| 321 340 | 
             
            }
         | 
| 322 341 |  | 
| 342 | 
            +
            /* Hidden declaration for fullbench */
         | 
| 343 | 
            +
            size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
         | 
| 344 | 
            +
                                      const void* src, size_t srcSize,
         | 
| 345 | 
            +
                                      void* dst, size_t dstCapacity);
         | 
| 346 | 
            +
            size_t ZSTD_decodeLiteralsBlock_wrapper(ZSTD_DCtx* dctx,
         | 
| 347 | 
            +
                                      const void* src, size_t srcSize,
         | 
| 348 | 
            +
                                      void* dst, size_t dstCapacity)
         | 
| 349 | 
            +
            {
         | 
| 350 | 
            +
                dctx->isFrameDecompression = 0;
         | 
| 351 | 
            +
                return ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, not_streaming);
         | 
| 352 | 
            +
            }
         | 
| 353 | 
            +
             | 
| 323 354 | 
             
            /* Default FSE distribution tables.
         | 
| 324 355 | 
             
             * These are pre-calculated FSE decoding tables using default distributions as defined in specification :
         | 
| 325 356 | 
             
             * https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
         | 
| @@ -675,11 +706,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, | |
| 675 706 |  | 
| 676 707 | 
             
                /* SeqHead */
         | 
| 677 708 | 
             
                nbSeq = *ip++;
         | 
| 678 | 
            -
                if (!nbSeq) {
         | 
| 679 | 
            -
                    *nbSeqPtr=0;
         | 
| 680 | 
            -
                    RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
         | 
| 681 | 
            -
                    return 1;
         | 
| 682 | 
            -
                }
         | 
| 683 709 | 
             
                if (nbSeq > 0x7F) {
         | 
| 684 710 | 
             
                    if (nbSeq == 0xFF) {
         | 
| 685 711 | 
             
                        RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
         | 
| @@ -692,8 +718,16 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr, | |
| 692 718 | 
             
                }
         | 
| 693 719 | 
             
                *nbSeqPtr = nbSeq;
         | 
| 694 720 |  | 
| 721 | 
            +
                if (nbSeq == 0) {
         | 
| 722 | 
            +
                    /* No sequence : section ends immediately */
         | 
| 723 | 
            +
                    RETURN_ERROR_IF(ip != iend, corruption_detected,
         | 
| 724 | 
            +
                        "extraneous data present in the Sequences section");
         | 
| 725 | 
            +
                    return (size_t)(ip - istart);
         | 
| 726 | 
            +
                }
         | 
| 727 | 
            +
             | 
| 695 728 | 
             
                /* FSE table descriptors */
         | 
| 696 729 | 
             
                RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
         | 
| 730 | 
            +
                RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */
         | 
| 697 731 | 
             
                {   symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
         | 
| 698 732 | 
             
                    symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
         | 
| 699 733 | 
             
                    symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
         | 
| @@ -840,7 +874,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt | |
| 840 874 | 
             
            /* ZSTD_safecopyDstBeforeSrc():
         | 
| 841 875 | 
             
             * This version allows overlap with dst before src, or handles the non-overlap case with dst after src
         | 
| 842 876 | 
             
             * Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
         | 
| 843 | 
            -
            static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE | 
| 877 | 
            +
            static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) {
         | 
| 844 878 | 
             
                ptrdiff_t const diff = op - ip;
         | 
| 845 879 | 
             
                BYTE* const oend = op + length;
         | 
| 846 880 |  | 
| @@ -869,6 +903,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length | |
| 869 903 | 
             
             * to be optimized for many small sequences, since those fall into ZSTD_execSequence().
         | 
| 870 904 | 
             
             */
         | 
| 871 905 | 
             
            FORCE_NOINLINE
         | 
| 906 | 
            +
            ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
         | 
| 872 907 | 
             
            size_t ZSTD_execSequenceEnd(BYTE* op,
         | 
| 873 908 | 
             
                BYTE* const oend, seq_t sequence,
         | 
| 874 909 | 
             
                const BYTE** litPtr, const BYTE* const litLimit,
         | 
| @@ -916,6 +951,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op, | |
| 916 951 | 
             
             * This version is intended to be used during instances where the litBuffer is still split.  It is kept separate to avoid performance impact for the good case.
         | 
| 917 952 | 
             
             */
         | 
| 918 953 | 
             
            FORCE_NOINLINE
         | 
| 954 | 
            +
            ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
         | 
| 919 955 | 
             
            size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
         | 
| 920 956 | 
             
                BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
         | 
| 921 957 | 
             
                const BYTE** litPtr, const BYTE* const litLimit,
         | 
| @@ -961,6 +997,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op, | |
| 961 997 | 
             
            }
         | 
| 962 998 |  | 
| 963 999 | 
             
            HINT_INLINE
         | 
| 1000 | 
            +
            ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
         | 
| 964 1001 | 
             
            size_t ZSTD_execSequence(BYTE* op,
         | 
| 965 1002 | 
             
                BYTE* const oend, seq_t sequence,
         | 
| 966 1003 | 
             
                const BYTE** litPtr, const BYTE* const litLimit,
         | 
| @@ -1059,6 +1096,7 @@ size_t ZSTD_execSequence(BYTE* op, | |
| 1059 1096 | 
             
            }
         | 
| 1060 1097 |  | 
| 1061 1098 | 
             
            HINT_INLINE
         | 
| 1099 | 
            +
            ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
         | 
| 1062 1100 | 
             
            size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
         | 
| 1063 1101 | 
             
                BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
         | 
| 1064 1102 | 
             
                const BYTE** litPtr, const BYTE* const litLimit,
         | 
| @@ -1181,14 +1219,20 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16 | |
| 1181 1219 |  | 
| 1182 1220 | 
             
            typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
         | 
| 1183 1221 |  | 
| 1222 | 
            +
            /**
         | 
| 1223 | 
            +
             * ZSTD_decodeSequence():
         | 
| 1224 | 
            +
             * @p longOffsets : tells the decoder to reload more bit while decoding large offsets
         | 
| 1225 | 
            +
             *                  only used in 32-bit mode
         | 
| 1226 | 
            +
             * @return : Sequence (litL + matchL + offset)
         | 
| 1227 | 
            +
             */
         | 
| 1184 1228 | 
             
            FORCE_INLINE_TEMPLATE seq_t
         | 
| 1185 | 
            -
            ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
         | 
| 1229 | 
            +
            ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
         | 
| 1186 1230 | 
             
            {
         | 
| 1187 1231 | 
             
                seq_t seq;
         | 
| 1188 1232 | 
             
                /*
         | 
| 1189 | 
            -
                 * ZSTD_seqSymbol is a  | 
| 1190 | 
            -
                 * loaded in one operation | 
| 1191 | 
            -
                 * bit-extracting on aarch64.
         | 
| 1233 | 
            +
                 * ZSTD_seqSymbol is a 64 bits wide structure.
         | 
| 1234 | 
            +
                 * It can be loaded in one operation
         | 
| 1235 | 
            +
                 * and its fields extracted by simply shifting or bit-extracting on aarch64.
         | 
| 1192 1236 | 
             
                 * GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh
         | 
| 1193 1237 | 
             
                 * operations that cause performance drop. This can be avoided by using this
         | 
| 1194 1238 | 
             
                 * ZSTD_memcpy hack.
         | 
| @@ -1261,7 +1305,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) | |
| 1261 1305 | 
             
                            } else {
         | 
| 1262 1306 | 
             
                                offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
         | 
| 1263 1307 | 
             
                                {   size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
         | 
| 1264 | 
            -
                                    temp  | 
| 1308 | 
            +
                                    temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */
         | 
| 1265 1309 | 
             
                                    if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
         | 
| 1266 1310 | 
             
                                    seqState->prevOffset[1] = seqState->prevOffset[0];
         | 
| 1267 1311 | 
             
                                    seqState->prevOffset[0] = offset = temp;
         | 
| @@ -1288,17 +1332,22 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets) | |
| 1288 1332 | 
             
                    DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
         | 
| 1289 1333 | 
             
                                (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
         | 
| 1290 1334 |  | 
| 1291 | 
            -
                     | 
| 1292 | 
            -
             | 
| 1293 | 
            -
             | 
| 1294 | 
            -
             | 
| 1335 | 
            +
                    if (!isLastSeq) {
         | 
| 1336 | 
            +
                        /* don't update FSE state for last Sequence */
         | 
| 1337 | 
            +
                        ZSTD_updateFseStateWithDInfo(&seqState->stateLL, &seqState->DStream, llNext, llnbBits);    /* <=  9 bits */
         | 
| 1338 | 
            +
                        ZSTD_updateFseStateWithDInfo(&seqState->stateML, &seqState->DStream, mlNext, mlnbBits);    /* <=  9 bits */
         | 
| 1339 | 
            +
                        if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */
         | 
| 1340 | 
            +
                        ZSTD_updateFseStateWithDInfo(&seqState->stateOffb, &seqState->DStream, ofNext, ofnbBits);  /* <=  8 bits */
         | 
| 1341 | 
            +
                        BIT_reloadDStream(&seqState->DStream);
         | 
| 1342 | 
            +
                    }
         | 
| 1295 1343 | 
             
                }
         | 
| 1296 1344 |  | 
| 1297 1345 | 
             
                return seq;
         | 
| 1298 1346 | 
             
            }
         | 
| 1299 1347 |  | 
| 1300 | 
            -
            # | 
| 1301 | 
            -
             | 
| 1348 | 
            +
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1349 | 
            +
            #if DEBUGLEVEL >= 1
         | 
| 1350 | 
            +
            static int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefixStart, BYTE const* oLitEnd)
         | 
| 1302 1351 | 
             
            {
         | 
| 1303 1352 | 
             
                size_t const windowSize = dctx->fParams.windowSize;
         | 
| 1304 1353 | 
             
                /* No dictionary used. */
         | 
| @@ -1312,30 +1361,33 @@ MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefix | |
| 1312 1361 | 
             
                /* Dictionary is active. */
         | 
| 1313 1362 | 
             
                return 1;
         | 
| 1314 1363 | 
             
            }
         | 
| 1364 | 
            +
            #endif
         | 
| 1315 1365 |  | 
| 1316 | 
            -
             | 
| 1366 | 
            +
            static void ZSTD_assertValidSequence(
         | 
| 1317 1367 | 
             
                    ZSTD_DCtx const* dctx,
         | 
| 1318 1368 | 
             
                    BYTE const* op, BYTE const* oend,
         | 
| 1319 1369 | 
             
                    seq_t const seq,
         | 
| 1320 1370 | 
             
                    BYTE const* prefixStart, BYTE const* virtualStart)
         | 
| 1321 1371 | 
             
            {
         | 
| 1322 1372 | 
             
            #if DEBUGLEVEL >= 1
         | 
| 1323 | 
            -
                 | 
| 1324 | 
            -
             | 
| 1325 | 
            -
             | 
| 1326 | 
            -
             | 
| 1327 | 
            -
             | 
| 1328 | 
            -
             | 
| 1329 | 
            -
             | 
| 1330 | 
            -
             | 
| 1331 | 
            -
             | 
| 1332 | 
            -
                     | 
| 1333 | 
            -
             | 
| 1334 | 
            -
             | 
| 1335 | 
            -
             | 
| 1336 | 
            -
             | 
| 1337 | 
            -
                     | 
| 1338 | 
            -
             | 
| 1373 | 
            +
                if (dctx->isFrameDecompression) {
         | 
| 1374 | 
            +
                    size_t const windowSize = dctx->fParams.windowSize;
         | 
| 1375 | 
            +
                    size_t const sequenceSize = seq.litLength + seq.matchLength;
         | 
| 1376 | 
            +
                    BYTE const* const oLitEnd = op + seq.litLength;
         | 
| 1377 | 
            +
                    DEBUGLOG(6, "Checking sequence: litL=%u matchL=%u offset=%u",
         | 
| 1378 | 
            +
                            (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
         | 
| 1379 | 
            +
                    assert(op <= oend);
         | 
| 1380 | 
            +
                    assert((size_t)(oend - op) >= sequenceSize);
         | 
| 1381 | 
            +
                    assert(sequenceSize <= ZSTD_blockSizeMax(dctx));
         | 
| 1382 | 
            +
                    if (ZSTD_dictionaryIsActive(dctx, prefixStart, oLitEnd)) {
         | 
| 1383 | 
            +
                        size_t const dictSize = (size_t)((char const*)dctx->dictContentEndForFuzzing - (char const*)dctx->dictContentBeginForFuzzing);
         | 
| 1384 | 
            +
                        /* Offset must be within the dictionary. */
         | 
| 1385 | 
            +
                        assert(seq.offset <= (size_t)(oLitEnd - virtualStart));
         | 
| 1386 | 
            +
                        assert(seq.offset <= windowSize + dictSize);
         | 
| 1387 | 
            +
                    } else {
         | 
| 1388 | 
            +
                        /* Offset must be within our window. */
         | 
| 1389 | 
            +
                        assert(seq.offset <= windowSize);
         | 
| 1390 | 
            +
                    }
         | 
| 1339 1391 | 
             
                }
         | 
| 1340 1392 | 
             
            #else
         | 
| 1341 1393 | 
             
                (void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
         | 
| @@ -1351,23 +1403,21 @@ DONT_VECTORIZE | |
| 1351 1403 | 
             
            ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
         | 
| 1352 1404 | 
             
                                           void* dst, size_t maxDstSize,
         | 
| 1353 1405 | 
             
                                     const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1354 | 
            -
                                     const ZSTD_longOffset_e isLongOffset | 
| 1355 | 
            -
                                     const int frame)
         | 
| 1406 | 
            +
                                     const ZSTD_longOffset_e isLongOffset)
         | 
| 1356 1407 | 
             
            {
         | 
| 1357 1408 | 
             
                const BYTE* ip = (const BYTE*)seqStart;
         | 
| 1358 1409 | 
             
                const BYTE* const iend = ip + seqSize;
         | 
| 1359 1410 | 
             
                BYTE* const ostart = (BYTE*)dst;
         | 
| 1360 | 
            -
                BYTE* const oend = ostart  | 
| 1411 | 
            +
                BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
         | 
| 1361 1412 | 
             
                BYTE* op = ostart;
         | 
| 1362 1413 | 
             
                const BYTE* litPtr = dctx->litPtr;
         | 
| 1363 1414 | 
             
                const BYTE* litBufferEnd = dctx->litBufferEnd;
         | 
| 1364 1415 | 
             
                const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
         | 
| 1365 1416 | 
             
                const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
         | 
| 1366 1417 | 
             
                const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
         | 
| 1367 | 
            -
                DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
         | 
| 1368 | 
            -
                (void)frame;
         | 
| 1418 | 
            +
                DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq);
         | 
| 1369 1419 |  | 
| 1370 | 
            -
                /*  | 
| 1420 | 
            +
                /* Literals are split between internal buffer & output buffer */
         | 
| 1371 1421 | 
             
                if (nbSeq) {
         | 
| 1372 1422 | 
             
                    seqState_t seqState;
         | 
| 1373 1423 | 
             
                    dctx->fseEntropy = 1;
         | 
| @@ -1386,8 +1436,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, | |
| 1386 1436 | 
             
                            BIT_DStream_completed < BIT_DStream_overflow);
         | 
| 1387 1437 |  | 
| 1388 1438 | 
             
                    /* decompress without overrunning litPtr begins */
         | 
| 1389 | 
            -
                    {
         | 
| 1390 | 
            -
                        seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1439 | 
            +
                    {   seq_t sequence = {0,0,0};  /* some static analyzer believe that @sequence is not initialized (it necessarily is, since for(;;) loop as at least one iteration) */
         | 
| 1391 1440 | 
             
                        /* Align the decompression loop to 32 + 16 bytes.
         | 
| 1392 1441 | 
             
                            *
         | 
| 1393 1442 | 
             
                            * zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
         | 
| @@ -1449,27 +1498,26 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, | |
| 1449 1498 | 
             
            #endif
         | 
| 1450 1499 |  | 
| 1451 1500 | 
             
                        /* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
         | 
| 1452 | 
            -
                        for (;  | 
| 1453 | 
            -
                             | 
| 1501 | 
            +
                        for ( ; nbSeq; nbSeq--) {
         | 
| 1502 | 
            +
                            sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
         | 
| 1503 | 
            +
                            if (litPtr + sequence.litLength > dctx->litBufferEnd) break;
         | 
| 1504 | 
            +
                            {   size_t const oneSeqSize = ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequence.litLength - WILDCOPY_OVERLENGTH, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
         | 
| 1454 1505 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1455 | 
            -
             | 
| 1456 | 
            -
             | 
| 1506 | 
            +
                                assert(!ZSTD_isError(oneSeqSize));
         | 
| 1507 | 
            +
                                ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
         | 
| 1457 1508 | 
             
            #endif
         | 
| 1458 | 
            -
             | 
| 1459 | 
            -
             | 
| 1460 | 
            -
             | 
| 1461 | 
            -
             | 
| 1462 | 
            -
             | 
| 1463 | 
            -
             | 
| 1464 | 
            -
                            BIT_reloadDStream(&(seqState.DStream));
         | 
| 1465 | 
            -
                            sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1466 | 
            -
                        }
         | 
| 1509 | 
            +
                                if (UNLIKELY(ZSTD_isError(oneSeqSize)))
         | 
| 1510 | 
            +
                                    return oneSeqSize;
         | 
| 1511 | 
            +
                                DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
         | 
| 1512 | 
            +
                                op += oneSeqSize;
         | 
| 1513 | 
            +
                        }   }
         | 
| 1514 | 
            +
                        DEBUGLOG(6, "reached: (litPtr + sequence.litLength > dctx->litBufferEnd)");
         | 
| 1467 1515 |  | 
| 1468 1516 | 
             
                        /* If there are more sequences, they will need to read literals from litExtraBuffer; copy over the remainder from dst and update litPtr and litEnd */
         | 
| 1469 1517 | 
             
                        if (nbSeq > 0) {
         | 
| 1470 1518 | 
             
                            const size_t leftoverLit = dctx->litBufferEnd - litPtr;
         | 
| 1471 | 
            -
                             | 
| 1472 | 
            -
                            {
         | 
| 1519 | 
            +
                            DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
         | 
| 1520 | 
            +
                            if (leftoverLit) {
         | 
| 1473 1521 | 
             
                                RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
         | 
| 1474 1522 | 
             
                                ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
         | 
| 1475 1523 | 
             
                                sequence.litLength -= leftoverLit;
         | 
| @@ -1478,24 +1526,22 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, | |
| 1478 1526 | 
             
                            litPtr = dctx->litExtraBuffer;
         | 
| 1479 1527 | 
             
                            litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
         | 
| 1480 1528 | 
             
                            dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 1481 | 
            -
                            {
         | 
| 1482 | 
            -
                                size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
         | 
| 1529 | 
            +
                            {   size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
         | 
| 1483 1530 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1484 1531 | 
             
                                assert(!ZSTD_isError(oneSeqSize));
         | 
| 1485 | 
            -
                                 | 
| 1532 | 
            +
                                ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
         | 
| 1486 1533 | 
             
            #endif
         | 
| 1487 1534 | 
             
                                if (UNLIKELY(ZSTD_isError(oneSeqSize)))
         | 
| 1488 1535 | 
             
                                    return oneSeqSize;
         | 
| 1489 1536 | 
             
                                DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
         | 
| 1490 1537 | 
             
                                op += oneSeqSize;
         | 
| 1491 | 
            -
                                if (--nbSeq)
         | 
| 1492 | 
            -
                                    BIT_reloadDStream(&(seqState.DStream));
         | 
| 1493 1538 | 
             
                            }
         | 
| 1539 | 
            +
                            nbSeq--;
         | 
| 1494 1540 | 
             
                        }
         | 
| 1495 1541 | 
             
                    }
         | 
| 1496 1542 |  | 
| 1497 | 
            -
                    if (nbSeq > 0)  | 
| 1498 | 
            -
             | 
| 1543 | 
            +
                    if (nbSeq > 0) {
         | 
| 1544 | 
            +
                        /* there is remaining lit from extra buffer */
         | 
| 1499 1545 |  | 
| 1500 1546 | 
             
            #if defined(__GNUC__) && defined(__x86_64__)
         | 
| 1501 1547 | 
             
                        __asm__(".p2align 6");
         | 
| @@ -1514,35 +1560,34 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, | |
| 1514 1560 | 
             
            #  endif
         | 
| 1515 1561 | 
             
            #endif
         | 
| 1516 1562 |  | 
| 1517 | 
            -
                        for (; ; ) {
         | 
| 1518 | 
            -
                            seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1563 | 
            +
                        for ( ; nbSeq ; nbSeq--) {
         | 
| 1564 | 
            +
                            seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
         | 
| 1519 1565 | 
             
                            size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
         | 
| 1520 1566 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1521 1567 | 
             
                            assert(!ZSTD_isError(oneSeqSize));
         | 
| 1522 | 
            -
                             | 
| 1568 | 
            +
                            ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
         | 
| 1523 1569 | 
             
            #endif
         | 
| 1524 1570 | 
             
                            if (UNLIKELY(ZSTD_isError(oneSeqSize)))
         | 
| 1525 1571 | 
             
                                return oneSeqSize;
         | 
| 1526 1572 | 
             
                            DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
         | 
| 1527 1573 | 
             
                            op += oneSeqSize;
         | 
| 1528 | 
            -
                            if (UNLIKELY(!--nbSeq))
         | 
| 1529 | 
            -
                                break;
         | 
| 1530 | 
            -
                            BIT_reloadDStream(&(seqState.DStream));
         | 
| 1531 1574 | 
             
                        }
         | 
| 1532 1575 | 
             
                    }
         | 
| 1533 1576 |  | 
| 1534 1577 | 
             
                    /* check if reached exact end */
         | 
| 1535 1578 | 
             
                    DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
         | 
| 1536 1579 | 
             
                    RETURN_ERROR_IF(nbSeq, corruption_detected, "");
         | 
| 1537 | 
            -
                     | 
| 1580 | 
            +
                    DEBUGLOG(5, "bitStream : start=%p, ptr=%p, bitsConsumed=%u", seqState.DStream.start, seqState.DStream.ptr, seqState.DStream.bitsConsumed);
         | 
| 1581 | 
            +
                    RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
         | 
| 1538 1582 | 
             
                    /* save reps for next block */
         | 
| 1539 1583 | 
             
                    { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
         | 
| 1540 1584 | 
             
                }
         | 
| 1541 1585 |  | 
| 1542 1586 | 
             
                /* last literal segment */
         | 
| 1543 | 
            -
                if (dctx->litBufferLocation == ZSTD_split) | 
| 1544 | 
            -
             | 
| 1545 | 
            -
                    size_t const lastLLSize = litBufferEnd - litPtr;
         | 
| 1587 | 
            +
                if (dctx->litBufferLocation == ZSTD_split) {
         | 
| 1588 | 
            +
                    /* split hasn't been reached yet, first get dst then copy litExtraBuffer */
         | 
| 1589 | 
            +
                    size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
         | 
| 1590 | 
            +
                    DEBUGLOG(6, "copy last literals from segment : %u", (U32)lastLLSize);
         | 
| 1546 1591 | 
             
                    RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
         | 
| 1547 1592 | 
             
                    if (op != NULL) {
         | 
| 1548 1593 | 
             
                        ZSTD_memmove(op, litPtr, lastLLSize);
         | 
| @@ -1552,15 +1597,17 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx, | |
| 1552 1597 | 
             
                    litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
         | 
| 1553 1598 | 
             
                    dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 1554 1599 | 
             
                }
         | 
| 1555 | 
            -
                 | 
| 1600 | 
            +
                /* copy last literals from internal buffer */
         | 
| 1601 | 
            +
                {   size_t const lastLLSize = (size_t)(litBufferEnd - litPtr);
         | 
| 1602 | 
            +
                    DEBUGLOG(6, "copy last literals from internal buffer : %u", (U32)lastLLSize);
         | 
| 1556 1603 | 
             
                    RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
         | 
| 1557 1604 | 
             
                    if (op != NULL) {
         | 
| 1558 1605 | 
             
                        ZSTD_memcpy(op, litPtr, lastLLSize);
         | 
| 1559 1606 | 
             
                        op += lastLLSize;
         | 
| 1560 | 
            -
             | 
| 1561 | 
            -
                }
         | 
| 1607 | 
            +
                }   }
         | 
| 1562 1608 |  | 
| 1563 | 
            -
                 | 
| 1609 | 
            +
                DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
         | 
| 1610 | 
            +
                return (size_t)(op - ostart);
         | 
| 1564 1611 | 
             
            }
         | 
| 1565 1612 |  | 
| 1566 1613 | 
             
            FORCE_INLINE_TEMPLATE size_t
         | 
| @@ -1568,13 +1615,12 @@ DONT_VECTORIZE | |
| 1568 1615 | 
             
            ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
         | 
| 1569 1616 | 
             
                void* dst, size_t maxDstSize,
         | 
| 1570 1617 | 
             
                const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1571 | 
            -
                const ZSTD_longOffset_e isLongOffset | 
| 1572 | 
            -
                const int frame)
         | 
| 1618 | 
            +
                const ZSTD_longOffset_e isLongOffset)
         | 
| 1573 1619 | 
             
            {
         | 
| 1574 1620 | 
             
                const BYTE* ip = (const BYTE*)seqStart;
         | 
| 1575 1621 | 
             
                const BYTE* const iend = ip + seqSize;
         | 
| 1576 1622 | 
             
                BYTE* const ostart = (BYTE*)dst;
         | 
| 1577 | 
            -
                BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ostart  | 
| 1623 | 
            +
                BYTE* const oend = dctx->litBufferLocation == ZSTD_not_in_dst ? ZSTD_maybeNullPtrAdd(ostart, maxDstSize) : dctx->litBuffer;
         | 
| 1578 1624 | 
             
                BYTE* op = ostart;
         | 
| 1579 1625 | 
             
                const BYTE* litPtr = dctx->litPtr;
         | 
| 1580 1626 | 
             
                const BYTE* const litEnd = litPtr + dctx->litSize;
         | 
| @@ -1582,7 +1628,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, | |
| 1582 1628 | 
             
                const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
         | 
| 1583 1629 | 
             
                const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
         | 
| 1584 1630 | 
             
                DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq);
         | 
| 1585 | 
            -
                (void)frame;
         | 
| 1586 1631 |  | 
| 1587 1632 | 
             
                /* Regen sequences */
         | 
| 1588 1633 | 
             
                if (nbSeq) {
         | 
| @@ -1597,11 +1642,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, | |
| 1597 1642 | 
             
                    ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
         | 
| 1598 1643 | 
             
                    assert(dst != NULL);
         | 
| 1599 1644 |  | 
| 1600 | 
            -
                    ZSTD_STATIC_ASSERT(
         | 
| 1601 | 
            -
                        BIT_DStream_unfinished < BIT_DStream_completed &&
         | 
| 1602 | 
            -
                        BIT_DStream_endOfBuffer < BIT_DStream_completed &&
         | 
| 1603 | 
            -
                        BIT_DStream_completed < BIT_DStream_overflow);
         | 
| 1604 | 
            -
             | 
| 1605 1645 | 
             
            #if defined(__GNUC__) && defined(__x86_64__)
         | 
| 1606 1646 | 
             
                        __asm__(".p2align 6");
         | 
| 1607 1647 | 
             
                        __asm__("nop");
         | 
| @@ -1616,73 +1656,70 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx, | |
| 1616 1656 | 
             
            #  endif
         | 
| 1617 1657 | 
             
            #endif
         | 
| 1618 1658 |  | 
| 1619 | 
            -
                    for ( ; ; ) {
         | 
| 1620 | 
            -
                        seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1659 | 
            +
                    for ( ; nbSeq ; nbSeq--) {
         | 
| 1660 | 
            +
                        seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
         | 
| 1621 1661 | 
             
                        size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
         | 
| 1622 1662 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1623 1663 | 
             
                        assert(!ZSTD_isError(oneSeqSize));
         | 
| 1624 | 
            -
                         | 
| 1664 | 
            +
                        ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
         | 
| 1625 1665 | 
             
            #endif
         | 
| 1626 1666 | 
             
                        if (UNLIKELY(ZSTD_isError(oneSeqSize)))
         | 
| 1627 1667 | 
             
                            return oneSeqSize;
         | 
| 1628 1668 | 
             
                        DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
         | 
| 1629 1669 | 
             
                        op += oneSeqSize;
         | 
| 1630 | 
            -
                        if (UNLIKELY(!--nbSeq))
         | 
| 1631 | 
            -
                            break;
         | 
| 1632 | 
            -
                        BIT_reloadDStream(&(seqState.DStream));
         | 
| 1633 1670 | 
             
                    }
         | 
| 1634 1671 |  | 
| 1635 1672 | 
             
                    /* check if reached exact end */
         | 
| 1636 | 
            -
                     | 
| 1637 | 
            -
                    RETURN_ERROR_IF( | 
| 1638 | 
            -
                    RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected, "");
         | 
| 1673 | 
            +
                    assert(nbSeq == 0);
         | 
| 1674 | 
            +
                    RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
         | 
| 1639 1675 | 
             
                    /* save reps for next block */
         | 
| 1640 1676 | 
             
                    { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
         | 
| 1641 1677 | 
             
                }
         | 
| 1642 1678 |  | 
| 1643 1679 | 
             
                /* last literal segment */
         | 
| 1644 | 
            -
                {   size_t const lastLLSize = litEnd - litPtr;
         | 
| 1680 | 
            +
                {   size_t const lastLLSize = (size_t)(litEnd - litPtr);
         | 
| 1681 | 
            +
                    DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize);
         | 
| 1645 1682 | 
             
                    RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
         | 
| 1646 1683 | 
             
                    if (op != NULL) {
         | 
| 1647 1684 | 
             
                        ZSTD_memcpy(op, litPtr, lastLLSize);
         | 
| 1648 1685 | 
             
                        op += lastLLSize;
         | 
| 1649 | 
            -
             | 
| 1650 | 
            -
                }
         | 
| 1686 | 
            +
                }   }
         | 
| 1651 1687 |  | 
| 1652 | 
            -
                 | 
| 1688 | 
            +
                DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
         | 
| 1689 | 
            +
                return (size_t)(op - ostart);
         | 
| 1653 1690 | 
             
            }
         | 
| 1654 1691 |  | 
| 1655 1692 | 
             
            static size_t
         | 
| 1656 1693 | 
             
            ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
         | 
| 1657 1694 | 
             
                                             void* dst, size_t maxDstSize,
         | 
| 1658 1695 | 
             
                                       const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1659 | 
            -
                                       const ZSTD_longOffset_e isLongOffset | 
| 1660 | 
            -
                                       const int frame)
         | 
| 1696 | 
            +
                                       const ZSTD_longOffset_e isLongOffset)
         | 
| 1661 1697 | 
             
            {
         | 
| 1662 | 
            -
                return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1698 | 
            +
                return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1663 1699 | 
             
            }
         | 
| 1664 1700 |  | 
| 1665 1701 | 
             
            static size_t
         | 
| 1666 1702 | 
             
            ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
         | 
| 1667 1703 | 
             
                                                           void* dst, size_t maxDstSize,
         | 
| 1668 1704 | 
             
                                                     const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1669 | 
            -
                                                     const ZSTD_longOffset_e isLongOffset | 
| 1670 | 
            -
                                                     const int frame)
         | 
| 1705 | 
            +
                                                     const ZSTD_longOffset_e isLongOffset)
         | 
| 1671 1706 | 
             
            {
         | 
| 1672 | 
            -
                return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1707 | 
            +
                return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1673 1708 | 
             
            }
         | 
| 1674 1709 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
         | 
| 1675 1710 |  | 
| 1676 1711 | 
             
            #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
         | 
| 1677 1712 |  | 
| 1678 | 
            -
            FORCE_INLINE_TEMPLATE | 
| 1679 | 
            -
             | 
| 1713 | 
            +
            FORCE_INLINE_TEMPLATE
         | 
| 1714 | 
            +
             | 
| 1715 | 
            +
            size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
         | 
| 1680 1716 | 
             
                               const BYTE* const prefixStart, const BYTE* const dictEnd)
         | 
| 1681 1717 | 
             
            {
         | 
| 1682 1718 | 
             
                prefetchPos += sequence.litLength;
         | 
| 1683 1719 | 
             
                {   const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
         | 
| 1684 | 
            -
                     | 
| 1685 | 
            -
             | 
| 1720 | 
            +
                    /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
         | 
| 1721 | 
            +
                     * No consequence though : memory address is only used for prefetching, not for dereferencing */
         | 
| 1722 | 
            +
                    const BYTE* const match = ZSTD_wrappedPtrSub(ZSTD_wrappedPtrAdd(matchBase, prefetchPos), sequence.offset);
         | 
| 1686 1723 | 
             
                    PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE);   /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
         | 
| 1687 1724 | 
             
                }
         | 
| 1688 1725 | 
             
                return prefetchPos + sequence.matchLength;
         | 
| @@ -1697,20 +1734,18 @@ ZSTD_decompressSequencesLong_body( | |
| 1697 1734 | 
             
                                           ZSTD_DCtx* dctx,
         | 
| 1698 1735 | 
             
                                           void* dst, size_t maxDstSize,
         | 
| 1699 1736 | 
             
                                     const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1700 | 
            -
                                     const ZSTD_longOffset_e isLongOffset | 
| 1701 | 
            -
                                     const int frame)
         | 
| 1737 | 
            +
                                     const ZSTD_longOffset_e isLongOffset)
         | 
| 1702 1738 | 
             
            {
         | 
| 1703 1739 | 
             
                const BYTE* ip = (const BYTE*)seqStart;
         | 
| 1704 1740 | 
             
                const BYTE* const iend = ip + seqSize;
         | 
| 1705 1741 | 
             
                BYTE* const ostart = (BYTE*)dst;
         | 
| 1706 | 
            -
                BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ostart  | 
| 1742 | 
            +
                BYTE* const oend = dctx->litBufferLocation == ZSTD_in_dst ? dctx->litBuffer : ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
         | 
| 1707 1743 | 
             
                BYTE* op = ostart;
         | 
| 1708 1744 | 
             
                const BYTE* litPtr = dctx->litPtr;
         | 
| 1709 1745 | 
             
                const BYTE* litBufferEnd = dctx->litBufferEnd;
         | 
| 1710 1746 | 
             
                const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
         | 
| 1711 1747 | 
             
                const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
         | 
| 1712 1748 | 
             
                const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
         | 
| 1713 | 
            -
                (void)frame;
         | 
| 1714 1749 |  | 
| 1715 1750 | 
             
                /* Regen sequences */
         | 
| 1716 1751 | 
             
                if (nbSeq) {
         | 
| @@ -1735,20 +1770,17 @@ ZSTD_decompressSequencesLong_body( | |
| 1735 1770 | 
             
                    ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
         | 
| 1736 1771 |  | 
| 1737 1772 | 
             
                    /* prepare in advance */
         | 
| 1738 | 
            -
                    for (seqNb=0;  | 
| 1739 | 
            -
                        seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1773 | 
            +
                    for (seqNb=0; seqNb<seqAdvance; seqNb++) {
         | 
| 1774 | 
            +
                        seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
         | 
| 1740 1775 | 
             
                        prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
         | 
| 1741 1776 | 
             
                        sequences[seqNb] = sequence;
         | 
| 1742 1777 | 
             
                    }
         | 
| 1743 | 
            -
                    RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
         | 
| 1744 1778 |  | 
| 1745 1779 | 
             
                    /* decompress without stomping litBuffer */
         | 
| 1746 | 
            -
                    for (;  | 
| 1747 | 
            -
                        seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
         | 
| 1748 | 
            -
                        size_t oneSeqSize;
         | 
| 1780 | 
            +
                    for (; seqNb < nbSeq; seqNb++) {
         | 
| 1781 | 
            +
                        seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
         | 
| 1749 1782 |  | 
| 1750 | 
            -
                        if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
         | 
| 1751 | 
            -
                        {
         | 
| 1783 | 
            +
                        if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
         | 
| 1752 1784 | 
             
                            /* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
         | 
| 1753 1785 | 
             
                            const size_t leftoverLit = dctx->litBufferEnd - litPtr;
         | 
| 1754 1786 | 
             
                            if (leftoverLit)
         | 
| @@ -1761,26 +1793,26 @@ ZSTD_decompressSequencesLong_body( | |
| 1761 1793 | 
             
                            litPtr = dctx->litExtraBuffer;
         | 
| 1762 1794 | 
             
                            litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
         | 
| 1763 1795 | 
             
                            dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 1764 | 
            -
                            oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1796 | 
            +
                            {   size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1765 1797 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1766 | 
            -
             | 
| 1767 | 
            -
             | 
| 1798 | 
            +
                                assert(!ZSTD_isError(oneSeqSize));
         | 
| 1799 | 
            +
                                ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
         | 
| 1768 1800 | 
             
            #endif
         | 
| 1769 | 
            -
             | 
| 1801 | 
            +
                                if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
         | 
| 1770 1802 |  | 
| 1771 | 
            -
             | 
| 1772 | 
            -
             | 
| 1773 | 
            -
             | 
| 1774 | 
            -
                        }
         | 
| 1803 | 
            +
                                prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
         | 
| 1804 | 
            +
                                sequences[seqNb & STORED_SEQS_MASK] = sequence;
         | 
| 1805 | 
            +
                                op += oneSeqSize;
         | 
| 1806 | 
            +
                        }   }
         | 
| 1775 1807 | 
             
                        else
         | 
| 1776 1808 | 
             
                        {
         | 
| 1777 1809 | 
             
                            /* lit buffer is either wholly contained in first or second split, or not split at all*/
         | 
| 1778 | 
            -
                            oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
         | 
| 1810 | 
            +
                            size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
         | 
| 1779 1811 | 
             
                                ZSTD_execSequenceSplitLitBuffer(op, oend, litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength - WILDCOPY_OVERLENGTH, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd) :
         | 
| 1780 1812 | 
             
                                ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1781 1813 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1782 1814 | 
             
                            assert(!ZSTD_isError(oneSeqSize));
         | 
| 1783 | 
            -
                             | 
| 1815 | 
            +
                            ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
         | 
| 1784 1816 | 
             
            #endif
         | 
| 1785 1817 | 
             
                            if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
         | 
| 1786 1818 |  | 
| @@ -1789,17 +1821,15 @@ ZSTD_decompressSequencesLong_body( | |
| 1789 1821 | 
             
                            op += oneSeqSize;
         | 
| 1790 1822 | 
             
                        }
         | 
| 1791 1823 | 
             
                    }
         | 
| 1792 | 
            -
                    RETURN_ERROR_IF( | 
| 1824 | 
            +
                    RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
         | 
| 1793 1825 |  | 
| 1794 1826 | 
             
                    /* finish queue */
         | 
| 1795 1827 | 
             
                    seqNb -= seqAdvance;
         | 
| 1796 1828 | 
             
                    for ( ; seqNb<nbSeq ; seqNb++) {
         | 
| 1797 1829 | 
             
                        seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
         | 
| 1798 | 
            -
                        if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
         | 
| 1799 | 
            -
                        {
         | 
| 1830 | 
            +
                        if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
         | 
| 1800 1831 | 
             
                            const size_t leftoverLit = dctx->litBufferEnd - litPtr;
         | 
| 1801 | 
            -
                            if (leftoverLit)
         | 
| 1802 | 
            -
                            {
         | 
| 1832 | 
            +
                            if (leftoverLit) {
         | 
| 1803 1833 | 
             
                                RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
         | 
| 1804 1834 | 
             
                                ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
         | 
| 1805 1835 | 
             
                                sequence->litLength -= leftoverLit;
         | 
| @@ -1808,11 +1838,10 @@ ZSTD_decompressSequencesLong_body( | |
| 1808 1838 | 
             
                            litPtr = dctx->litExtraBuffer;
         | 
| 1809 1839 | 
             
                            litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
         | 
| 1810 1840 | 
             
                            dctx->litBufferLocation = ZSTD_not_in_dst;
         | 
| 1811 | 
            -
                            {
         | 
| 1812 | 
            -
                                size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1841 | 
            +
                            {   size_t const oneSeqSize = ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1813 1842 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1814 1843 | 
             
                                assert(!ZSTD_isError(oneSeqSize));
         | 
| 1815 | 
            -
                                 | 
| 1844 | 
            +
                                ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
         | 
| 1816 1845 | 
             
            #endif
         | 
| 1817 1846 | 
             
                                if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
         | 
| 1818 1847 | 
             
                                op += oneSeqSize;
         | 
| @@ -1825,7 +1854,7 @@ ZSTD_decompressSequencesLong_body( | |
| 1825 1854 | 
             
                                ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
         | 
| 1826 1855 | 
             
            #if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
         | 
| 1827 1856 | 
             
                            assert(!ZSTD_isError(oneSeqSize));
         | 
| 1828 | 
            -
                             | 
| 1857 | 
            +
                            ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
         | 
| 1829 1858 | 
             
            #endif
         | 
| 1830 1859 | 
             
                            if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
         | 
| 1831 1860 | 
             
                            op += oneSeqSize;
         | 
| @@ -1837,8 +1866,7 @@ ZSTD_decompressSequencesLong_body( | |
| 1837 1866 | 
             
                }
         | 
| 1838 1867 |  | 
| 1839 1868 | 
             
                /* last literal segment */
         | 
| 1840 | 
            -
                if (dctx->litBufferLocation == ZSTD_split) | 
| 1841 | 
            -
                {
         | 
| 1869 | 
            +
                if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
         | 
| 1842 1870 | 
             
                    size_t const lastLLSize = litBufferEnd - litPtr;
         | 
| 1843 1871 | 
             
                    RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
         | 
| 1844 1872 | 
             
                    if (op != NULL) {
         | 
| @@ -1856,17 +1884,16 @@ ZSTD_decompressSequencesLong_body( | |
| 1856 1884 | 
             
                    }
         | 
| 1857 1885 | 
             
                }
         | 
| 1858 1886 |  | 
| 1859 | 
            -
                return op-ostart;
         | 
| 1887 | 
            +
                return (size_t)(op - ostart);
         | 
| 1860 1888 | 
             
            }
         | 
| 1861 1889 |  | 
| 1862 1890 | 
             
            static size_t
         | 
| 1863 1891 | 
             
            ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
         | 
| 1864 1892 | 
             
                                             void* dst, size_t maxDstSize,
         | 
| 1865 1893 | 
             
                                       const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1866 | 
            -
                                       const ZSTD_longOffset_e isLongOffset | 
| 1867 | 
            -
                                       const int frame)
         | 
| 1894 | 
            +
                                       const ZSTD_longOffset_e isLongOffset)
         | 
| 1868 1895 | 
             
            {
         | 
| 1869 | 
            -
                return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1896 | 
            +
                return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1870 1897 | 
             
            }
         | 
| 1871 1898 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
         | 
| 1872 1899 |  | 
| @@ -1880,20 +1907,18 @@ DONT_VECTORIZE | |
| 1880 1907 | 
             
            ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
         | 
| 1881 1908 | 
             
                                             void* dst, size_t maxDstSize,
         | 
| 1882 1909 | 
             
                                       const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1883 | 
            -
                                       const ZSTD_longOffset_e isLongOffset | 
| 1884 | 
            -
                                       const int frame)
         | 
| 1910 | 
            +
                                       const ZSTD_longOffset_e isLongOffset)
         | 
| 1885 1911 | 
             
            {
         | 
| 1886 | 
            -
                return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1912 | 
            +
                return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1887 1913 | 
             
            }
         | 
| 1888 1914 | 
             
            static BMI2_TARGET_ATTRIBUTE size_t
         | 
| 1889 1915 | 
             
            DONT_VECTORIZE
         | 
| 1890 1916 | 
             
            ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
         | 
| 1891 1917 | 
             
                                             void* dst, size_t maxDstSize,
         | 
| 1892 1918 | 
             
                                       const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1893 | 
            -
                                       const ZSTD_longOffset_e isLongOffset | 
| 1894 | 
            -
                                       const int frame)
         | 
| 1919 | 
            +
                                       const ZSTD_longOffset_e isLongOffset)
         | 
| 1895 1920 | 
             
            {
         | 
| 1896 | 
            -
                return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1921 | 
            +
                return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1897 1922 | 
             
            }
         | 
| 1898 1923 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
         | 
| 1899 1924 |  | 
| @@ -1902,10 +1927,9 @@ static BMI2_TARGET_ATTRIBUTE size_t | |
| 1902 1927 | 
             
            ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
         | 
| 1903 1928 | 
             
                                             void* dst, size_t maxDstSize,
         | 
| 1904 1929 | 
             
                                       const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1905 | 
            -
                                       const ZSTD_longOffset_e isLongOffset | 
| 1906 | 
            -
                                       const int frame)
         | 
| 1930 | 
            +
                                       const ZSTD_longOffset_e isLongOffset)
         | 
| 1907 1931 | 
             
            {
         | 
| 1908 | 
            -
                return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1932 | 
            +
                return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1909 1933 | 
             
            }
         | 
| 1910 1934 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
         | 
| 1911 1935 |  | 
| @@ -1915,37 +1939,34 @@ typedef size_t (*ZSTD_decompressSequences_t)( | |
| 1915 1939 | 
             
                                        ZSTD_DCtx* dctx,
         | 
| 1916 1940 | 
             
                                        void* dst, size_t maxDstSize,
         | 
| 1917 1941 | 
             
                                        const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1918 | 
            -
                                        const ZSTD_longOffset_e isLongOffset | 
| 1919 | 
            -
                                        const int frame);
         | 
| 1942 | 
            +
                                        const ZSTD_longOffset_e isLongOffset);
         | 
| 1920 1943 |  | 
| 1921 1944 | 
             
            #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
         | 
| 1922 1945 | 
             
            static size_t
         | 
| 1923 1946 | 
             
            ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
         | 
| 1924 1947 | 
             
                               const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1925 | 
            -
                               const ZSTD_longOffset_e isLongOffset | 
| 1926 | 
            -
                               const int frame)
         | 
| 1948 | 
            +
                               const ZSTD_longOffset_e isLongOffset)
         | 
| 1927 1949 | 
             
            {
         | 
| 1928 1950 | 
             
                DEBUGLOG(5, "ZSTD_decompressSequences");
         | 
| 1929 1951 | 
             
            #if DYNAMIC_BMI2
         | 
| 1930 1952 | 
             
                if (ZSTD_DCtx_get_bmi2(dctx)) {
         | 
| 1931 | 
            -
                    return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1953 | 
            +
                    return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1932 1954 | 
             
                }
         | 
| 1933 1955 | 
             
            #endif
         | 
| 1934 | 
            -
                return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1956 | 
            +
                return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1935 1957 | 
             
            }
         | 
| 1936 1958 | 
             
            static size_t
         | 
| 1937 1959 | 
             
            ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
         | 
| 1938 1960 | 
             
                                             const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1939 | 
            -
                                             const ZSTD_longOffset_e isLongOffset | 
| 1940 | 
            -
                                             const int frame)
         | 
| 1961 | 
            +
                                             const ZSTD_longOffset_e isLongOffset)
         | 
| 1941 1962 | 
             
            {
         | 
| 1942 1963 | 
             
                DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
         | 
| 1943 1964 | 
             
            #if DYNAMIC_BMI2
         | 
| 1944 1965 | 
             
                if (ZSTD_DCtx_get_bmi2(dctx)) {
         | 
| 1945 | 
            -
                    return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1966 | 
            +
                    return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1946 1967 | 
             
                }
         | 
| 1947 1968 | 
             
            #endif
         | 
| 1948 | 
            -
                return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1969 | 
            +
                return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1949 1970 | 
             
            }
         | 
| 1950 1971 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
         | 
| 1951 1972 |  | 
| @@ -1960,16 +1981,15 @@ static size_t | |
| 1960 1981 | 
             
            ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
         | 
| 1961 1982 | 
             
                                         void* dst, size_t maxDstSize,
         | 
| 1962 1983 | 
             
                                         const void* seqStart, size_t seqSize, int nbSeq,
         | 
| 1963 | 
            -
                                         const ZSTD_longOffset_e isLongOffset | 
| 1964 | 
            -
                                         const int frame)
         | 
| 1984 | 
            +
                                         const ZSTD_longOffset_e isLongOffset)
         | 
| 1965 1985 | 
             
            {
         | 
| 1966 1986 | 
             
                DEBUGLOG(5, "ZSTD_decompressSequencesLong");
         | 
| 1967 1987 | 
             
            #if DYNAMIC_BMI2
         | 
| 1968 1988 | 
             
                if (ZSTD_DCtx_get_bmi2(dctx)) {
         | 
| 1969 | 
            -
                    return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1989 | 
            +
                    return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1970 1990 | 
             
                }
         | 
| 1971 1991 | 
             
            #endif
         | 
| 1972 | 
            -
              return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset | 
| 1992 | 
            +
              return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
         | 
| 1973 1993 | 
             
            }
         | 
| 1974 1994 | 
             
            #endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
         | 
| 1975 1995 |  | 
| @@ -2051,20 +2071,20 @@ static size_t ZSTD_maxShortOffset(void) | |
| 2051 2071 | 
             
            size_t
         | 
| 2052 2072 | 
             
            ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
         | 
| 2053 2073 | 
             
                                          void* dst, size_t dstCapacity,
         | 
| 2054 | 
            -
                                    const void* src, size_t srcSize, const  | 
| 2074 | 
            +
                                    const void* src, size_t srcSize, const streaming_operation streaming)
         | 
| 2055 2075 | 
             
            {   /* blockType == blockCompressed */
         | 
| 2056 2076 | 
             
                const BYTE* ip = (const BYTE*)src;
         | 
| 2057 | 
            -
                DEBUGLOG(5, "ZSTD_decompressBlock_internal ( | 
| 2077 | 
            +
                DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize);
         | 
| 2058 2078 |  | 
| 2059 2079 | 
             
                /* Note : the wording of the specification
         | 
| 2060 | 
            -
                 * allows compressed block to be sized exactly  | 
| 2080 | 
            +
                 * allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx).
         | 
| 2061 2081 | 
             
                 * This generally does not happen, as it makes little sense,
         | 
| 2062 2082 | 
             
                 * since an uncompressed block would feature same size and have no decompression cost.
         | 
| 2063 2083 | 
             
                 * Also, note that decoder from reference libzstd before < v1.5.4
         | 
| 2064 2084 | 
             
                 * would consider this edge case as an error.
         | 
| 2065 | 
            -
                 * As a consequence, avoid generating compressed blocks of size  | 
| 2085 | 
            +
                 * As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx)
         | 
| 2066 2086 | 
             
                 * for broader compatibility with the deployed ecosystem of zstd decoders */
         | 
| 2067 | 
            -
                RETURN_ERROR_IF(srcSize >  | 
| 2087 | 
            +
                RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, "");
         | 
| 2068 2088 |  | 
| 2069 2089 | 
             
                /* Decode literals section */
         | 
| 2070 2090 | 
             
                {   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
         | 
| @@ -2079,8 +2099,8 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, | |
| 2079 2099 | 
             
                    /* Compute the maximum block size, which must also work when !frame and fParams are unset.
         | 
| 2080 2100 | 
             
                     * Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
         | 
| 2081 2101 | 
             
                     */
         | 
| 2082 | 
            -
                    size_t const blockSizeMax = MIN(dstCapacity, ( | 
| 2083 | 
            -
                    size_t const totalHistorySize = ZSTD_totalHistorySize((BYTE*)dst  | 
| 2102 | 
            +
                    size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
         | 
| 2103 | 
            +
                    size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart);
         | 
| 2084 2104 | 
             
                    /* isLongOffset must be true if there are long offsets.
         | 
| 2085 2105 | 
             
                     * Offsets are long if they are larger than ZSTD_maxShortOffset().
         | 
| 2086 2106 | 
             
                     * We don't expect that to be the case in 64-bit mode.
         | 
| @@ -2145,21 +2165,22 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx, | |
| 2145 2165 | 
             
                    {
         | 
| 2146 2166 | 
             
            #endif
         | 
| 2147 2167 | 
             
            #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
         | 
| 2148 | 
            -
                        return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset | 
| 2168 | 
            +
                        return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
         | 
| 2149 2169 | 
             
            #endif
         | 
| 2150 2170 | 
             
                    }
         | 
| 2151 2171 |  | 
| 2152 2172 | 
             
            #ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
         | 
| 2153 2173 | 
             
                    /* else */
         | 
| 2154 2174 | 
             
                    if (dctx->litBufferLocation == ZSTD_split)
         | 
| 2155 | 
            -
                        return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset | 
| 2175 | 
            +
                        return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
         | 
| 2156 2176 | 
             
                    else
         | 
| 2157 | 
            -
                        return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset | 
| 2177 | 
            +
                        return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
         | 
| 2158 2178 | 
             
            #endif
         | 
| 2159 2179 | 
             
                }
         | 
| 2160 2180 | 
             
            }
         | 
| 2161 2181 |  | 
| 2162 2182 |  | 
| 2183 | 
            +
            ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
         | 
| 2163 2184 | 
             
            void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
         | 
| 2164 2185 | 
             
            {
         | 
| 2165 2186 | 
             
                if (dst != dctx->previousDstEnd && dstSize > 0) {   /* not contiguous */
         | 
| @@ -2176,8 +2197,10 @@ size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx, | |
| 2176 2197 | 
             
                                             const void* src, size_t srcSize)
         | 
| 2177 2198 | 
             
            {
         | 
| 2178 2199 | 
             
                size_t dSize;
         | 
| 2200 | 
            +
                dctx->isFrameDecompression = 0;
         | 
| 2179 2201 | 
             
                ZSTD_checkContinuity(dctx, dst, dstCapacity);
         | 
| 2180 | 
            -
                dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize,  | 
| 2202 | 
            +
                dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming);
         | 
| 2203 | 
            +
                FORWARD_IF_ERROR(dSize, "");
         | 
| 2181 2204 | 
             
                dctx->previousDstEnd = (char*)dst + dSize;
         | 
| 2182 2205 | 
             
                return dSize;
         | 
| 2183 2206 | 
             
            }
         |