multi_compress 0.3.1 → 0.3.3
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/CHANGELOG.md +15 -3
- data/GET_STARTED.md +3 -3
- data/README.md +75 -66
- data/THIRD_PARTY_NOTICES.md +24 -0
- data/ext/multi_compress/brotli_dec_static_init.c +3 -0
- data/ext/multi_compress/brotli_enc_static_init.c +3 -0
- data/ext/multi_compress/extconf.rb +22 -1
- data/ext/multi_compress/multi_compress.c +152 -72
- data/ext/multi_compress/vendor/.vendored +2 -2
- data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
- data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
- data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
- data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
- data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
- data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
- data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
- data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
- data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
- data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
- data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
- data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
- data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
- data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
- data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
- data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
- data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
- data/ext/multi_compress/vendor/zstd/COPYING +339 -0
- data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
- data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
- data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
- data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
- data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
- data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
- data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
- data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
- data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
- data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
- data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
- data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
- data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
- data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
- data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
- data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
- data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
- data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
- data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
- data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
- data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
- data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
- data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
- data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
- data/lib/multi_compress/version.rb +1 -1
- metadata +29 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under both the BSD-style license (found in the
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
#include "../common/mem.h" /* low level memory routines */
|
|
21
21
|
#define FSE_STATIC_LINKING_ONLY
|
|
22
22
|
#include "../common/fse.h"
|
|
23
|
-
#define HUF_STATIC_LINKING_ONLY
|
|
24
23
|
#include "../common/huf.h"
|
|
25
24
|
#include "../common/zstd_internal.h"
|
|
26
25
|
#include "zstd_decompress_internal.h" /* ZSTD_DCtx */
|
|
27
26
|
#include "zstd_ddict.h" /* ZSTD_DDictDictContent */
|
|
28
27
|
#include "zstd_decompress_block.h"
|
|
28
|
+
#include "../common/bits.h" /* ZSTD_highbit32 */
|
|
29
29
|
|
|
30
30
|
/*_*******************************************************
|
|
31
31
|
* Macros
|
|
@@ -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
|
-
|
|
92
|
-
/* initially this will be stored entirely in dst during huffman decoding, it will partially shifted to litExtraBuffer after */
|
|
116
|
+
} else {
|
|
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
|
{
|
|
@@ -124,7 +139,8 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
124
139
|
RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected, "");
|
|
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
|
{
|
|
@@ -134,13 +150,16 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
134
150
|
ZSTD_FALLTHROUGH;
|
|
135
151
|
|
|
136
152
|
case set_compressed:
|
|
137
|
-
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE ==
|
|
153
|
+
RETURN_ERROR_IF(srcSize < 5, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need up to 5 for case 3");
|
|
138
154
|
{ size_t lhSize, litSize, litCSize;
|
|
139
155
|
U32 singleStream=0;
|
|
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);
|
|
160
|
+
int const flags = 0
|
|
161
|
+
| (ZSTD_DCtx_get_bmi2(dctx) ? HUF_flags_bmi2 : 0)
|
|
162
|
+
| (dctx->disableHufAsm ? HUF_flags_disableAsm : 0);
|
|
144
163
|
switch(lhlCode)
|
|
145
164
|
{
|
|
146
165
|
case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
|
|
@@ -164,7 +183,11 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
164
183
|
break;
|
|
165
184
|
}
|
|
166
185
|
RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
|
|
167
|
-
RETURN_ERROR_IF(litSize >
|
|
186
|
+
RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
|
|
187
|
+
if (!singleStream)
|
|
188
|
+
RETURN_ERROR_IF(litSize < MIN_LITERALS_FOR_4_STREAMS, literals_headerWrong,
|
|
189
|
+
"Not enough literals (%zu) for the 4-streams mode (min %u)",
|
|
190
|
+
litSize, MIN_LITERALS_FOR_4_STREAMS);
|
|
168
191
|
RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected, "");
|
|
169
192
|
RETURN_ERROR_IF(expectedWriteSize < litSize , dstSize_tooSmall, "");
|
|
170
193
|
ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 0);
|
|
@@ -176,13 +199,14 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
176
199
|
|
|
177
200
|
if (litEncType==set_repeat) {
|
|
178
201
|
if (singleStream) {
|
|
179
|
-
hufSuccess =
|
|
202
|
+
hufSuccess = HUF_decompress1X_usingDTable(
|
|
180
203
|
dctx->litBuffer, litSize, istart+lhSize, litCSize,
|
|
181
|
-
dctx->HUFptr,
|
|
204
|
+
dctx->HUFptr, flags);
|
|
182
205
|
} else {
|
|
183
|
-
|
|
206
|
+
assert(litSize >= MIN_LITERALS_FOR_4_STREAMS);
|
|
207
|
+
hufSuccess = HUF_decompress4X_usingDTable(
|
|
184
208
|
dctx->litBuffer, litSize, istart+lhSize, litCSize,
|
|
185
|
-
dctx->HUFptr,
|
|
209
|
+
dctx->HUFptr, flags);
|
|
186
210
|
}
|
|
187
211
|
} else {
|
|
188
212
|
if (singleStream) {
|
|
@@ -190,26 +214,28 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
190
214
|
hufSuccess = HUF_decompress1X_DCtx_wksp(
|
|
191
215
|
dctx->entropy.hufTable, dctx->litBuffer, litSize,
|
|
192
216
|
istart+lhSize, litCSize, dctx->workspace,
|
|
193
|
-
sizeof(dctx->workspace));
|
|
217
|
+
sizeof(dctx->workspace), flags);
|
|
194
218
|
#else
|
|
195
|
-
hufSuccess =
|
|
219
|
+
hufSuccess = HUF_decompress1X1_DCtx_wksp(
|
|
196
220
|
dctx->entropy.hufTable, dctx->litBuffer, litSize,
|
|
197
221
|
istart+lhSize, litCSize, dctx->workspace,
|
|
198
|
-
sizeof(dctx->workspace),
|
|
222
|
+
sizeof(dctx->workspace), flags);
|
|
199
223
|
#endif
|
|
200
224
|
} else {
|
|
201
|
-
hufSuccess =
|
|
225
|
+
hufSuccess = HUF_decompress4X_hufOnly_wksp(
|
|
202
226
|
dctx->entropy.hufTable, dctx->litBuffer, litSize,
|
|
203
227
|
istart+lhSize, litCSize, dctx->workspace,
|
|
204
|
-
sizeof(dctx->workspace),
|
|
228
|
+
sizeof(dctx->workspace), flags);
|
|
205
229
|
}
|
|
206
230
|
}
|
|
207
231
|
if (dctx->litBufferLocation == ZSTD_split)
|
|
208
232
|
{
|
|
233
|
+
assert(litSize > ZSTD_LITBUFFEREXTRASIZE);
|
|
209
234
|
ZSTD_memcpy(dctx->litExtraBuffer, dctx->litBufferEnd - ZSTD_LITBUFFEREXTRASIZE, ZSTD_LITBUFFEREXTRASIZE);
|
|
210
235
|
ZSTD_memmove(dctx->litBuffer + ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH, dctx->litBuffer, litSize - ZSTD_LITBUFFEREXTRASIZE);
|
|
211
236
|
dctx->litBuffer += ZSTD_LITBUFFEREXTRASIZE - WILDCOPY_OVERLENGTH;
|
|
212
237
|
dctx->litBufferEnd -= WILDCOPY_OVERLENGTH;
|
|
238
|
+
assert(dctx->litBufferEnd <= (BYTE*)dst + blockSizeMax);
|
|
213
239
|
}
|
|
214
240
|
|
|
215
241
|
RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected, "");
|
|
@@ -224,7 +250,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
224
250
|
case set_basic:
|
|
225
251
|
{ size_t litSize, lhSize;
|
|
226
252
|
U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
|
227
|
-
size_t expectedWriteSize = MIN(
|
|
253
|
+
size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
|
|
228
254
|
switch(lhlCode)
|
|
229
255
|
{
|
|
230
256
|
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
|
|
@@ -237,11 +263,13 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
237
263
|
break;
|
|
238
264
|
case 3:
|
|
239
265
|
lhSize = 3;
|
|
266
|
+
RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize = 3");
|
|
240
267
|
litSize = MEM_readLE24(istart) >> 4;
|
|
241
268
|
break;
|
|
242
269
|
}
|
|
243
270
|
|
|
244
271
|
RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
|
|
272
|
+
RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
|
|
245
273
|
RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
|
|
246
274
|
ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
|
|
247
275
|
if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
|
|
@@ -270,7 +298,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
270
298
|
case set_rle:
|
|
271
299
|
{ U32 const lhlCode = ((istart[0]) >> 2) & 3;
|
|
272
300
|
size_t litSize, lhSize;
|
|
273
|
-
size_t expectedWriteSize = MIN(
|
|
301
|
+
size_t expectedWriteSize = MIN(blockSizeMax, dstCapacity);
|
|
274
302
|
switch(lhlCode)
|
|
275
303
|
{
|
|
276
304
|
case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
|
|
@@ -279,16 +307,17 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
279
307
|
break;
|
|
280
308
|
case 1:
|
|
281
309
|
lhSize = 2;
|
|
310
|
+
RETURN_ERROR_IF(srcSize<3, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 3");
|
|
282
311
|
litSize = MEM_readLE16(istart) >> 4;
|
|
283
312
|
break;
|
|
284
313
|
case 3:
|
|
285
314
|
lhSize = 3;
|
|
315
|
+
RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 2; here we need lhSize+1 = 4");
|
|
286
316
|
litSize = MEM_readLE24(istart) >> 4;
|
|
287
|
-
RETURN_ERROR_IF(srcSize<4, corruption_detected, "srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4");
|
|
288
317
|
break;
|
|
289
318
|
}
|
|
290
319
|
RETURN_ERROR_IF(litSize > 0 && dst == NULL, dstSize_tooSmall, "NULL not handled");
|
|
291
|
-
RETURN_ERROR_IF(litSize >
|
|
320
|
+
RETURN_ERROR_IF(litSize > blockSizeMax, corruption_detected, "");
|
|
292
321
|
RETURN_ERROR_IF(expectedWriteSize < litSize, dstSize_tooSmall, "");
|
|
293
322
|
ZSTD_allocateLiteralsBuffer(dctx, dst, dstCapacity, litSize, streaming, expectedWriteSize, 1);
|
|
294
323
|
if (dctx->litBufferLocation == ZSTD_split)
|
|
@@ -310,6 +339,18 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
310
339
|
}
|
|
311
340
|
}
|
|
312
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
|
+
|
|
313
354
|
/* Default FSE distribution tables.
|
|
314
355
|
* These are pre-calculated FSE decoding tables using default distributions as defined in specification :
|
|
315
356
|
* https://github.com/facebook/zstd/blob/release/doc/zstd_compression_format.md#default-distributions
|
|
@@ -317,7 +358,7 @@ size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
|
|
|
317
358
|
* - start from default distributions, present in /lib/common/zstd_internal.h
|
|
318
359
|
* - generate tables normally, using ZSTD_buildFSETable()
|
|
319
360
|
* - printout the content of tables
|
|
320
|
-
* -
|
|
361
|
+
* - prettify output, report below, test with fuzzer to ensure it's correct */
|
|
321
362
|
|
|
322
363
|
/* Default FSE distribution table for Literal Lengths */
|
|
323
364
|
static const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
|
|
@@ -506,14 +547,15 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
|
|
|
506
547
|
for (i = 8; i < n; i += 8) {
|
|
507
548
|
MEM_write64(spread + pos + i, sv);
|
|
508
549
|
}
|
|
509
|
-
|
|
550
|
+
assert(n>=0);
|
|
551
|
+
pos += (size_t)n;
|
|
510
552
|
}
|
|
511
553
|
}
|
|
512
554
|
/* Now we spread those positions across the table.
|
|
513
|
-
* The benefit of doing it in two stages is that we avoid the
|
|
555
|
+
* The benefit of doing it in two stages is that we avoid the
|
|
514
556
|
* variable size inner loop, which caused lots of branch misses.
|
|
515
557
|
* Now we can run through all the positions without any branch misses.
|
|
516
|
-
* We unroll the loop twice, since that is what
|
|
558
|
+
* We unroll the loop twice, since that is what empirically worked best.
|
|
517
559
|
*/
|
|
518
560
|
{
|
|
519
561
|
size_t position = 0;
|
|
@@ -540,7 +582,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
|
|
|
540
582
|
for (i=0; i<n; i++) {
|
|
541
583
|
tableDecode[position].baseValue = s;
|
|
542
584
|
position = (position + step) & tableMask;
|
|
543
|
-
while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
|
|
585
|
+
while (UNLIKELY(position > highThreshold)) position = (position + step) & tableMask; /* lowprob area */
|
|
544
586
|
} }
|
|
545
587
|
assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
|
|
546
588
|
}
|
|
@@ -551,7 +593,7 @@ void ZSTD_buildFSETable_body(ZSTD_seqSymbol* dt,
|
|
|
551
593
|
for (u=0; u<tableSize; u++) {
|
|
552
594
|
U32 const symbol = tableDecode[u].baseValue;
|
|
553
595
|
U32 const nextState = symbolNext[symbol]++;
|
|
554
|
-
tableDecode[u].nbBits = (BYTE) (tableLog -
|
|
596
|
+
tableDecode[u].nbBits = (BYTE) (tableLog - ZSTD_highbit32(nextState) );
|
|
555
597
|
tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
|
|
556
598
|
assert(nbAdditionalBits[symbol] < 255);
|
|
557
599
|
tableDecode[u].nbAdditionalBits = nbAdditionalBits[symbol];
|
|
@@ -603,7 +645,7 @@ void ZSTD_buildFSETable(ZSTD_seqSymbol* dt,
|
|
|
603
645
|
* @return : nb bytes read from src,
|
|
604
646
|
* or an error code if it fails */
|
|
605
647
|
static size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,
|
|
606
|
-
|
|
648
|
+
SymbolEncodingType_e type, unsigned max, U32 maxLog,
|
|
607
649
|
const void* src, size_t srcSize,
|
|
608
650
|
const U32* baseValue, const U8* nbAdditionalBits,
|
|
609
651
|
const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,
|
|
@@ -664,11 +706,6 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|
|
664
706
|
|
|
665
707
|
/* SeqHead */
|
|
666
708
|
nbSeq = *ip++;
|
|
667
|
-
if (!nbSeq) {
|
|
668
|
-
*nbSeqPtr=0;
|
|
669
|
-
RETURN_ERROR_IF(srcSize != 1, srcSize_wrong, "");
|
|
670
|
-
return 1;
|
|
671
|
-
}
|
|
672
709
|
if (nbSeq > 0x7F) {
|
|
673
710
|
if (nbSeq == 0xFF) {
|
|
674
711
|
RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong, "");
|
|
@@ -681,11 +718,19 @@ size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
|
|
|
681
718
|
}
|
|
682
719
|
*nbSeqPtr = nbSeq;
|
|
683
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
|
+
|
|
684
728
|
/* FSE table descriptors */
|
|
685
729
|
RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong, ""); /* minimum possible size: 1 byte for symbol encoding types */
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
730
|
+
RETURN_ERROR_IF(*ip & 3, corruption_detected, ""); /* The last field, Reserved, must be all-zeroes. */
|
|
731
|
+
{ SymbolEncodingType_e const LLtype = (SymbolEncodingType_e)(*ip >> 6);
|
|
732
|
+
SymbolEncodingType_e const OFtype = (SymbolEncodingType_e)((*ip >> 4) & 3);
|
|
733
|
+
SymbolEncodingType_e const MLtype = (SymbolEncodingType_e)((*ip >> 2) & 3);
|
|
689
734
|
ip++;
|
|
690
735
|
|
|
691
736
|
/* Build DTables */
|
|
@@ -829,7 +874,7 @@ static void ZSTD_safecopy(BYTE* op, const BYTE* const oend_w, BYTE const* ip, pt
|
|
|
829
874
|
/* ZSTD_safecopyDstBeforeSrc():
|
|
830
875
|
* This version allows overlap with dst before src, or handles the non-overlap case with dst after src
|
|
831
876
|
* Kept separate from more common ZSTD_safecopy case to avoid performance impact to the safecopy common case */
|
|
832
|
-
static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE
|
|
877
|
+
static void ZSTD_safecopyDstBeforeSrc(BYTE* op, const BYTE* ip, ptrdiff_t length) {
|
|
833
878
|
ptrdiff_t const diff = op - ip;
|
|
834
879
|
BYTE* const oend = op + length;
|
|
835
880
|
|
|
@@ -858,6 +903,7 @@ static void ZSTD_safecopyDstBeforeSrc(BYTE* op, BYTE const* ip, ptrdiff_t length
|
|
|
858
903
|
* to be optimized for many small sequences, since those fall into ZSTD_execSequence().
|
|
859
904
|
*/
|
|
860
905
|
FORCE_NOINLINE
|
|
906
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
861
907
|
size_t ZSTD_execSequenceEnd(BYTE* op,
|
|
862
908
|
BYTE* const oend, seq_t sequence,
|
|
863
909
|
const BYTE** litPtr, const BYTE* const litLimit,
|
|
@@ -905,6 +951,7 @@ size_t ZSTD_execSequenceEnd(BYTE* op,
|
|
|
905
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.
|
|
906
952
|
*/
|
|
907
953
|
FORCE_NOINLINE
|
|
954
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
908
955
|
size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
|
|
909
956
|
BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
|
|
910
957
|
const BYTE** litPtr, const BYTE* const litLimit,
|
|
@@ -950,6 +997,7 @@ size_t ZSTD_execSequenceEndSplitLitBuffer(BYTE* op,
|
|
|
950
997
|
}
|
|
951
998
|
|
|
952
999
|
HINT_INLINE
|
|
1000
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
953
1001
|
size_t ZSTD_execSequence(BYTE* op,
|
|
954
1002
|
BYTE* const oend, seq_t sequence,
|
|
955
1003
|
const BYTE** litPtr, const BYTE* const litLimit,
|
|
@@ -964,6 +1012,11 @@ size_t ZSTD_execSequence(BYTE* op,
|
|
|
964
1012
|
|
|
965
1013
|
assert(op != NULL /* Precondition */);
|
|
966
1014
|
assert(oend_w < oend /* No underflow */);
|
|
1015
|
+
|
|
1016
|
+
#if defined(__aarch64__)
|
|
1017
|
+
/* prefetch sequence starting from match that will be used for copy later */
|
|
1018
|
+
PREFETCH_L1(match);
|
|
1019
|
+
#endif
|
|
967
1020
|
/* Handle edge cases in a slow path:
|
|
968
1021
|
* - Read beyond end of literals
|
|
969
1022
|
* - Match end is within WILDCOPY_OVERLIMIT of oend
|
|
@@ -1043,6 +1096,7 @@ size_t ZSTD_execSequence(BYTE* op,
|
|
|
1043
1096
|
}
|
|
1044
1097
|
|
|
1045
1098
|
HINT_INLINE
|
|
1099
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
1046
1100
|
size_t ZSTD_execSequenceSplitLitBuffer(BYTE* op,
|
|
1047
1101
|
BYTE* const oend, const BYTE* const oend_w, seq_t sequence,
|
|
1048
1102
|
const BYTE** litPtr, const BYTE* const litLimit,
|
|
@@ -1154,7 +1208,7 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16
|
|
|
1154
1208
|
}
|
|
1155
1209
|
|
|
1156
1210
|
/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
|
|
1157
|
-
* offset bits. But we can only read at most
|
|
1211
|
+
* offset bits. But we can only read at most STREAM_ACCUMULATOR_MIN_32
|
|
1158
1212
|
* bits before reloading. This value is the maximum number of bytes we read
|
|
1159
1213
|
* after reloading when we are decoding long offsets.
|
|
1160
1214
|
*/
|
|
@@ -1165,13 +1219,37 @@ ZSTD_updateFseStateWithDInfo(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, U16
|
|
|
1165
1219
|
|
|
1166
1220
|
typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
|
|
1167
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
|
+
*/
|
|
1168
1228
|
FORCE_INLINE_TEMPLATE seq_t
|
|
1169
|
-
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
1229
|
+
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets, const int isLastSeq)
|
|
1170
1230
|
{
|
|
1171
1231
|
seq_t seq;
|
|
1232
|
+
/*
|
|
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.
|
|
1236
|
+
* GCC doesn't recognize this and generates more unnecessary ldr/ldrb/ldrh
|
|
1237
|
+
* operations that cause performance drop. This can be avoided by using this
|
|
1238
|
+
* ZSTD_memcpy hack.
|
|
1239
|
+
*/
|
|
1240
|
+
#if defined(__aarch64__) && (defined(__GNUC__) && !defined(__clang__))
|
|
1241
|
+
ZSTD_seqSymbol llDInfoS, mlDInfoS, ofDInfoS;
|
|
1242
|
+
ZSTD_seqSymbol* const llDInfo = &llDInfoS;
|
|
1243
|
+
ZSTD_seqSymbol* const mlDInfo = &mlDInfoS;
|
|
1244
|
+
ZSTD_seqSymbol* const ofDInfo = &ofDInfoS;
|
|
1245
|
+
ZSTD_memcpy(llDInfo, seqState->stateLL.table + seqState->stateLL.state, sizeof(ZSTD_seqSymbol));
|
|
1246
|
+
ZSTD_memcpy(mlDInfo, seqState->stateML.table + seqState->stateML.state, sizeof(ZSTD_seqSymbol));
|
|
1247
|
+
ZSTD_memcpy(ofDInfo, seqState->stateOffb.table + seqState->stateOffb.state, sizeof(ZSTD_seqSymbol));
|
|
1248
|
+
#else
|
|
1172
1249
|
const ZSTD_seqSymbol* const llDInfo = seqState->stateLL.table + seqState->stateLL.state;
|
|
1173
1250
|
const ZSTD_seqSymbol* const mlDInfo = seqState->stateML.table + seqState->stateML.state;
|
|
1174
1251
|
const ZSTD_seqSymbol* const ofDInfo = seqState->stateOffb.table + seqState->stateOffb.state;
|
|
1252
|
+
#endif
|
|
1175
1253
|
seq.matchLength = mlDInfo->baseValue;
|
|
1176
1254
|
seq.litLength = llDInfo->baseValue;
|
|
1177
1255
|
{ U32 const ofBase = ofDInfo->baseValue;
|
|
@@ -1186,28 +1264,31 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
|
1186
1264
|
U32 const llnbBits = llDInfo->nbBits;
|
|
1187
1265
|
U32 const mlnbBits = mlDInfo->nbBits;
|
|
1188
1266
|
U32 const ofnbBits = ofDInfo->nbBits;
|
|
1267
|
+
|
|
1268
|
+
assert(llBits <= MaxLLBits);
|
|
1269
|
+
assert(mlBits <= MaxMLBits);
|
|
1270
|
+
assert(ofBits <= MaxOff);
|
|
1189
1271
|
/*
|
|
1190
1272
|
* As gcc has better branch and block analyzers, sometimes it is only
|
|
1191
|
-
* valuable to mark
|
|
1273
|
+
* valuable to mark likeliness for clang, it gives around 3-4% of
|
|
1192
1274
|
* performance.
|
|
1193
1275
|
*/
|
|
1194
1276
|
|
|
1195
1277
|
/* sequence */
|
|
1196
1278
|
{ size_t offset;
|
|
1197
|
-
#if defined(__clang__)
|
|
1198
|
-
if (LIKELY(ofBits > 1)) {
|
|
1199
|
-
#else
|
|
1200
1279
|
if (ofBits > 1) {
|
|
1201
|
-
#endif
|
|
1202
1280
|
ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
|
|
1203
1281
|
ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
|
|
1204
|
-
|
|
1282
|
+
ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 > LONG_OFFSETS_MAX_EXTRA_BITS_32);
|
|
1283
|
+
ZSTD_STATIC_ASSERT(STREAM_ACCUMULATOR_MIN_32 - LONG_OFFSETS_MAX_EXTRA_BITS_32 >= MaxMLBits);
|
|
1205
1284
|
if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {
|
|
1206
|
-
|
|
1285
|
+
/* Always read extra bits, this keeps the logic simple,
|
|
1286
|
+
* avoids branches, and avoids accidentally reading 0 bits.
|
|
1287
|
+
*/
|
|
1288
|
+
U32 const extraBits = LONG_OFFSETS_MAX_EXTRA_BITS_32;
|
|
1207
1289
|
offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
|
|
1208
1290
|
BIT_reloadDStream(&seqState->DStream);
|
|
1209
|
-
|
|
1210
|
-
assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32); /* to avoid another reload */
|
|
1291
|
+
offset += BIT_readBitsFast(&seqState->DStream, extraBits);
|
|
1211
1292
|
} else {
|
|
1212
1293
|
offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
|
|
1213
1294
|
if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
|
|
@@ -1224,7 +1305,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
|
1224
1305
|
} else {
|
|
1225
1306
|
offset = ofBase + ll0 + BIT_readBitsFast(&seqState->DStream, 1);
|
|
1226
1307
|
{ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
|
|
1227
|
-
temp
|
|
1308
|
+
temp -= !temp; /* 0 is not valid: input corrupted => force offset to -1 => corruption detected at execSequence */
|
|
1228
1309
|
if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
|
|
1229
1310
|
seqState->prevOffset[1] = seqState->prevOffset[0];
|
|
1230
1311
|
seqState->prevOffset[0] = offset = temp;
|
|
@@ -1232,11 +1313,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
|
1232
1313
|
seq.offset = offset;
|
|
1233
1314
|
}
|
|
1234
1315
|
|
|
1235
|
-
#if defined(__clang__)
|
|
1236
|
-
if (UNLIKELY(mlBits > 0))
|
|
1237
|
-
#else
|
|
1238
1316
|
if (mlBits > 0)
|
|
1239
|
-
#endif
|
|
1240
1317
|
seq.matchLength += BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/);
|
|
1241
1318
|
|
|
1242
1319
|
if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
|
|
@@ -1246,11 +1323,7 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
|
1246
1323
|
/* Ensure there are enough bits to read the rest of data in 64-bit mode. */
|
|
1247
1324
|
ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
|
|
1248
1325
|
|
|
1249
|
-
#if defined(__clang__)
|
|
1250
|
-
if (UNLIKELY(llBits > 0))
|
|
1251
|
-
#else
|
|
1252
1326
|
if (llBits > 0)
|
|
1253
|
-
#endif
|
|
1254
1327
|
seq.litLength += BIT_readBitsFast(&seqState->DStream, llBits/*>0*/);
|
|
1255
1328
|
|
|
1256
1329
|
if (MEM_32bits())
|
|
@@ -1259,17 +1332,22 @@ ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
|
|
|
1259
1332
|
DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
|
|
1260
1333
|
(U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
|
|
1261
1334
|
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
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
|
+
}
|
|
1266
1343
|
}
|
|
1267
1344
|
|
|
1268
1345
|
return seq;
|
|
1269
1346
|
}
|
|
1270
1347
|
|
|
1271
|
-
#
|
|
1272
|
-
|
|
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)
|
|
1273
1351
|
{
|
|
1274
1352
|
size_t const windowSize = dctx->fParams.windowSize;
|
|
1275
1353
|
/* No dictionary used. */
|
|
@@ -1283,30 +1361,33 @@ MEM_STATIC int ZSTD_dictionaryIsActive(ZSTD_DCtx const* dctx, BYTE const* prefix
|
|
|
1283
1361
|
/* Dictionary is active. */
|
|
1284
1362
|
return 1;
|
|
1285
1363
|
}
|
|
1364
|
+
#endif
|
|
1286
1365
|
|
|
1287
|
-
|
|
1366
|
+
static void ZSTD_assertValidSequence(
|
|
1288
1367
|
ZSTD_DCtx const* dctx,
|
|
1289
1368
|
BYTE const* op, BYTE const* oend,
|
|
1290
1369
|
seq_t const seq,
|
|
1291
1370
|
BYTE const* prefixStart, BYTE const* virtualStart)
|
|
1292
1371
|
{
|
|
1293
1372
|
#if DEBUGLEVEL >= 1
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
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
|
+
}
|
|
1310
1391
|
}
|
|
1311
1392
|
#else
|
|
1312
1393
|
(void)dctx, (void)op, (void)oend, (void)seq, (void)prefixStart, (void)virtualStart;
|
|
@@ -1322,23 +1403,21 @@ DONT_VECTORIZE
|
|
|
1322
1403
|
ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
1323
1404
|
void* dst, size_t maxDstSize,
|
|
1324
1405
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1325
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1326
|
-
const int frame)
|
|
1406
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1327
1407
|
{
|
|
1328
1408
|
const BYTE* ip = (const BYTE*)seqStart;
|
|
1329
1409
|
const BYTE* const iend = ip + seqSize;
|
|
1330
1410
|
BYTE* const ostart = (BYTE*)dst;
|
|
1331
|
-
BYTE* const oend = ostart
|
|
1411
|
+
BYTE* const oend = ZSTD_maybeNullPtrAdd(ostart, maxDstSize);
|
|
1332
1412
|
BYTE* op = ostart;
|
|
1333
1413
|
const BYTE* litPtr = dctx->litPtr;
|
|
1334
1414
|
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
|
1335
1415
|
const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
|
|
1336
1416
|
const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);
|
|
1337
1417
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
|
1338
|
-
DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer");
|
|
1339
|
-
(void)frame;
|
|
1418
|
+
DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer (%i seqs)", nbSeq);
|
|
1340
1419
|
|
|
1341
|
-
/*
|
|
1420
|
+
/* Literals are split between internal buffer & output buffer */
|
|
1342
1421
|
if (nbSeq) {
|
|
1343
1422
|
seqState_t seqState;
|
|
1344
1423
|
dctx->fseEntropy = 1;
|
|
@@ -1357,8 +1436,7 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
|
1357
1436
|
BIT_DStream_completed < BIT_DStream_overflow);
|
|
1358
1437
|
|
|
1359
1438
|
/* decompress without overrunning litPtr begins */
|
|
1360
|
-
{
|
|
1361
|
-
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) */
|
|
1362
1440
|
/* Align the decompression loop to 32 + 16 bytes.
|
|
1363
1441
|
*
|
|
1364
1442
|
* zstd compiled with gcc-9 on an Intel i9-9900k shows 10% decompression
|
|
@@ -1420,27 +1498,26 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
|
1420
1498
|
#endif
|
|
1421
1499
|
|
|
1422
1500
|
/* Handle the initial state where litBuffer is currently split between dst and litExtraBuffer */
|
|
1423
|
-
for (;
|
|
1424
|
-
|
|
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);
|
|
1425
1505
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1426
|
-
|
|
1427
|
-
|
|
1506
|
+
assert(!ZSTD_isError(oneSeqSize));
|
|
1507
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
|
|
1428
1508
|
#endif
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
BIT_reloadDStream(&(seqState.DStream));
|
|
1436
|
-
sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
|
|
1437
|
-
}
|
|
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)");
|
|
1438
1515
|
|
|
1439
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 */
|
|
1440
1517
|
if (nbSeq > 0) {
|
|
1441
1518
|
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
|
1442
|
-
|
|
1443
|
-
{
|
|
1519
|
+
DEBUGLOG(6, "There are %i sequences left, and %zu/%zu literals left in buffer", nbSeq, leftoverLit, sequence.litLength);
|
|
1520
|
+
if (leftoverLit) {
|
|
1444
1521
|
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
|
1445
1522
|
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
|
1446
1523
|
sequence.litLength -= leftoverLit;
|
|
@@ -1449,24 +1526,22 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
|
1449
1526
|
litPtr = dctx->litExtraBuffer;
|
|
1450
1527
|
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
|
1451
1528
|
dctx->litBufferLocation = ZSTD_not_in_dst;
|
|
1452
|
-
{
|
|
1453
|
-
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);
|
|
1454
1530
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1455
1531
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1456
|
-
|
|
1532
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
|
|
1457
1533
|
#endif
|
|
1458
1534
|
if (UNLIKELY(ZSTD_isError(oneSeqSize)))
|
|
1459
1535
|
return oneSeqSize;
|
|
1460
1536
|
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
|
|
1461
1537
|
op += oneSeqSize;
|
|
1462
|
-
if (--nbSeq)
|
|
1463
|
-
BIT_reloadDStream(&(seqState.DStream));
|
|
1464
1538
|
}
|
|
1539
|
+
nbSeq--;
|
|
1465
1540
|
}
|
|
1466
1541
|
}
|
|
1467
1542
|
|
|
1468
|
-
if (nbSeq > 0)
|
|
1469
|
-
|
|
1543
|
+
if (nbSeq > 0) {
|
|
1544
|
+
/* there is remaining lit from extra buffer */
|
|
1470
1545
|
|
|
1471
1546
|
#if defined(__GNUC__) && defined(__x86_64__)
|
|
1472
1547
|
__asm__(".p2align 6");
|
|
@@ -1485,35 +1560,34 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
|
1485
1560
|
# endif
|
|
1486
1561
|
#endif
|
|
1487
1562
|
|
|
1488
|
-
for (; ; ) {
|
|
1489
|
-
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
|
|
1563
|
+
for ( ; nbSeq ; nbSeq--) {
|
|
1564
|
+
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
|
|
1490
1565
|
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litBufferEnd, prefixStart, vBase, dictEnd);
|
|
1491
1566
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1492
1567
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1493
|
-
|
|
1568
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
|
|
1494
1569
|
#endif
|
|
1495
1570
|
if (UNLIKELY(ZSTD_isError(oneSeqSize)))
|
|
1496
1571
|
return oneSeqSize;
|
|
1497
1572
|
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
|
|
1498
1573
|
op += oneSeqSize;
|
|
1499
|
-
if (UNLIKELY(!--nbSeq))
|
|
1500
|
-
break;
|
|
1501
|
-
BIT_reloadDStream(&(seqState.DStream));
|
|
1502
1574
|
}
|
|
1503
1575
|
}
|
|
1504
1576
|
|
|
1505
1577
|
/* check if reached exact end */
|
|
1506
1578
|
DEBUGLOG(5, "ZSTD_decompressSequences_bodySplitLitBuffer: after decode loop, remaining nbSeq : %i", nbSeq);
|
|
1507
1579
|
RETURN_ERROR_IF(nbSeq, corruption_detected, "");
|
|
1508
|
-
|
|
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, "");
|
|
1509
1582
|
/* save reps for next block */
|
|
1510
1583
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
|
|
1511
1584
|
}
|
|
1512
1585
|
|
|
1513
1586
|
/* last literal segment */
|
|
1514
|
-
if (dctx->litBufferLocation == ZSTD_split)
|
|
1515
|
-
|
|
1516
|
-
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);
|
|
1517
1591
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
|
|
1518
1592
|
if (op != NULL) {
|
|
1519
1593
|
ZSTD_memmove(op, litPtr, lastLLSize);
|
|
@@ -1523,15 +1597,17 @@ ZSTD_decompressSequences_bodySplitLitBuffer( ZSTD_DCtx* dctx,
|
|
|
1523
1597
|
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
|
1524
1598
|
dctx->litBufferLocation = ZSTD_not_in_dst;
|
|
1525
1599
|
}
|
|
1526
|
-
|
|
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);
|
|
1527
1603
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
|
1528
1604
|
if (op != NULL) {
|
|
1529
1605
|
ZSTD_memcpy(op, litPtr, lastLLSize);
|
|
1530
1606
|
op += lastLLSize;
|
|
1531
|
-
|
|
1532
|
-
}
|
|
1607
|
+
} }
|
|
1533
1608
|
|
|
1534
|
-
|
|
1609
|
+
DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
|
|
1610
|
+
return (size_t)(op - ostart);
|
|
1535
1611
|
}
|
|
1536
1612
|
|
|
1537
1613
|
FORCE_INLINE_TEMPLATE size_t
|
|
@@ -1539,21 +1615,19 @@ DONT_VECTORIZE
|
|
|
1539
1615
|
ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|
1540
1616
|
void* dst, size_t maxDstSize,
|
|
1541
1617
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1542
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1543
|
-
const int frame)
|
|
1618
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1544
1619
|
{
|
|
1545
1620
|
const BYTE* ip = (const BYTE*)seqStart;
|
|
1546
1621
|
const BYTE* const iend = ip + seqSize;
|
|
1547
1622
|
BYTE* const ostart = (BYTE*)dst;
|
|
1548
|
-
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;
|
|
1549
1624
|
BYTE* op = ostart;
|
|
1550
1625
|
const BYTE* litPtr = dctx->litPtr;
|
|
1551
1626
|
const BYTE* const litEnd = litPtr + dctx->litSize;
|
|
1552
1627
|
const BYTE* const prefixStart = (const BYTE*)(dctx->prefixStart);
|
|
1553
1628
|
const BYTE* const vBase = (const BYTE*)(dctx->virtualStart);
|
|
1554
1629
|
const BYTE* const dictEnd = (const BYTE*)(dctx->dictEnd);
|
|
1555
|
-
DEBUGLOG(5, "ZSTD_decompressSequences_body");
|
|
1556
|
-
(void)frame;
|
|
1630
|
+
DEBUGLOG(5, "ZSTD_decompressSequences_body: nbSeq = %d", nbSeq);
|
|
1557
1631
|
|
|
1558
1632
|
/* Regen sequences */
|
|
1559
1633
|
if (nbSeq) {
|
|
@@ -1568,11 +1642,6 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|
|
1568
1642
|
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
|
1569
1643
|
assert(dst != NULL);
|
|
1570
1644
|
|
|
1571
|
-
ZSTD_STATIC_ASSERT(
|
|
1572
|
-
BIT_DStream_unfinished < BIT_DStream_completed &&
|
|
1573
|
-
BIT_DStream_endOfBuffer < BIT_DStream_completed &&
|
|
1574
|
-
BIT_DStream_completed < BIT_DStream_overflow);
|
|
1575
|
-
|
|
1576
1645
|
#if defined(__GNUC__) && defined(__x86_64__)
|
|
1577
1646
|
__asm__(".p2align 6");
|
|
1578
1647
|
__asm__("nop");
|
|
@@ -1587,73 +1656,70 @@ ZSTD_decompressSequences_body(ZSTD_DCtx* dctx,
|
|
|
1587
1656
|
# endif
|
|
1588
1657
|
#endif
|
|
1589
1658
|
|
|
1590
|
-
for ( ; ; ) {
|
|
1591
|
-
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
|
|
1659
|
+
for ( ; nbSeq ; nbSeq--) {
|
|
1660
|
+
seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset, nbSeq==1);
|
|
1592
1661
|
size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);
|
|
1593
1662
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1594
1663
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1595
|
-
|
|
1664
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequence, prefixStart, vBase);
|
|
1596
1665
|
#endif
|
|
1597
1666
|
if (UNLIKELY(ZSTD_isError(oneSeqSize)))
|
|
1598
1667
|
return oneSeqSize;
|
|
1599
1668
|
DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
|
|
1600
1669
|
op += oneSeqSize;
|
|
1601
|
-
if (UNLIKELY(!--nbSeq))
|
|
1602
|
-
break;
|
|
1603
|
-
BIT_reloadDStream(&(seqState.DStream));
|
|
1604
1670
|
}
|
|
1605
1671
|
|
|
1606
1672
|
/* check if reached exact end */
|
|
1607
|
-
|
|
1608
|
-
RETURN_ERROR_IF(
|
|
1609
|
-
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, "");
|
|
1610
1675
|
/* save reps for next block */
|
|
1611
1676
|
{ U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
|
|
1612
1677
|
}
|
|
1613
1678
|
|
|
1614
1679
|
/* last literal segment */
|
|
1615
|
-
{ size_t const lastLLSize = litEnd - litPtr;
|
|
1680
|
+
{ size_t const lastLLSize = (size_t)(litEnd - litPtr);
|
|
1681
|
+
DEBUGLOG(6, "copy last literals : %u", (U32)lastLLSize);
|
|
1616
1682
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall, "");
|
|
1617
1683
|
if (op != NULL) {
|
|
1618
1684
|
ZSTD_memcpy(op, litPtr, lastLLSize);
|
|
1619
1685
|
op += lastLLSize;
|
|
1620
|
-
|
|
1621
|
-
}
|
|
1686
|
+
} }
|
|
1622
1687
|
|
|
1623
|
-
|
|
1688
|
+
DEBUGLOG(6, "decoded block of size %u bytes", (U32)(op - ostart));
|
|
1689
|
+
return (size_t)(op - ostart);
|
|
1624
1690
|
}
|
|
1625
1691
|
|
|
1626
1692
|
static size_t
|
|
1627
1693
|
ZSTD_decompressSequences_default(ZSTD_DCtx* dctx,
|
|
1628
1694
|
void* dst, size_t maxDstSize,
|
|
1629
1695
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1630
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1631
|
-
const int frame)
|
|
1696
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1632
1697
|
{
|
|
1633
|
-
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1698
|
+
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1634
1699
|
}
|
|
1635
1700
|
|
|
1636
1701
|
static size_t
|
|
1637
1702
|
ZSTD_decompressSequencesSplitLitBuffer_default(ZSTD_DCtx* dctx,
|
|
1638
1703
|
void* dst, size_t maxDstSize,
|
|
1639
1704
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1640
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1641
|
-
const int frame)
|
|
1705
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1642
1706
|
{
|
|
1643
|
-
return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1707
|
+
return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1644
1708
|
}
|
|
1645
1709
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
|
|
1646
1710
|
|
|
1647
1711
|
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
|
|
1648
1712
|
|
|
1649
|
-
FORCE_INLINE_TEMPLATE
|
|
1650
|
-
|
|
1713
|
+
FORCE_INLINE_TEMPLATE
|
|
1714
|
+
|
|
1715
|
+
size_t ZSTD_prefetchMatch(size_t prefetchPos, seq_t const sequence,
|
|
1651
1716
|
const BYTE* const prefixStart, const BYTE* const dictEnd)
|
|
1652
1717
|
{
|
|
1653
1718
|
prefetchPos += sequence.litLength;
|
|
1654
1719
|
{ const BYTE* const matchBase = (sequence.offset > prefetchPos) ? dictEnd : prefixStart;
|
|
1655
|
-
|
|
1656
|
-
|
|
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);
|
|
1657
1723
|
PREFETCH_L1(match); PREFETCH_L1(match+CACHELINE_SIZE); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
|
|
1658
1724
|
}
|
|
1659
1725
|
return prefetchPos + sequence.matchLength;
|
|
@@ -1668,20 +1734,18 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1668
1734
|
ZSTD_DCtx* dctx,
|
|
1669
1735
|
void* dst, size_t maxDstSize,
|
|
1670
1736
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1671
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1672
|
-
const int frame)
|
|
1737
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1673
1738
|
{
|
|
1674
1739
|
const BYTE* ip = (const BYTE*)seqStart;
|
|
1675
1740
|
const BYTE* const iend = ip + seqSize;
|
|
1676
1741
|
BYTE* const ostart = (BYTE*)dst;
|
|
1677
|
-
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);
|
|
1678
1743
|
BYTE* op = ostart;
|
|
1679
1744
|
const BYTE* litPtr = dctx->litPtr;
|
|
1680
1745
|
const BYTE* litBufferEnd = dctx->litBufferEnd;
|
|
1681
1746
|
const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);
|
|
1682
1747
|
const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);
|
|
1683
1748
|
const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
|
|
1684
|
-
(void)frame;
|
|
1685
1749
|
|
|
1686
1750
|
/* Regen sequences */
|
|
1687
1751
|
if (nbSeq) {
|
|
@@ -1706,20 +1770,17 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1706
1770
|
ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
|
|
1707
1771
|
|
|
1708
1772
|
/* prepare in advance */
|
|
1709
|
-
for (seqNb=0;
|
|
1710
|
-
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);
|
|
1711
1775
|
prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
|
|
1712
1776
|
sequences[seqNb] = sequence;
|
|
1713
1777
|
}
|
|
1714
|
-
RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected, "");
|
|
1715
1778
|
|
|
1716
1779
|
/* decompress without stomping litBuffer */
|
|
1717
|
-
for (;
|
|
1718
|
-
seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
|
|
1719
|
-
size_t oneSeqSize;
|
|
1780
|
+
for (; seqNb < nbSeq; seqNb++) {
|
|
1781
|
+
seq_t sequence = ZSTD_decodeSequence(&seqState, isLongOffset, seqNb == nbSeq-1);
|
|
1720
1782
|
|
|
1721
|
-
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd)
|
|
1722
|
-
{
|
|
1783
|
+
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK].litLength > dctx->litBufferEnd) {
|
|
1723
1784
|
/* lit buffer is reaching split point, empty out the first buffer and transition to litExtraBuffer */
|
|
1724
1785
|
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
|
1725
1786
|
if (leftoverLit)
|
|
@@ -1732,26 +1793,26 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1732
1793
|
litPtr = dctx->litExtraBuffer;
|
|
1733
1794
|
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
|
1734
1795
|
dctx->litBufferLocation = ZSTD_not_in_dst;
|
|
1735
|
-
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);
|
|
1736
1797
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1737
|
-
|
|
1738
|
-
|
|
1798
|
+
assert(!ZSTD_isError(oneSeqSize));
|
|
1799
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
|
|
1739
1800
|
#endif
|
|
1740
|
-
|
|
1801
|
+
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
1741
1802
|
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
}
|
|
1803
|
+
prefetchPos = ZSTD_prefetchMatch(prefetchPos, sequence, prefixStart, dictEnd);
|
|
1804
|
+
sequences[seqNb & STORED_SEQS_MASK] = sequence;
|
|
1805
|
+
op += oneSeqSize;
|
|
1806
|
+
} }
|
|
1746
1807
|
else
|
|
1747
1808
|
{
|
|
1748
1809
|
/* lit buffer is either wholly contained in first or second split, or not split at all*/
|
|
1749
|
-
oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
|
|
1810
|
+
size_t const oneSeqSize = dctx->litBufferLocation == ZSTD_split ?
|
|
1750
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) :
|
|
1751
1812
|
ZSTD_execSequence(op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
|
|
1752
1813
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1753
1814
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1754
|
-
|
|
1815
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequences[(seqNb - ADVANCED_SEQS) & STORED_SEQS_MASK], prefixStart, dictStart);
|
|
1755
1816
|
#endif
|
|
1756
1817
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
1757
1818
|
|
|
@@ -1760,17 +1821,15 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1760
1821
|
op += oneSeqSize;
|
|
1761
1822
|
}
|
|
1762
1823
|
}
|
|
1763
|
-
RETURN_ERROR_IF(
|
|
1824
|
+
RETURN_ERROR_IF(!BIT_endOfDStream(&seqState.DStream), corruption_detected, "");
|
|
1764
1825
|
|
|
1765
1826
|
/* finish queue */
|
|
1766
1827
|
seqNb -= seqAdvance;
|
|
1767
1828
|
for ( ; seqNb<nbSeq ; seqNb++) {
|
|
1768
1829
|
seq_t *sequence = &(sequences[seqNb&STORED_SEQS_MASK]);
|
|
1769
|
-
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd)
|
|
1770
|
-
{
|
|
1830
|
+
if (dctx->litBufferLocation == ZSTD_split && litPtr + sequence->litLength > dctx->litBufferEnd) {
|
|
1771
1831
|
const size_t leftoverLit = dctx->litBufferEnd - litPtr;
|
|
1772
|
-
if (leftoverLit)
|
|
1773
|
-
{
|
|
1832
|
+
if (leftoverLit) {
|
|
1774
1833
|
RETURN_ERROR_IF(leftoverLit > (size_t)(oend - op), dstSize_tooSmall, "remaining lit must fit within dstBuffer");
|
|
1775
1834
|
ZSTD_safecopyDstBeforeSrc(op, litPtr, leftoverLit);
|
|
1776
1835
|
sequence->litLength -= leftoverLit;
|
|
@@ -1779,11 +1838,10 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1779
1838
|
litPtr = dctx->litExtraBuffer;
|
|
1780
1839
|
litBufferEnd = dctx->litExtraBuffer + ZSTD_LITBUFFEREXTRASIZE;
|
|
1781
1840
|
dctx->litBufferLocation = ZSTD_not_in_dst;
|
|
1782
|
-
{
|
|
1783
|
-
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);
|
|
1784
1842
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1785
1843
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1786
|
-
|
|
1844
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
|
|
1787
1845
|
#endif
|
|
1788
1846
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
1789
1847
|
op += oneSeqSize;
|
|
@@ -1796,7 +1854,7 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1796
1854
|
ZSTD_execSequence(op, oend, *sequence, &litPtr, litBufferEnd, prefixStart, dictStart, dictEnd);
|
|
1797
1855
|
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && defined(FUZZING_ASSERT_VALID_SEQUENCE)
|
|
1798
1856
|
assert(!ZSTD_isError(oneSeqSize));
|
|
1799
|
-
|
|
1857
|
+
ZSTD_assertValidSequence(dctx, op, oend, sequences[seqNb&STORED_SEQS_MASK], prefixStart, dictStart);
|
|
1800
1858
|
#endif
|
|
1801
1859
|
if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
|
|
1802
1860
|
op += oneSeqSize;
|
|
@@ -1808,8 +1866,7 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1808
1866
|
}
|
|
1809
1867
|
|
|
1810
1868
|
/* last literal segment */
|
|
1811
|
-
if (dctx->litBufferLocation == ZSTD_split)
|
|
1812
|
-
{
|
|
1869
|
+
if (dctx->litBufferLocation == ZSTD_split) { /* first deplete literal buffer in dst, then copy litExtraBuffer */
|
|
1813
1870
|
size_t const lastLLSize = litBufferEnd - litPtr;
|
|
1814
1871
|
RETURN_ERROR_IF(lastLLSize > (size_t)(oend - op), dstSize_tooSmall, "");
|
|
1815
1872
|
if (op != NULL) {
|
|
@@ -1827,17 +1884,16 @@ ZSTD_decompressSequencesLong_body(
|
|
|
1827
1884
|
}
|
|
1828
1885
|
}
|
|
1829
1886
|
|
|
1830
|
-
return op-ostart;
|
|
1887
|
+
return (size_t)(op - ostart);
|
|
1831
1888
|
}
|
|
1832
1889
|
|
|
1833
1890
|
static size_t
|
|
1834
1891
|
ZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,
|
|
1835
1892
|
void* dst, size_t maxDstSize,
|
|
1836
1893
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1837
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1838
|
-
const int frame)
|
|
1894
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1839
1895
|
{
|
|
1840
|
-
return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1896
|
+
return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1841
1897
|
}
|
|
1842
1898
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
|
|
1843
1899
|
|
|
@@ -1851,20 +1907,18 @@ DONT_VECTORIZE
|
|
|
1851
1907
|
ZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,
|
|
1852
1908
|
void* dst, size_t maxDstSize,
|
|
1853
1909
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1854
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1855
|
-
const int frame)
|
|
1910
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1856
1911
|
{
|
|
1857
|
-
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1912
|
+
return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1858
1913
|
}
|
|
1859
1914
|
static BMI2_TARGET_ATTRIBUTE size_t
|
|
1860
1915
|
DONT_VECTORIZE
|
|
1861
1916
|
ZSTD_decompressSequencesSplitLitBuffer_bmi2(ZSTD_DCtx* dctx,
|
|
1862
1917
|
void* dst, size_t maxDstSize,
|
|
1863
1918
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1864
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1865
|
-
const int frame)
|
|
1919
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1866
1920
|
{
|
|
1867
|
-
return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1921
|
+
return ZSTD_decompressSequences_bodySplitLitBuffer(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1868
1922
|
}
|
|
1869
1923
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
|
|
1870
1924
|
|
|
@@ -1873,50 +1927,40 @@ static BMI2_TARGET_ATTRIBUTE size_t
|
|
|
1873
1927
|
ZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,
|
|
1874
1928
|
void* dst, size_t maxDstSize,
|
|
1875
1929
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1876
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1877
|
-
const int frame)
|
|
1930
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1878
1931
|
{
|
|
1879
|
-
return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1932
|
+
return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1880
1933
|
}
|
|
1881
1934
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
|
|
1882
1935
|
|
|
1883
1936
|
#endif /* DYNAMIC_BMI2 */
|
|
1884
1937
|
|
|
1885
|
-
typedef size_t (*ZSTD_decompressSequences_t)(
|
|
1886
|
-
ZSTD_DCtx* dctx,
|
|
1887
|
-
void* dst, size_t maxDstSize,
|
|
1888
|
-
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1889
|
-
const ZSTD_longOffset_e isLongOffset,
|
|
1890
|
-
const int frame);
|
|
1891
|
-
|
|
1892
1938
|
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
|
|
1893
1939
|
static size_t
|
|
1894
1940
|
ZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
|
|
1895
1941
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1896
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1897
|
-
const int frame)
|
|
1942
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1898
1943
|
{
|
|
1899
1944
|
DEBUGLOG(5, "ZSTD_decompressSequences");
|
|
1900
1945
|
#if DYNAMIC_BMI2
|
|
1901
1946
|
if (ZSTD_DCtx_get_bmi2(dctx)) {
|
|
1902
|
-
return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1947
|
+
return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1903
1948
|
}
|
|
1904
1949
|
#endif
|
|
1905
|
-
return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1950
|
+
return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1906
1951
|
}
|
|
1907
1952
|
static size_t
|
|
1908
1953
|
ZSTD_decompressSequencesSplitLitBuffer(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,
|
|
1909
1954
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1910
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1911
|
-
const int frame)
|
|
1955
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1912
1956
|
{
|
|
1913
1957
|
DEBUGLOG(5, "ZSTD_decompressSequencesSplitLitBuffer");
|
|
1914
1958
|
#if DYNAMIC_BMI2
|
|
1915
1959
|
if (ZSTD_DCtx_get_bmi2(dctx)) {
|
|
1916
|
-
return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1960
|
+
return ZSTD_decompressSequencesSplitLitBuffer_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1917
1961
|
}
|
|
1918
1962
|
#endif
|
|
1919
|
-
return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1963
|
+
return ZSTD_decompressSequencesSplitLitBuffer_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1920
1964
|
}
|
|
1921
1965
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */
|
|
1922
1966
|
|
|
@@ -1931,69 +1975,114 @@ static size_t
|
|
|
1931
1975
|
ZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,
|
|
1932
1976
|
void* dst, size_t maxDstSize,
|
|
1933
1977
|
const void* seqStart, size_t seqSize, int nbSeq,
|
|
1934
|
-
const ZSTD_longOffset_e isLongOffset
|
|
1935
|
-
const int frame)
|
|
1978
|
+
const ZSTD_longOffset_e isLongOffset)
|
|
1936
1979
|
{
|
|
1937
1980
|
DEBUGLOG(5, "ZSTD_decompressSequencesLong");
|
|
1938
1981
|
#if DYNAMIC_BMI2
|
|
1939
1982
|
if (ZSTD_DCtx_get_bmi2(dctx)) {
|
|
1940
|
-
return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1983
|
+
return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1941
1984
|
}
|
|
1942
1985
|
#endif
|
|
1943
|
-
return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset
|
|
1986
|
+
return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);
|
|
1944
1987
|
}
|
|
1945
1988
|
#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */
|
|
1946
1989
|
|
|
1947
1990
|
|
|
1991
|
+
/**
|
|
1992
|
+
* @returns The total size of the history referenceable by zstd, including
|
|
1993
|
+
* both the prefix and the extDict. At @p op any offset larger than this
|
|
1994
|
+
* is invalid.
|
|
1995
|
+
*/
|
|
1996
|
+
static size_t ZSTD_totalHistorySize(BYTE* op, BYTE const* virtualStart)
|
|
1997
|
+
{
|
|
1998
|
+
return (size_t)(op - virtualStart);
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
typedef struct {
|
|
2002
|
+
unsigned longOffsetShare;
|
|
2003
|
+
unsigned maxNbAdditionalBits;
|
|
2004
|
+
} ZSTD_OffsetInfo;
|
|
1948
2005
|
|
|
1949
|
-
|
|
1950
|
-
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
|
1951
|
-
/* ZSTD_getLongOffsetsShare() :
|
|
2006
|
+
/* ZSTD_getOffsetInfo() :
|
|
1952
2007
|
* condition : offTable must be valid
|
|
1953
2008
|
* @return : "share" of long offsets (arbitrarily defined as > (1<<23))
|
|
1954
|
-
* compared to maximum possible of (1<<OffFSELog)
|
|
1955
|
-
|
|
1956
|
-
|
|
2009
|
+
* compared to maximum possible of (1<<OffFSELog),
|
|
2010
|
+
* as well as the maximum number additional bits required.
|
|
2011
|
+
*/
|
|
2012
|
+
static ZSTD_OffsetInfo
|
|
2013
|
+
ZSTD_getOffsetInfo(const ZSTD_seqSymbol* offTable, int nbSeq)
|
|
1957
2014
|
{
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
2015
|
+
ZSTD_OffsetInfo info = {0, 0};
|
|
2016
|
+
/* If nbSeq == 0, then the offTable is uninitialized, but we have
|
|
2017
|
+
* no sequences, so both values should be 0.
|
|
2018
|
+
*/
|
|
2019
|
+
if (nbSeq != 0) {
|
|
2020
|
+
const void* ptr = offTable;
|
|
2021
|
+
U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;
|
|
2022
|
+
const ZSTD_seqSymbol* table = offTable + 1;
|
|
2023
|
+
U32 const max = 1 << tableLog;
|
|
2024
|
+
U32 u;
|
|
2025
|
+
DEBUGLOG(5, "ZSTD_getLongOffsetsShare: (tableLog=%u)", tableLog);
|
|
2026
|
+
|
|
2027
|
+
assert(max <= (1 << OffFSELog)); /* max not too large */
|
|
2028
|
+
for (u=0; u<max; u++) {
|
|
2029
|
+
info.maxNbAdditionalBits = MAX(info.maxNbAdditionalBits, table[u].nbAdditionalBits);
|
|
2030
|
+
if (table[u].nbAdditionalBits > 22) info.longOffsetShare += 1;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
assert(tableLog <= OffFSELog);
|
|
2034
|
+
info.longOffsetShare <<= (OffFSELog - tableLog); /* scale to OffFSELog */
|
|
1968
2035
|
}
|
|
1969
2036
|
|
|
1970
|
-
|
|
1971
|
-
|
|
2037
|
+
return info;
|
|
2038
|
+
}
|
|
1972
2039
|
|
|
1973
|
-
|
|
2040
|
+
/**
|
|
2041
|
+
* @returns The maximum offset we can decode in one read of our bitstream, without
|
|
2042
|
+
* reloading more bits in the middle of the offset bits read. Any offsets larger
|
|
2043
|
+
* than this must use the long offset decoder.
|
|
2044
|
+
*/
|
|
2045
|
+
static size_t ZSTD_maxShortOffset(void)
|
|
2046
|
+
{
|
|
2047
|
+
if (MEM_64bits()) {
|
|
2048
|
+
/* We can decode any offset without reloading bits.
|
|
2049
|
+
* This might change if the max window size grows.
|
|
2050
|
+
*/
|
|
2051
|
+
ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);
|
|
2052
|
+
return (size_t)-1;
|
|
2053
|
+
} else {
|
|
2054
|
+
/* The maximum offBase is (1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1.
|
|
2055
|
+
* This offBase would require STREAM_ACCUMULATOR_MIN extra bits.
|
|
2056
|
+
* Then we have to subtract ZSTD_REP_NUM to get the maximum possible offset.
|
|
2057
|
+
*/
|
|
2058
|
+
size_t const maxOffbase = ((size_t)1 << (STREAM_ACCUMULATOR_MIN + 1)) - 1;
|
|
2059
|
+
size_t const maxOffset = maxOffbase - ZSTD_REP_NUM;
|
|
2060
|
+
assert(ZSTD_highbit32((U32)maxOffbase) == STREAM_ACCUMULATOR_MIN);
|
|
2061
|
+
return maxOffset;
|
|
2062
|
+
}
|
|
1974
2063
|
}
|
|
1975
|
-
#endif
|
|
1976
2064
|
|
|
1977
2065
|
size_t
|
|
1978
2066
|
ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
1979
2067
|
void* dst, size_t dstCapacity,
|
|
1980
|
-
const void* src, size_t srcSize, const
|
|
2068
|
+
const void* src, size_t srcSize, const streaming_operation streaming)
|
|
1981
2069
|
{ /* blockType == blockCompressed */
|
|
1982
2070
|
const BYTE* ip = (const BYTE*)src;
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
*
|
|
1987
|
-
*
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
2071
|
+
DEBUGLOG(5, "ZSTD_decompressBlock_internal (cSize : %u)", (unsigned)srcSize);
|
|
2072
|
+
|
|
2073
|
+
/* Note : the wording of the specification
|
|
2074
|
+
* allows compressed block to be sized exactly ZSTD_blockSizeMax(dctx).
|
|
2075
|
+
* This generally does not happen, as it makes little sense,
|
|
2076
|
+
* since an uncompressed block would feature same size and have no decompression cost.
|
|
2077
|
+
* Also, note that decoder from reference libzstd before < v1.5.4
|
|
2078
|
+
* would consider this edge case as an error.
|
|
2079
|
+
* As a consequence, avoid generating compressed blocks of size ZSTD_blockSizeMax(dctx)
|
|
2080
|
+
* for broader compatibility with the deployed ecosystem of zstd decoders */
|
|
2081
|
+
RETURN_ERROR_IF(srcSize > ZSTD_blockSizeMax(dctx), srcSize_wrong, "");
|
|
1993
2082
|
|
|
1994
2083
|
/* Decode literals section */
|
|
1995
2084
|
{ size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize, dst, dstCapacity, streaming);
|
|
1996
|
-
DEBUGLOG(5, "ZSTD_decodeLiteralsBlock :
|
|
2085
|
+
DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : cSize=%u, nbLiterals=%zu", (U32)litCSize, dctx->litSize);
|
|
1997
2086
|
if (ZSTD_isError(litCSize)) return litCSize;
|
|
1998
2087
|
ip += litCSize;
|
|
1999
2088
|
srcSize -= litCSize;
|
|
@@ -2001,6 +2090,23 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
|
2001
2090
|
|
|
2002
2091
|
/* Build Decoding Tables */
|
|
2003
2092
|
{
|
|
2093
|
+
/* Compute the maximum block size, which must also work when !frame and fParams are unset.
|
|
2094
|
+
* Additionally, take the min with dstCapacity to ensure that the totalHistorySize fits in a size_t.
|
|
2095
|
+
*/
|
|
2096
|
+
size_t const blockSizeMax = MIN(dstCapacity, ZSTD_blockSizeMax(dctx));
|
|
2097
|
+
size_t const totalHistorySize = ZSTD_totalHistorySize(ZSTD_maybeNullPtrAdd((BYTE*)dst, blockSizeMax), (BYTE const*)dctx->virtualStart);
|
|
2098
|
+
/* isLongOffset must be true if there are long offsets.
|
|
2099
|
+
* Offsets are long if they are larger than ZSTD_maxShortOffset().
|
|
2100
|
+
* We don't expect that to be the case in 64-bit mode.
|
|
2101
|
+
*
|
|
2102
|
+
* We check here to see if our history is large enough to allow long offsets.
|
|
2103
|
+
* If it isn't, then we can't possible have (valid) long offsets. If the offset
|
|
2104
|
+
* is invalid, then it is okay to read it incorrectly.
|
|
2105
|
+
*
|
|
2106
|
+
* If isLongOffsets is true, then we will later check our decoding table to see
|
|
2107
|
+
* if it is even possible to generate long offsets.
|
|
2108
|
+
*/
|
|
2109
|
+
ZSTD_longOffset_e isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (totalHistorySize > ZSTD_maxShortOffset()));
|
|
2004
2110
|
/* These macros control at build-time which decompressor implementation
|
|
2005
2111
|
* we use. If neither is defined, we do some inspection and dispatch at
|
|
2006
2112
|
* runtime.
|
|
@@ -2008,6 +2114,11 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
|
2008
2114
|
#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
|
|
2009
2115
|
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
|
2010
2116
|
int usePrefetchDecoder = dctx->ddictIsCold;
|
|
2117
|
+
#else
|
|
2118
|
+
/* Set to 1 to avoid computing offset info if we don't need to.
|
|
2119
|
+
* Otherwise this value is ignored.
|
|
2120
|
+
*/
|
|
2121
|
+
int usePrefetchDecoder = 1;
|
|
2011
2122
|
#endif
|
|
2012
2123
|
int nbSeq;
|
|
2013
2124
|
size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);
|
|
@@ -2015,40 +2126,55 @@ ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
|
|
|
2015
2126
|
ip += seqHSize;
|
|
2016
2127
|
srcSize -= seqHSize;
|
|
2017
2128
|
|
|
2018
|
-
RETURN_ERROR_IF(dst == NULL && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
|
|
2129
|
+
RETURN_ERROR_IF((dst == NULL || dstCapacity == 0) && nbSeq > 0, dstSize_tooSmall, "NULL not handled");
|
|
2130
|
+
RETURN_ERROR_IF(MEM_64bits() && sizeof(size_t) == sizeof(void*) && (size_t)(-1) - (size_t)dst < (size_t)(1 << 20), dstSize_tooSmall,
|
|
2131
|
+
"invalid dst");
|
|
2019
2132
|
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2133
|
+
/* If we could potentially have long offsets, or we might want to use the prefetch decoder,
|
|
2134
|
+
* compute information about the share of long offsets, and the maximum nbAdditionalBits.
|
|
2135
|
+
* NOTE: could probably use a larger nbSeq limit
|
|
2136
|
+
*/
|
|
2137
|
+
if (isLongOffset || (!usePrefetchDecoder && (totalHistorySize > (1u << 24)) && (nbSeq > 8))) {
|
|
2138
|
+
ZSTD_OffsetInfo const info = ZSTD_getOffsetInfo(dctx->OFTptr, nbSeq);
|
|
2139
|
+
if (isLongOffset && info.maxNbAdditionalBits <= STREAM_ACCUMULATOR_MIN) {
|
|
2140
|
+
/* If isLongOffset, but the maximum number of additional bits that we see in our table is small
|
|
2141
|
+
* enough, then we know it is impossible to have too long an offset in this block, so we can
|
|
2142
|
+
* use the regular offset decoder.
|
|
2143
|
+
*/
|
|
2144
|
+
isLongOffset = ZSTD_lo_isRegularOffset;
|
|
2145
|
+
}
|
|
2146
|
+
if (!usePrefetchDecoder) {
|
|
2147
|
+
U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */
|
|
2148
|
+
usePrefetchDecoder = (info.longOffsetShare >= minShare);
|
|
2149
|
+
}
|
|
2028
2150
|
}
|
|
2029
|
-
#endif
|
|
2030
2151
|
|
|
2031
2152
|
dctx->ddictIsCold = 0;
|
|
2032
2153
|
|
|
2033
2154
|
#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \
|
|
2034
2155
|
!defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)
|
|
2035
|
-
if (usePrefetchDecoder)
|
|
2156
|
+
if (usePrefetchDecoder) {
|
|
2157
|
+
#else
|
|
2158
|
+
(void)usePrefetchDecoder;
|
|
2159
|
+
{
|
|
2036
2160
|
#endif
|
|
2037
2161
|
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT
|
|
2038
|
-
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset
|
|
2162
|
+
return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
|
|
2039
2163
|
#endif
|
|
2164
|
+
}
|
|
2040
2165
|
|
|
2041
2166
|
#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG
|
|
2042
2167
|
/* else */
|
|
2043
2168
|
if (dctx->litBufferLocation == ZSTD_split)
|
|
2044
|
-
return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset
|
|
2169
|
+
return ZSTD_decompressSequencesSplitLitBuffer(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
|
|
2045
2170
|
else
|
|
2046
|
-
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset
|
|
2171
|
+
return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);
|
|
2047
2172
|
#endif
|
|
2048
2173
|
}
|
|
2049
2174
|
}
|
|
2050
2175
|
|
|
2051
2176
|
|
|
2177
|
+
ZSTD_ALLOW_POINTER_OVERFLOW_ATTR
|
|
2052
2178
|
void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
|
|
2053
2179
|
{
|
|
2054
2180
|
if (dst != dctx->previousDstEnd && dstSize > 0) { /* not contiguous */
|
|
@@ -2060,13 +2186,24 @@ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst, size_t dstSize)
|
|
|
2060
2186
|
}
|
|
2061
2187
|
|
|
2062
2188
|
|
|
2063
|
-
size_t
|
|
2064
|
-
|
|
2065
|
-
|
|
2189
|
+
size_t ZSTD_decompressBlock_deprecated(ZSTD_DCtx* dctx,
|
|
2190
|
+
void* dst, size_t dstCapacity,
|
|
2191
|
+
const void* src, size_t srcSize)
|
|
2066
2192
|
{
|
|
2067
2193
|
size_t dSize;
|
|
2194
|
+
dctx->isFrameDecompression = 0;
|
|
2068
2195
|
ZSTD_checkContinuity(dctx, dst, dstCapacity);
|
|
2069
|
-
dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize,
|
|
2196
|
+
dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, not_streaming);
|
|
2197
|
+
FORWARD_IF_ERROR(dSize, "");
|
|
2070
2198
|
dctx->previousDstEnd = (char*)dst + dSize;
|
|
2071
2199
|
return dSize;
|
|
2072
2200
|
}
|
|
2201
|
+
|
|
2202
|
+
|
|
2203
|
+
/* NOTE: Must just wrap ZSTD_decompressBlock_deprecated() */
|
|
2204
|
+
size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
|
|
2205
|
+
void* dst, size_t dstCapacity,
|
|
2206
|
+
const void* src, size_t srcSize)
|
|
2207
|
+
{
|
|
2208
|
+
return ZSTD_decompressBlock_deprecated(dctx, dst, dstCapacity, src, srcSize);
|
|
2209
|
+
}
|