zstdlib 0.12.0-x86_64-darwin → 0.13.0-x86_64-darwin
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.bundle +0 -0
- data/lib/2.5/zstdlib_c.bundle +0 -0
- data/lib/2.6/zstdlib_c.bundle +0 -0
- data/lib/2.7/zstdlib_c.bundle +0 -0
- data/lib/3.0/zstdlib_c.bundle +0 -0
- data/lib/3.1/zstdlib_c.bundle +0 -0
- data/lib/3.2/zstdlib_c.bundle +0 -0
- data/lib/3.3/zstdlib_c.bundle +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
|
}
|