extzstd 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/HISTORY.ja.md +13 -0
  3. data/README.md +17 -14
  4. data/contrib/zstd/{NEWS → CHANGELOG} +115 -2
  5. data/contrib/zstd/CODE_OF_CONDUCT.md +5 -0
  6. data/contrib/zstd/Makefile +99 -53
  7. data/contrib/zstd/README.md +59 -39
  8. data/contrib/zstd/TESTING.md +1 -1
  9. data/contrib/zstd/appveyor.yml +17 -6
  10. data/contrib/zstd/lib/BUCK +29 -2
  11. data/contrib/zstd/lib/Makefile +118 -21
  12. data/contrib/zstd/lib/README.md +84 -44
  13. data/contrib/zstd/lib/common/bitstream.h +17 -33
  14. data/contrib/zstd/lib/common/compiler.h +62 -8
  15. data/contrib/zstd/lib/common/cpu.h +215 -0
  16. data/contrib/zstd/lib/common/debug.c +44 -0
  17. data/contrib/zstd/lib/common/debug.h +134 -0
  18. data/contrib/zstd/lib/common/entropy_common.c +16 -1
  19. data/contrib/zstd/lib/common/error_private.c +7 -0
  20. data/contrib/zstd/lib/common/fse.h +48 -44
  21. data/contrib/zstd/lib/common/fse_decompress.c +3 -3
  22. data/contrib/zstd/lib/common/huf.h +169 -113
  23. data/contrib/zstd/lib/common/mem.h +20 -2
  24. data/contrib/zstd/lib/common/pool.c +135 -49
  25. data/contrib/zstd/lib/common/pool.h +40 -21
  26. data/contrib/zstd/lib/common/threading.c +2 -2
  27. data/contrib/zstd/lib/common/threading.h +12 -12
  28. data/contrib/zstd/lib/common/xxhash.c +3 -2
  29. data/contrib/zstd/lib/common/zstd_common.c +3 -6
  30. data/contrib/zstd/lib/common/zstd_errors.h +17 -7
  31. data/contrib/zstd/lib/common/zstd_internal.h +76 -48
  32. data/contrib/zstd/lib/compress/fse_compress.c +89 -209
  33. data/contrib/zstd/lib/compress/hist.c +203 -0
  34. data/contrib/zstd/lib/compress/hist.h +95 -0
  35. data/contrib/zstd/lib/compress/huf_compress.c +188 -80
  36. data/contrib/zstd/lib/compress/zstd_compress.c +2500 -1203
  37. data/contrib/zstd/lib/compress/zstd_compress_internal.h +463 -62
  38. data/contrib/zstd/lib/compress/zstd_double_fast.c +321 -131
  39. data/contrib/zstd/lib/compress/zstd_double_fast.h +13 -4
  40. data/contrib/zstd/lib/compress/zstd_fast.c +335 -108
  41. data/contrib/zstd/lib/compress/zstd_fast.h +12 -6
  42. data/contrib/zstd/lib/compress/zstd_lazy.c +654 -313
  43. data/contrib/zstd/lib/compress/zstd_lazy.h +44 -16
  44. data/contrib/zstd/lib/compress/zstd_ldm.c +310 -420
  45. data/contrib/zstd/lib/compress/zstd_ldm.h +63 -26
  46. data/contrib/zstd/lib/compress/zstd_opt.c +773 -325
  47. data/contrib/zstd/lib/compress/zstd_opt.h +31 -5
  48. data/contrib/zstd/lib/compress/zstdmt_compress.c +1468 -518
  49. data/contrib/zstd/lib/compress/zstdmt_compress.h +96 -45
  50. data/contrib/zstd/lib/decompress/huf_decompress.c +518 -282
  51. data/contrib/zstd/lib/decompress/zstd_ddict.c +240 -0
  52. data/contrib/zstd/lib/decompress/zstd_ddict.h +44 -0
  53. data/contrib/zstd/lib/decompress/zstd_decompress.c +613 -1513
  54. data/contrib/zstd/lib/decompress/zstd_decompress_block.c +1311 -0
  55. data/contrib/zstd/lib/decompress/zstd_decompress_block.h +59 -0
  56. data/contrib/zstd/lib/decompress/zstd_decompress_internal.h +175 -0
  57. data/contrib/zstd/lib/dictBuilder/cover.c +194 -113
  58. data/contrib/zstd/lib/dictBuilder/cover.h +112 -0
  59. data/contrib/zstd/lib/dictBuilder/divsufsort.c +3 -3
  60. data/contrib/zstd/lib/dictBuilder/fastcover.c +740 -0
  61. data/contrib/zstd/lib/dictBuilder/zdict.c +142 -106
  62. data/contrib/zstd/lib/dictBuilder/zdict.h +115 -49
  63. data/contrib/zstd/lib/legacy/zstd_legacy.h +44 -12
  64. data/contrib/zstd/lib/legacy/zstd_v01.c +41 -10
  65. data/contrib/zstd/lib/legacy/zstd_v01.h +12 -7
  66. data/contrib/zstd/lib/legacy/zstd_v02.c +37 -12
  67. data/contrib/zstd/lib/legacy/zstd_v02.h +12 -7
  68. data/contrib/zstd/lib/legacy/zstd_v03.c +38 -12
  69. data/contrib/zstd/lib/legacy/zstd_v03.h +12 -7
  70. data/contrib/zstd/lib/legacy/zstd_v04.c +55 -174
  71. data/contrib/zstd/lib/legacy/zstd_v04.h +12 -7
  72. data/contrib/zstd/lib/legacy/zstd_v05.c +59 -31
  73. data/contrib/zstd/lib/legacy/zstd_v05.h +12 -7
  74. data/contrib/zstd/lib/legacy/zstd_v06.c +48 -20
  75. data/contrib/zstd/lib/legacy/zstd_v06.h +10 -5
  76. data/contrib/zstd/lib/legacy/zstd_v07.c +62 -29
  77. data/contrib/zstd/lib/legacy/zstd_v07.h +10 -5
  78. data/contrib/zstd/lib/zstd.h +1346 -832
  79. data/ext/extzstd.c +27 -19
  80. data/ext/extzstd_stream.c +20 -4
  81. data/ext/zstd_compress.c +1 -0
  82. data/ext/zstd_decompress.c +4 -0
  83. data/ext/zstd_dictbuilder.c +4 -0
  84. data/ext/zstd_dictbuilder_fastcover.c +5 -0
  85. data/lib/extzstd.rb +52 -220
  86. data/lib/extzstd/version.rb +1 -1
  87. metadata +21 -7
  88. data/contrib/zstd/circle.yml +0 -63
@@ -0,0 +1,240 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+ /* zstd_ddict.c :
12
+ * concentrates all logic that needs to know the internals of ZSTD_DDict object */
13
+
14
+ /*-*******************************************************
15
+ * Dependencies
16
+ *********************************************************/
17
+ #include <string.h> /* memcpy, memmove, memset */
18
+ #include "cpu.h" /* bmi2 */
19
+ #include "mem.h" /* low level memory routines */
20
+ #define FSE_STATIC_LINKING_ONLY
21
+ #include "fse.h"
22
+ #define HUF_STATIC_LINKING_ONLY
23
+ #include "huf.h"
24
+ #include "zstd_decompress_internal.h"
25
+ #include "zstd_ddict.h"
26
+
27
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
28
+ # include "zstd_legacy.h"
29
+ #endif
30
+
31
+
32
+
33
+ /*-*******************************************************
34
+ * Types
35
+ *********************************************************/
36
+ struct ZSTD_DDict_s {
37
+ void* dictBuffer;
38
+ const void* dictContent;
39
+ size_t dictSize;
40
+ ZSTD_entropyDTables_t entropy;
41
+ U32 dictID;
42
+ U32 entropyPresent;
43
+ ZSTD_customMem cMem;
44
+ }; /* typedef'd to ZSTD_DDict within "zstd.h" */
45
+
46
+ const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict)
47
+ {
48
+ assert(ddict != NULL);
49
+ return ddict->dictContent;
50
+ }
51
+
52
+ size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict)
53
+ {
54
+ assert(ddict != NULL);
55
+ return ddict->dictSize;
56
+ }
57
+
58
+ void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
59
+ {
60
+ DEBUGLOG(4, "ZSTD_copyDDictParameters");
61
+ assert(dctx != NULL);
62
+ assert(ddict != NULL);
63
+ dctx->dictID = ddict->dictID;
64
+ dctx->prefixStart = ddict->dictContent;
65
+ dctx->virtualStart = ddict->dictContent;
66
+ dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
67
+ dctx->previousDstEnd = dctx->dictEnd;
68
+ if (ddict->entropyPresent) {
69
+ dctx->litEntropy = 1;
70
+ dctx->fseEntropy = 1;
71
+ dctx->LLTptr = ddict->entropy.LLTable;
72
+ dctx->MLTptr = ddict->entropy.MLTable;
73
+ dctx->OFTptr = ddict->entropy.OFTable;
74
+ dctx->HUFptr = ddict->entropy.hufTable;
75
+ dctx->entropy.rep[0] = ddict->entropy.rep[0];
76
+ dctx->entropy.rep[1] = ddict->entropy.rep[1];
77
+ dctx->entropy.rep[2] = ddict->entropy.rep[2];
78
+ } else {
79
+ dctx->litEntropy = 0;
80
+ dctx->fseEntropy = 0;
81
+ }
82
+ }
83
+
84
+
85
+ static size_t
86
+ ZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict,
87
+ ZSTD_dictContentType_e dictContentType)
88
+ {
89
+ ddict->dictID = 0;
90
+ ddict->entropyPresent = 0;
91
+ if (dictContentType == ZSTD_dct_rawContent) return 0;
92
+
93
+ if (ddict->dictSize < 8) {
94
+ if (dictContentType == ZSTD_dct_fullDict)
95
+ return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
96
+ return 0; /* pure content mode */
97
+ }
98
+ { U32 const magic = MEM_readLE32(ddict->dictContent);
99
+ if (magic != ZSTD_MAGIC_DICTIONARY) {
100
+ if (dictContentType == ZSTD_dct_fullDict)
101
+ return ERROR(dictionary_corrupted); /* only accept specified dictionaries */
102
+ return 0; /* pure content mode */
103
+ }
104
+ }
105
+ ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE);
106
+
107
+ /* load entropy tables */
108
+ RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy(
109
+ &ddict->entropy, ddict->dictContent, ddict->dictSize)),
110
+ dictionary_corrupted);
111
+ ddict->entropyPresent = 1;
112
+ return 0;
113
+ }
114
+
115
+
116
+ static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,
117
+ const void* dict, size_t dictSize,
118
+ ZSTD_dictLoadMethod_e dictLoadMethod,
119
+ ZSTD_dictContentType_e dictContentType)
120
+ {
121
+ if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
122
+ ddict->dictBuffer = NULL;
123
+ ddict->dictContent = dict;
124
+ if (!dict) dictSize = 0;
125
+ } else {
126
+ void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);
127
+ ddict->dictBuffer = internalBuffer;
128
+ ddict->dictContent = internalBuffer;
129
+ if (!internalBuffer) return ERROR(memory_allocation);
130
+ memcpy(internalBuffer, dict, dictSize);
131
+ }
132
+ ddict->dictSize = dictSize;
133
+ ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
134
+
135
+ /* parse dictionary content */
136
+ FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) );
137
+
138
+ return 0;
139
+ }
140
+
141
+ ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
142
+ ZSTD_dictLoadMethod_e dictLoadMethod,
143
+ ZSTD_dictContentType_e dictContentType,
144
+ ZSTD_customMem customMem)
145
+ {
146
+ if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
147
+
148
+ { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
149
+ if (ddict == NULL) return NULL;
150
+ ddict->cMem = customMem;
151
+ { size_t const initResult = ZSTD_initDDict_internal(ddict,
152
+ dict, dictSize,
153
+ dictLoadMethod, dictContentType);
154
+ if (ZSTD_isError(initResult)) {
155
+ ZSTD_freeDDict(ddict);
156
+ return NULL;
157
+ } }
158
+ return ddict;
159
+ }
160
+ }
161
+
162
+ /*! ZSTD_createDDict() :
163
+ * Create a digested dictionary, to start decompression without startup delay.
164
+ * `dict` content is copied inside DDict.
165
+ * Consequently, `dict` can be released after `ZSTD_DDict` creation */
166
+ ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
167
+ {
168
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
169
+ return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator);
170
+ }
171
+
172
+ /*! ZSTD_createDDict_byReference() :
173
+ * Create a digested dictionary, to start decompression without startup delay.
174
+ * Dictionary content is simply referenced, it will be accessed during decompression.
175
+ * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */
176
+ ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
177
+ {
178
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
179
+ return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator);
180
+ }
181
+
182
+
183
+ const ZSTD_DDict* ZSTD_initStaticDDict(
184
+ void* sBuffer, size_t sBufferSize,
185
+ const void* dict, size_t dictSize,
186
+ ZSTD_dictLoadMethod_e dictLoadMethod,
187
+ ZSTD_dictContentType_e dictContentType)
188
+ {
189
+ size_t const neededSpace = sizeof(ZSTD_DDict)
190
+ + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
191
+ ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer;
192
+ assert(sBuffer != NULL);
193
+ assert(dict != NULL);
194
+ if ((size_t)sBuffer & 7) return NULL; /* 8-aligned */
195
+ if (sBufferSize < neededSpace) return NULL;
196
+ if (dictLoadMethod == ZSTD_dlm_byCopy) {
197
+ memcpy(ddict+1, dict, dictSize); /* local copy */
198
+ dict = ddict+1;
199
+ }
200
+ if (ZSTD_isError( ZSTD_initDDict_internal(ddict,
201
+ dict, dictSize,
202
+ ZSTD_dlm_byRef, dictContentType) ))
203
+ return NULL;
204
+ return ddict;
205
+ }
206
+
207
+
208
+ size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
209
+ {
210
+ if (ddict==NULL) return 0; /* support free on NULL */
211
+ { ZSTD_customMem const cMem = ddict->cMem;
212
+ ZSTD_free(ddict->dictBuffer, cMem);
213
+ ZSTD_free(ddict, cMem);
214
+ return 0;
215
+ }
216
+ }
217
+
218
+ /*! ZSTD_estimateDDictSize() :
219
+ * Estimate amount of memory that will be needed to create a dictionary for decompression.
220
+ * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
221
+ size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
222
+ {
223
+ return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
224
+ }
225
+
226
+ size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
227
+ {
228
+ if (ddict==NULL) return 0; /* support sizeof on NULL */
229
+ return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;
230
+ }
231
+
232
+ /*! ZSTD_getDictID_fromDDict() :
233
+ * Provides the dictID of the dictionary loaded into `ddict`.
234
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
235
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
236
+ unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
237
+ {
238
+ if (ddict==NULL) return 0;
239
+ return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
240
+ }
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under both the BSD-style license (found in the
6
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7
+ * in the COPYING file in the root directory of this source tree).
8
+ * You may select, at your option, one of the above-listed licenses.
9
+ */
10
+
11
+
12
+ #ifndef ZSTD_DDICT_H
13
+ #define ZSTD_DDICT_H
14
+
15
+ /*-*******************************************************
16
+ * Dependencies
17
+ *********************************************************/
18
+ #include <stddef.h> /* size_t */
19
+ #include "zstd.h" /* ZSTD_DDict, and several public functions */
20
+
21
+
22
+ /*-*******************************************************
23
+ * Interface
24
+ *********************************************************/
25
+
26
+ /* note: several prototypes are already published in `zstd.h` :
27
+ * ZSTD_createDDict()
28
+ * ZSTD_createDDict_byReference()
29
+ * ZSTD_createDDict_advanced()
30
+ * ZSTD_freeDDict()
31
+ * ZSTD_initStaticDDict()
32
+ * ZSTD_sizeof_DDict()
33
+ * ZSTD_estimateDDictSize()
34
+ * ZSTD_getDictID_fromDict()
35
+ */
36
+
37
+ const void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict);
38
+ size_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict);
39
+
40
+ void ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);
41
+
42
+
43
+
44
+ #endif /* ZSTD_DDICT_H */
@@ -14,8 +14,9 @@
14
14
  *****************************************************************/
15
15
  /*!
16
16
  * HEAPMODE :
17
- * Select how default decompression function ZSTD_decompress() will allocate memory,
18
- * in memory stack (0), or in memory heap (1, requires malloc())
17
+ * Select how default decompression function ZSTD_decompress() allocates its context,
18
+ * on stack (0), or into heap (1, default; requires malloc()).
19
+ * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected.
19
20
  */
20
21
  #ifndef ZSTD_HEAPMODE
21
22
  # define ZSTD_HEAPMODE 1
@@ -23,19 +24,31 @@
23
24
 
24
25
  /*!
25
26
  * LEGACY_SUPPORT :
26
- * if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
27
+ * if set to 1+, ZSTD_decompress() can decode older formats (v0.1+)
27
28
  */
28
29
  #ifndef ZSTD_LEGACY_SUPPORT
29
30
  # define ZSTD_LEGACY_SUPPORT 0
30
31
  #endif
31
32
 
32
33
  /*!
33
- * MAXWINDOWSIZE_DEFAULT :
34
- * maximum window size accepted by DStream, by default.
35
- * Frames requiring more memory will be rejected.
36
- */
34
+ * MAXWINDOWSIZE_DEFAULT :
35
+ * maximum window size accepted by DStream __by default__.
36
+ * Frames requiring more memory will be rejected.
37
+ * It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize().
38
+ */
37
39
  #ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
38
- # define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_DEFAULTMAX) + 1)
40
+ # define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)
41
+ #endif
42
+
43
+ /*!
44
+ * NO_FORWARD_PROGRESS_MAX :
45
+ * maximum allowed nb of calls to ZSTD_decompressStream()
46
+ * without any forward progress
47
+ * (defined as: no byte read from input, and no byte flushed to output)
48
+ * before triggering an error.
49
+ */
50
+ #ifndef ZSTD_NO_FORWARD_PROGRESS_MAX
51
+ # define ZSTD_NO_FORWARD_PROGRESS_MAX 16
39
52
  #endif
40
53
 
41
54
 
@@ -43,103 +56,25 @@
43
56
  * Dependencies
44
57
  *********************************************************/
45
58
  #include <string.h> /* memcpy, memmove, memset */
59
+ #include "cpu.h" /* bmi2 */
46
60
  #include "mem.h" /* low level memory routines */
47
61
  #define FSE_STATIC_LINKING_ONLY
48
62
  #include "fse.h"
49
63
  #define HUF_STATIC_LINKING_ONLY
50
64
  #include "huf.h"
51
- #include "zstd_internal.h"
65
+ #include "zstd_internal.h" /* blockProperties_t */
66
+ #include "zstd_decompress_internal.h" /* ZSTD_DCtx */
67
+ #include "zstd_ddict.h" /* ZSTD_DDictDictContent */
68
+ #include "zstd_decompress_block.h" /* ZSTD_decompressBlock_internal */
52
69
 
53
70
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
54
71
  # include "zstd_legacy.h"
55
72
  #endif
56
73
 
57
74
 
58
- /*-*************************************
59
- * Errors
60
- ***************************************/
61
- #define ZSTD_isError ERR_isError /* for inlining */
62
- #define FSE_isError ERR_isError
63
- #define HUF_isError ERR_isError
64
-
65
-
66
- /*_*******************************************************
67
- * Memory operations
68
- **********************************************************/
69
- static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
70
-
71
-
72
75
  /*-*************************************************************
73
76
  * Context management
74
77
  ***************************************************************/
75
- typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
76
- ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
77
- ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
78
- ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
79
-
80
- typedef enum { zdss_init=0, zdss_loadHeader,
81
- zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
82
-
83
- typedef struct {
84
- FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
85
- FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
86
- FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
87
- HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
88
- U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];
89
- U32 rep[ZSTD_REP_NUM];
90
- } ZSTD_entropyDTables_t;
91
-
92
- struct ZSTD_DCtx_s
93
- {
94
- const FSE_DTable* LLTptr;
95
- const FSE_DTable* MLTptr;
96
- const FSE_DTable* OFTptr;
97
- const HUF_DTable* HUFptr;
98
- ZSTD_entropyDTables_t entropy;
99
- const void* previousDstEnd; /* detect continuity */
100
- const void* base; /* start of current segment */
101
- const void* vBase; /* virtual start of previous segment if it was just before current one */
102
- const void* dictEnd; /* end of previous segment */
103
- size_t expected;
104
- ZSTD_frameHeader fParams;
105
- U64 decodedSize;
106
- blockType_e bType; /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */
107
- ZSTD_dStage stage;
108
- U32 litEntropy;
109
- U32 fseEntropy;
110
- XXH64_state_t xxhState;
111
- size_t headerSize;
112
- U32 dictID;
113
- ZSTD_format_e format;
114
- const BYTE* litPtr;
115
- ZSTD_customMem customMem;
116
- size_t litSize;
117
- size_t rleSize;
118
- size_t staticSize;
119
-
120
- /* streaming */
121
- ZSTD_DDict* ddictLocal;
122
- const ZSTD_DDict* ddict;
123
- ZSTD_dStreamStage streamStage;
124
- char* inBuff;
125
- size_t inBuffSize;
126
- size_t inPos;
127
- size_t maxWindowSize;
128
- char* outBuff;
129
- size_t outBuffSize;
130
- size_t outStart;
131
- size_t outEnd;
132
- size_t lhSize;
133
- void* legacyContext;
134
- U32 previousLegacyVersion;
135
- U32 legacyVersion;
136
- U32 hostageByte;
137
-
138
- /* workspace */
139
- BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];
140
- BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
141
- }; /* typedef'd to ZSTD_DCtx within "zstd.h" */
142
-
143
78
  size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)
144
79
  {
145
80
  if (dctx==NULL) return 0; /* support sizeof NULL */
@@ -154,8 +89,8 @@ size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
154
89
  static size_t ZSTD_startingInputLength(ZSTD_format_e format)
155
90
  {
156
91
  size_t const startingInputLength = (format==ZSTD_f_zstd1_magicless) ?
157
- ZSTD_frameHeaderSize_prefix - ZSTD_frameIdSize :
158
- ZSTD_frameHeaderSize_prefix;
92
+ ZSTD_FRAMEHEADERSIZE_PREFIX - ZSTD_FRAMEIDSIZE :
93
+ ZSTD_FRAMEHEADERSIZE_PREFIX;
159
94
  ZSTD_STATIC_ASSERT(ZSTD_FRAMEHEADERSIZE_PREFIX >= ZSTD_FRAMEIDSIZE);
160
95
  /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */
161
96
  assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );
@@ -169,10 +104,17 @@ static void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)
169
104
  dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
170
105
  dctx->ddict = NULL;
171
106
  dctx->ddictLocal = NULL;
107
+ dctx->dictEnd = NULL;
108
+ dctx->ddictIsCold = 0;
109
+ dctx->dictUses = ZSTD_dont_use;
172
110
  dctx->inBuff = NULL;
173
111
  dctx->inBuffSize = 0;
174
112
  dctx->outBuffSize = 0;
175
113
  dctx->streamStage = zdss_init;
114
+ dctx->legacyContext = NULL;
115
+ dctx->previousLegacyVersion = 0;
116
+ dctx->noForwardProgress = 0;
117
+ dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());
176
118
  }
177
119
 
178
120
  ZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)
@@ -195,8 +137,6 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
195
137
  { ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);
196
138
  if (!dctx) return NULL;
197
139
  dctx->customMem = customMem;
198
- dctx->legacyContext = NULL;
199
- dctx->previousLegacyVersion = 0;
200
140
  ZSTD_initDCtx_internal(dctx);
201
141
  return dctx;
202
142
  }
@@ -204,16 +144,24 @@ ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
204
144
 
205
145
  ZSTD_DCtx* ZSTD_createDCtx(void)
206
146
  {
147
+ DEBUGLOG(3, "ZSTD_createDCtx");
207
148
  return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);
208
149
  }
209
150
 
151
+ static void ZSTD_clearDict(ZSTD_DCtx* dctx)
152
+ {
153
+ ZSTD_freeDDict(dctx->ddictLocal);
154
+ dctx->ddictLocal = NULL;
155
+ dctx->ddict = NULL;
156
+ dctx->dictUses = ZSTD_dont_use;
157
+ }
158
+
210
159
  size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
211
160
  {
212
161
  if (dctx==NULL) return 0; /* support free on NULL */
213
- if (dctx->staticSize) return ERROR(memory_allocation); /* not compatible with static DCtx */
162
+ RETURN_ERROR_IF(dctx->staticSize, memory_allocation, "not compatible with static DCtx");
214
163
  { ZSTD_customMem const cMem = dctx->customMem;
215
- ZSTD_freeDDict(dctx->ddictLocal);
216
- dctx->ddictLocal = NULL;
164
+ ZSTD_clearDict(dctx);
217
165
  ZSTD_free(dctx->inBuff, cMem);
218
166
  dctx->inBuff = NULL;
219
167
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
@@ -234,8 +182,8 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
234
182
 
235
183
 
236
184
  /*-*************************************************************
237
- * Decompression section
238
- ***************************************************************/
185
+ * Frame header decoding
186
+ ***************************************************************/
239
187
 
240
188
  /*! ZSTD_isFrame() :
241
189
  * Tells if the content of `buffer` starts with a valid Frame Identifier.
@@ -244,10 +192,10 @@ void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
244
192
  * Note 3 : Skippable Frame Identifiers are considered valid. */
245
193
  unsigned ZSTD_isFrame(const void* buffer, size_t size)
246
194
  {
247
- if (size < ZSTD_frameIdSize) return 0;
195
+ if (size < ZSTD_FRAMEIDSIZE) return 0;
248
196
  { U32 const magic = MEM_readLE32(buffer);
249
197
  if (magic == ZSTD_MAGICNUMBER) return 1;
250
- if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
198
+ if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
251
199
  }
252
200
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
253
201
  if (ZSTD_isLegacy(buffer, size)) return 1;
@@ -257,13 +205,13 @@ unsigned ZSTD_isFrame(const void* buffer, size_t size)
257
205
 
258
206
  /** ZSTD_frameHeaderSize_internal() :
259
207
  * srcSize must be large enough to reach header size fields.
260
- * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
208
+ * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless.
261
209
  * @return : size of the Frame Header
262
210
  * or an error code, which can be tested with ZSTD_isError() */
263
211
  static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)
264
212
  {
265
213
  size_t const minInputSize = ZSTD_startingInputLength(format);
266
- if (srcSize < minInputSize) return ERROR(srcSize_wrong);
214
+ RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong);
267
215
 
268
216
  { BYTE const fhd = ((const BYTE*)src)[minInputSize-1];
269
217
  U32 const dictID= fhd & 3;
@@ -277,38 +225,41 @@ static size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZST
277
225
 
278
226
  /** ZSTD_frameHeaderSize() :
279
227
  * srcSize must be >= ZSTD_frameHeaderSize_prefix.
280
- * @return : size of the Frame Header */
228
+ * @return : size of the Frame Header,
229
+ * or an error code (if srcSize is too small) */
281
230
  size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
282
231
  {
283
232
  return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);
284
233
  }
285
234
 
286
235
 
287
- /** ZSTD_getFrameHeader_internal() :
236
+ /** ZSTD_getFrameHeader_advanced() :
288
237
  * decode Frame Header, or require larger `srcSize`.
289
238
  * note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless
290
239
  * @return : 0, `zfhPtr` is correctly filled,
291
240
  * >0, `srcSize` is too small, value is wanted `srcSize` amount,
292
241
  * or an error code, which can be tested using ZSTD_isError() */
293
- static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
242
+ size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)
294
243
  {
295
244
  const BYTE* ip = (const BYTE*)src;
296
245
  size_t const minInputSize = ZSTD_startingInputLength(format);
297
246
 
247
+ memset(zfhPtr, 0, sizeof(*zfhPtr)); /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */
298
248
  if (srcSize < minInputSize) return minInputSize;
249
+ RETURN_ERROR_IF(src==NULL, GENERIC, "invalid parameter");
299
250
 
300
251
  if ( (format != ZSTD_f_zstd1_magicless)
301
252
  && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {
302
- if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
253
+ if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
303
254
  /* skippable frame */
304
- if (srcSize < ZSTD_skippableHeaderSize)
305
- return ZSTD_skippableHeaderSize; /* magic number + frame length */
255
+ if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)
256
+ return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */
306
257
  memset(zfhPtr, 0, sizeof(*zfhPtr));
307
- zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_frameIdSize);
258
+ zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);
308
259
  zfhPtr->frameType = ZSTD_skippableFrame;
309
260
  return 0;
310
261
  }
311
- return ERROR(prefix_unknown);
262
+ RETURN_ERROR(prefix_unknown);
312
263
  }
313
264
 
314
265
  /* ensure there is enough `srcSize` to fully read/decode frame header */
@@ -326,14 +277,13 @@ static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void*
326
277
  U64 windowSize = 0;
327
278
  U32 dictID = 0;
328
279
  U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;
329
- if ((fhdByte & 0x08) != 0)
330
- return ERROR(frameParameter_unsupported); /* reserved bits, must be zero */
280
+ RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,
281
+ "reserved bits, must be zero");
331
282
 
332
283
  if (!singleSegment) {
333
284
  BYTE const wlByte = ip[pos++];
334
285
  U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
335
- if (windowLog > ZSTD_WINDOWLOG_MAX)
336
- return ERROR(frameParameter_windowTooLarge);
286
+ RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge);
337
287
  windowSize = (1ULL << windowLog);
338
288
  windowSize += (windowSize >> 3) * (wlByte&7);
339
289
  }
@@ -373,7 +323,7 @@ static size_t ZSTD_getFrameHeader_internal(ZSTD_frameHeader* zfhPtr, const void*
373
323
  * or an error code, which can be tested using ZSTD_isError() */
374
324
  size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)
375
325
  {
376
- return ZSTD_getFrameHeader_internal(zfhPtr, src, srcSize, ZSTD_f_zstd1);
326
+ return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);
377
327
  }
378
328
 
379
329
 
@@ -400,6 +350,20 @@ unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
400
350
  } }
401
351
  }
402
352
 
353
+ static size_t readSkippableFrameSize(void const* src, size_t srcSize)
354
+ {
355
+ size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;
356
+ U32 sizeU32;
357
+
358
+ RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong);
359
+
360
+ sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);
361
+ RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,
362
+ frameParameter_unsupported);
363
+
364
+ return skippableHeaderSize + sizeU32;
365
+ }
366
+
403
367
  /** ZSTD_findDecompressedSize() :
404
368
  * compatible with legacy mode
405
369
  * `srcSize` must be the exact length of some number of ZSTD compressed and/or
@@ -409,15 +373,13 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
409
373
  {
410
374
  unsigned long long totalDstSize = 0;
411
375
 
412
- while (srcSize >= ZSTD_frameHeaderSize_prefix) {
376
+ while (srcSize >= ZSTD_FRAMEHEADERSIZE_PREFIX) {
413
377
  U32 const magicNumber = MEM_readLE32(src);
414
378
 
415
- if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
416
- size_t skippableSize;
417
- if (srcSize < ZSTD_skippableHeaderSize)
418
- return ERROR(srcSize_wrong);
419
- skippableSize = MEM_readLE32((const BYTE *)src + ZSTD_frameIdSize)
420
- + ZSTD_skippableHeaderSize;
379
+ if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
380
+ size_t const skippableSize = readSkippableFrameSize(src, srcSize);
381
+ if (ZSTD_isError(skippableSize))
382
+ return skippableSize;
421
383
  if (srcSize < skippableSize) {
422
384
  return ZSTD_CONTENTSIZE_ERROR;
423
385
  }
@@ -450,9 +412,9 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
450
412
  }
451
413
 
452
414
  /** ZSTD_getDecompressedSize() :
453
- * compatible with legacy mode
454
- * @return : decompressed size if known, 0 otherwise
455
- note : 0 can mean any of the following :
415
+ * compatible with legacy mode
416
+ * @return : decompressed size if known, 0 otherwise
417
+ note : 0 can mean any of the following :
456
418
  - frame content is empty
457
419
  - decompressed size field is not present in frame header
458
420
  - frame header unknown / not supported
@@ -466,999 +428,150 @@ unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
466
428
 
467
429
 
468
430
  /** ZSTD_decodeFrameHeader() :
469
- * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
470
- * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
431
+ * `headerSize` must be the size provided by ZSTD_frameHeaderSize().
432
+ * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
471
433
  static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
472
434
  {
473
- size_t const result = ZSTD_getFrameHeader_internal(&(dctx->fParams), src, headerSize, dctx->format);
435
+ size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);
474
436
  if (ZSTD_isError(result)) return result; /* invalid header */
475
- if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
476
- if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID))
477
- return ERROR(dictionary_wrong);
437
+ RETURN_ERROR_IF(result>0, srcSize_wrong, "headerSize too small");
438
+ #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
439
+ /* Skip the dictID check in fuzzing mode, because it makes the search
440
+ * harder.
441
+ */
442
+ RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),
443
+ dictionary_wrong);
444
+ #endif
478
445
  if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
479
446
  return 0;
480
447
  }
481
448
 
482
-
483
- /*! ZSTD_getcBlockSize() :
484
- * Provides the size of compressed block from block header `src` */
485
- size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
486
- blockProperties_t* bpPtr)
487
- {
488
- if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
489
- { U32 const cBlockHeader = MEM_readLE24(src);
490
- U32 const cSize = cBlockHeader >> 3;
491
- bpPtr->lastBlock = cBlockHeader & 1;
492
- bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
493
- bpPtr->origSize = cSize; /* only useful for RLE */
494
- if (bpPtr->blockType == bt_rle) return 1;
495
- if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
496
- return cSize;
497
- }
498
- }
499
-
500
-
501
- static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
502
- const void* src, size_t srcSize)
503
- {
504
- if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
505
- memcpy(dst, src, srcSize);
506
- return srcSize;
507
- }
508
-
509
-
510
- static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
511
- const void* src, size_t srcSize,
512
- size_t regenSize)
449
+ static ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)
513
450
  {
514
- if (srcSize != 1) return ERROR(srcSize_wrong);
515
- if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
516
- memset(dst, *(const BYTE*)src, regenSize);
517
- return regenSize;
451
+ ZSTD_frameSizeInfo frameSizeInfo;
452
+ frameSizeInfo.compressedSize = ret;
453
+ frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
454
+ return frameSizeInfo;
518
455
  }
519
456
 
520
- /*! ZSTD_decodeLiteralsBlock() :
521
- * @return : nb of bytes read from src (< srcSize )
522
- * note : symbol not declared but exposed for fullbench */
523
- size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
524
- const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
457
+ static ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)
525
458
  {
526
- if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
527
-
528
- { const BYTE* const istart = (const BYTE*) src;
529
- symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
459
+ ZSTD_frameSizeInfo frameSizeInfo;
460
+ memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));
530
461
 
531
- switch(litEncType)
532
- {
533
- case set_repeat:
534
- if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
535
- /* fall-through */
536
- case set_compressed:
537
- if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
538
- { size_t lhSize, litSize, litCSize;
539
- U32 singleStream=0;
540
- U32 const lhlCode = (istart[0] >> 2) & 3;
541
- U32 const lhc = MEM_readLE32(istart);
542
- switch(lhlCode)
543
- {
544
- case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
545
- /* 2 - 2 - 10 - 10 */
546
- singleStream = !lhlCode;
547
- lhSize = 3;
548
- litSize = (lhc >> 4) & 0x3FF;
549
- litCSize = (lhc >> 14) & 0x3FF;
550
- break;
551
- case 2:
552
- /* 2 - 2 - 14 - 14 */
553
- lhSize = 4;
554
- litSize = (lhc >> 4) & 0x3FFF;
555
- litCSize = lhc >> 18;
556
- break;
557
- case 3:
558
- /* 2 - 2 - 18 - 18 */
559
- lhSize = 5;
560
- litSize = (lhc >> 4) & 0x3FFFF;
561
- litCSize = (lhc >> 22) + (istart[4] << 10);
562
- break;
563
- }
564
- if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
565
- if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
566
-
567
- if (HUF_isError((litEncType==set_repeat) ?
568
- ( singleStream ?
569
- HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
570
- HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
571
- ( singleStream ?
572
- HUF_decompress1X2_DCtx_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize,
573
- dctx->entropy.workspace, sizeof(dctx->entropy.workspace)) :
574
- HUF_decompress4X_hufOnly_wksp(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize,
575
- dctx->entropy.workspace, sizeof(dctx->entropy.workspace)))))
576
- return ERROR(corruption_detected);
577
-
578
- dctx->litPtr = dctx->litBuffer;
579
- dctx->litSize = litSize;
580
- dctx->litEntropy = 1;
581
- if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
582
- memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
583
- return litCSize + lhSize;
584
- }
585
-
586
- case set_basic:
587
- { size_t litSize, lhSize;
588
- U32 const lhlCode = ((istart[0]) >> 2) & 3;
589
- switch(lhlCode)
590
- {
591
- case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
592
- lhSize = 1;
593
- litSize = istart[0] >> 3;
594
- break;
595
- case 1:
596
- lhSize = 2;
597
- litSize = MEM_readLE16(istart) >> 4;
598
- break;
599
- case 3:
600
- lhSize = 3;
601
- litSize = MEM_readLE24(istart) >> 4;
602
- break;
603
- }
604
-
605
- if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
606
- if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
607
- memcpy(dctx->litBuffer, istart+lhSize, litSize);
608
- dctx->litPtr = dctx->litBuffer;
609
- dctx->litSize = litSize;
610
- memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
611
- return lhSize+litSize;
612
- }
613
- /* direct reference into compressed stream */
614
- dctx->litPtr = istart+lhSize;
615
- dctx->litSize = litSize;
616
- return lhSize+litSize;
617
- }
618
-
619
- case set_rle:
620
- { U32 const lhlCode = ((istart[0]) >> 2) & 3;
621
- size_t litSize, lhSize;
622
- switch(lhlCode)
623
- {
624
- case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
625
- lhSize = 1;
626
- litSize = istart[0] >> 3;
627
- break;
628
- case 1:
629
- lhSize = 2;
630
- litSize = MEM_readLE16(istart) >> 4;
631
- break;
632
- case 3:
633
- lhSize = 3;
634
- litSize = MEM_readLE24(istart) >> 4;
635
- if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
636
- break;
637
- }
638
- if (litSize > ZSTD_BLOCKSIZE_MAX) return ERROR(corruption_detected);
639
- memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
640
- dctx->litPtr = dctx->litBuffer;
641
- dctx->litSize = litSize;
642
- return lhSize+1;
643
- }
644
- default:
645
- return ERROR(corruption_detected); /* impossible */
646
- }
647
- }
648
- }
649
-
650
-
651
- typedef union {
652
- FSE_decode_t realData;
653
- U32 alignedBy4;
654
- } FSE_decode_t4;
655
-
656
- /* Default FSE distribution table for Literal Lengths */
657
- static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
658
- { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
659
- /* base, symbol, bits */
660
- { { 0, 0, 4 } }, { { 16, 0, 4 } }, { { 32, 1, 5 } }, { { 0, 3, 5 } },
661
- { { 0, 4, 5 } }, { { 0, 6, 5 } }, { { 0, 7, 5 } }, { { 0, 9, 5 } },
662
- { { 0, 10, 5 } }, { { 0, 12, 5 } }, { { 0, 14, 6 } }, { { 0, 16, 5 } },
663
- { { 0, 18, 5 } }, { { 0, 19, 5 } }, { { 0, 21, 5 } }, { { 0, 22, 5 } },
664
- { { 0, 24, 5 } }, { { 32, 25, 5 } }, { { 0, 26, 5 } }, { { 0, 27, 6 } },
665
- { { 0, 29, 6 } }, { { 0, 31, 6 } }, { { 32, 0, 4 } }, { { 0, 1, 4 } },
666
- { { 0, 2, 5 } }, { { 32, 4, 5 } }, { { 0, 5, 5 } }, { { 32, 7, 5 } },
667
- { { 0, 8, 5 } }, { { 32, 10, 5 } }, { { 0, 11, 5 } }, { { 0, 13, 6 } },
668
- { { 32, 16, 5 } }, { { 0, 17, 5 } }, { { 32, 19, 5 } }, { { 0, 20, 5 } },
669
- { { 32, 22, 5 } }, { { 0, 23, 5 } }, { { 0, 25, 4 } }, { { 16, 25, 4 } },
670
- { { 32, 26, 5 } }, { { 0, 28, 6 } }, { { 0, 30, 6 } }, { { 48, 0, 4 } },
671
- { { 16, 1, 4 } }, { { 32, 2, 5 } }, { { 32, 3, 5 } }, { { 32, 5, 5 } },
672
- { { 32, 6, 5 } }, { { 32, 8, 5 } }, { { 32, 9, 5 } }, { { 32, 11, 5 } },
673
- { { 32, 12, 5 } }, { { 0, 15, 6 } }, { { 32, 17, 5 } }, { { 32, 18, 5 } },
674
- { { 32, 20, 5 } }, { { 32, 21, 5 } }, { { 32, 23, 5 } }, { { 32, 24, 5 } },
675
- { { 0, 35, 6 } }, { { 0, 34, 6 } }, { { 0, 33, 6 } }, { { 0, 32, 6 } },
676
- }; /* LL_defaultDTable */
677
-
678
- /* Default FSE distribution table for Match Lengths */
679
- static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
680
- { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
681
- /* base, symbol, bits */
682
- { { 0, 0, 6 } }, { { 0, 1, 4 } }, { { 32, 2, 5 } }, { { 0, 3, 5 } },
683
- { { 0, 5, 5 } }, { { 0, 6, 5 } }, { { 0, 8, 5 } }, { { 0, 10, 6 } },
684
- { { 0, 13, 6 } }, { { 0, 16, 6 } }, { { 0, 19, 6 } }, { { 0, 22, 6 } },
685
- { { 0, 25, 6 } }, { { 0, 28, 6 } }, { { 0, 31, 6 } }, { { 0, 33, 6 } },
686
- { { 0, 35, 6 } }, { { 0, 37, 6 } }, { { 0, 39, 6 } }, { { 0, 41, 6 } },
687
- { { 0, 43, 6 } }, { { 0, 45, 6 } }, { { 16, 1, 4 } }, { { 0, 2, 4 } },
688
- { { 32, 3, 5 } }, { { 0, 4, 5 } }, { { 32, 6, 5 } }, { { 0, 7, 5 } },
689
- { { 0, 9, 6 } }, { { 0, 12, 6 } }, { { 0, 15, 6 } }, { { 0, 18, 6 } },
690
- { { 0, 21, 6 } }, { { 0, 24, 6 } }, { { 0, 27, 6 } }, { { 0, 30, 6 } },
691
- { { 0, 32, 6 } }, { { 0, 34, 6 } }, { { 0, 36, 6 } }, { { 0, 38, 6 } },
692
- { { 0, 40, 6 } }, { { 0, 42, 6 } }, { { 0, 44, 6 } }, { { 32, 1, 4 } },
693
- { { 48, 1, 4 } }, { { 16, 2, 4 } }, { { 32, 4, 5 } }, { { 32, 5, 5 } },
694
- { { 32, 7, 5 } }, { { 32, 8, 5 } }, { { 0, 11, 6 } }, { { 0, 14, 6 } },
695
- { { 0, 17, 6 } }, { { 0, 20, 6 } }, { { 0, 23, 6 } }, { { 0, 26, 6 } },
696
- { { 0, 29, 6 } }, { { 0, 52, 6 } }, { { 0, 51, 6 } }, { { 0, 50, 6 } },
697
- { { 0, 49, 6 } }, { { 0, 48, 6 } }, { { 0, 47, 6 } }, { { 0, 46, 6 } },
698
- }; /* ML_defaultDTable */
699
-
700
- /* Default FSE distribution table for Offset Codes */
701
- static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
702
- { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
703
- /* base, symbol, bits */
704
- { { 0, 0, 5 } }, { { 0, 6, 4 } },
705
- { { 0, 9, 5 } }, { { 0, 15, 5 } },
706
- { { 0, 21, 5 } }, { { 0, 3, 5 } },
707
- { { 0, 7, 4 } }, { { 0, 12, 5 } },
708
- { { 0, 18, 5 } }, { { 0, 23, 5 } },
709
- { { 0, 5, 5 } }, { { 0, 8, 4 } },
710
- { { 0, 14, 5 } }, { { 0, 20, 5 } },
711
- { { 0, 2, 5 } }, { { 16, 7, 4 } },
712
- { { 0, 11, 5 } }, { { 0, 17, 5 } },
713
- { { 0, 22, 5 } }, { { 0, 4, 5 } },
714
- { { 16, 8, 4 } }, { { 0, 13, 5 } },
715
- { { 0, 19, 5 } }, { { 0, 1, 5 } },
716
- { { 16, 6, 4 } }, { { 0, 10, 5 } },
717
- { { 0, 16, 5 } }, { { 0, 28, 5 } },
718
- { { 0, 27, 5 } }, { { 0, 26, 5 } },
719
- { { 0, 25, 5 } }, { { 0, 24, 5 } },
720
- }; /* OF_defaultDTable */
721
-
722
- /*! ZSTD_buildSeqTable() :
723
- * @return : nb bytes read from src,
724
- * or an error code if it fails, testable with ZSTD_isError()
725
- */
726
- static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
727
- symbolEncodingType_e type, U32 max, U32 maxLog,
728
- const void* src, size_t srcSize,
729
- const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
730
- {
731
- const void* const tmpPtr = defaultTable; /* bypass strict aliasing */
732
- switch(type)
733
- {
734
- case set_rle :
735
- if (!srcSize) return ERROR(srcSize_wrong);
736
- if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
737
- FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
738
- *DTablePtr = DTableSpace;
739
- return 1;
740
- case set_basic :
741
- *DTablePtr = (const FSE_DTable*)tmpPtr;
742
- return 0;
743
- case set_repeat:
744
- if (!flagRepeatTable) return ERROR(corruption_detected);
745
- return 0;
746
- default : /* impossible */
747
- case set_compressed :
748
- { U32 tableLog;
749
- S16 norm[MaxSeq+1];
750
- size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
751
- if (FSE_isError(headerSize)) return ERROR(corruption_detected);
752
- if (tableLog > maxLog) return ERROR(corruption_detected);
753
- FSE_buildDTable(DTableSpace, norm, max, tableLog);
754
- *DTablePtr = DTableSpace;
755
- return headerSize;
756
- } }
757
- }
758
-
759
- size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
760
- const void* src, size_t srcSize)
761
- {
762
- const BYTE* const istart = (const BYTE* const)src;
763
- const BYTE* const iend = istart + srcSize;
764
- const BYTE* ip = istart;
765
- DEBUGLOG(5, "ZSTD_decodeSeqHeaders");
766
-
767
- /* check */
768
- if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
769
-
770
- /* SeqHead */
771
- { int nbSeq = *ip++;
772
- if (!nbSeq) { *nbSeqPtr=0; return 1; }
773
- if (nbSeq > 0x7F) {
774
- if (nbSeq == 0xFF) {
775
- if (ip+2 > iend) return ERROR(srcSize_wrong);
776
- nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
777
- } else {
778
- if (ip >= iend) return ERROR(srcSize_wrong);
779
- nbSeq = ((nbSeq-0x80)<<8) + *ip++;
780
- }
781
- }
782
- *nbSeqPtr = nbSeq;
783
- }
784
-
785
- /* FSE table descriptors */
786
- if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
787
- { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
788
- symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
789
- symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
790
- ip++;
791
-
792
- /* Build DTables */
793
- { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
794
- LLtype, MaxLL, LLFSELog,
795
- ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
796
- if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
797
- ip += llhSize;
798
- }
799
- { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
800
- OFtype, MaxOff, OffFSELog,
801
- ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
802
- if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
803
- ip += ofhSize;
804
- }
805
- { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
806
- MLtype, MaxML, MLFSELog,
807
- ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
808
- if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
809
- ip += mlhSize;
810
- }
811
- }
812
-
813
- return ip-istart;
814
- }
815
-
816
-
817
- typedef struct {
818
- size_t litLength;
819
- size_t matchLength;
820
- size_t offset;
821
- const BYTE* match;
822
- } seq_t;
823
-
824
- typedef struct {
825
- BIT_DStream_t DStream;
826
- FSE_DState_t stateLL;
827
- FSE_DState_t stateOffb;
828
- FSE_DState_t stateML;
829
- size_t prevOffset[ZSTD_REP_NUM];
830
- const BYTE* prefixStart;
831
- const BYTE* dictEnd;
832
- size_t pos;
833
- } seqState_t;
834
-
835
-
836
- FORCE_NOINLINE
837
- size_t ZSTD_execSequenceLast7(BYTE* op,
838
- BYTE* const oend, seq_t sequence,
839
- const BYTE** litPtr, const BYTE* const litLimit,
840
- const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
841
- {
842
- BYTE* const oLitEnd = op + sequence.litLength;
843
- size_t const sequenceLength = sequence.litLength + sequence.matchLength;
844
- BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
845
- BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
846
- const BYTE* const iLitEnd = *litPtr + sequence.litLength;
847
- const BYTE* match = oLitEnd - sequence.offset;
848
-
849
- /* check */
850
- if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
851
- if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
852
- if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */
853
-
854
- /* copy literals */
855
- if (op < oend_w) {
856
- ZSTD_wildcopy(op, *litPtr, oend_w - op);
857
- *litPtr += oend_w - op;
858
- op = oend_w;
859
- }
860
- while (op < oLitEnd) *op++ = *(*litPtr)++;
861
-
862
- /* copy Match */
863
- if (sequence.offset > (size_t)(oLitEnd - base)) {
864
- /* offset beyond prefix */
865
- if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
866
- match = dictEnd - (base-match);
867
- if (match + sequence.matchLength <= dictEnd) {
868
- memmove(oLitEnd, match, sequence.matchLength);
869
- return sequenceLength;
870
- }
871
- /* span extDict & currentPrefixSegment */
872
- { size_t const length1 = dictEnd - match;
873
- memmove(oLitEnd, match, length1);
874
- op = oLitEnd + length1;
875
- sequence.matchLength -= length1;
876
- match = base;
877
- } }
878
- while (op < oMatchEnd) *op++ = *match++;
879
- return sequenceLength;
880
- }
881
-
882
-
883
- typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;
884
-
885
- /* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum
886
- * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)
887
- * bits before reloading. This value is the maximum number of bytes we read
888
- * after reloading when we are decoding long offets.
889
- */
890
- #define LONG_OFFSETS_MAX_EXTRA_BITS_32 \
891
- (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32 \
892
- ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32 \
893
- : 0)
894
-
895
- static seq_t ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
896
- {
897
- seq_t seq;
898
-
899
- U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
900
- U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
901
- U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
902
-
903
- U32 const llBits = LL_bits[llCode];
904
- U32 const mlBits = ML_bits[mlCode];
905
- U32 const ofBits = ofCode;
906
- U32 const totalBits = llBits+mlBits+ofBits;
907
-
908
- static const U32 LL_base[MaxLL+1] = {
909
- 0, 1, 2, 3, 4, 5, 6, 7,
910
- 8, 9, 10, 11, 12, 13, 14, 15,
911
- 16, 18, 20, 22, 24, 28, 32, 40,
912
- 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
913
- 0x2000, 0x4000, 0x8000, 0x10000 };
914
-
915
- static const U32 ML_base[MaxML+1] = {
916
- 3, 4, 5, 6, 7, 8, 9, 10,
917
- 11, 12, 13, 14, 15, 16, 17, 18,
918
- 19, 20, 21, 22, 23, 24, 25, 26,
919
- 27, 28, 29, 30, 31, 32, 33, 34,
920
- 35, 37, 39, 41, 43, 47, 51, 59,
921
- 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
922
- 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
923
-
924
- static const U32 OF_base[MaxOff+1] = {
925
- 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
926
- 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
927
- 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
928
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
929
-
930
- /* sequence */
931
- { size_t offset;
932
- if (!ofCode)
933
- offset = 0;
934
- else {
935
- ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
936
- ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
937
- assert(ofBits <= MaxOff);
938
- if (MEM_32bits() && longOffsets) {
939
- U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
940
- offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
941
- if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
942
- if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
943
- } else {
944
- offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
945
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
946
- }
947
- }
948
-
949
- if (ofCode <= 1) {
950
- offset += (llCode==0);
951
- if (offset) {
952
- size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
953
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
954
- if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
955
- seqState->prevOffset[1] = seqState->prevOffset[0];
956
- seqState->prevOffset[0] = offset = temp;
957
- } else {
958
- offset = seqState->prevOffset[0];
959
- }
960
- } else {
961
- seqState->prevOffset[2] = seqState->prevOffset[1];
962
- seqState->prevOffset[1] = seqState->prevOffset[0];
963
- seqState->prevOffset[0] = offset;
964
- }
965
- seq.offset = offset;
966
- }
967
-
968
- seq.matchLength = ML_base[mlCode]
969
- + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
970
- if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
971
- BIT_reloadDStream(&seqState->DStream);
972
- if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
973
- BIT_reloadDStream(&seqState->DStream);
974
- /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
975
- ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
976
-
977
- seq.litLength = LL_base[llCode]
978
- + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
979
- if (MEM_32bits())
980
- BIT_reloadDStream(&seqState->DStream);
981
-
982
- DEBUGLOG(6, "seq: litL=%u, matchL=%u, offset=%u",
983
- (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);
984
-
985
- /* ANS state update */
986
- FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
987
- FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
988
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
989
- FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
990
-
991
- return seq;
992
- }
993
-
994
-
995
- HINT_INLINE
996
- size_t ZSTD_execSequence(BYTE* op,
997
- BYTE* const oend, seq_t sequence,
998
- const BYTE** litPtr, const BYTE* const litLimit,
999
- const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
1000
- {
1001
- BYTE* const oLitEnd = op + sequence.litLength;
1002
- size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1003
- BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1004
- BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
1005
- const BYTE* const iLitEnd = *litPtr + sequence.litLength;
1006
- const BYTE* match = oLitEnd - sequence.offset;
462
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
463
+ if (ZSTD_isLegacy(src, srcSize))
464
+ return ZSTD_findFrameSizeInfoLegacy(src, srcSize);
465
+ #endif
1007
466
 
1008
- /* check */
1009
- if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1010
- if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
1011
- if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
1012
-
1013
- /* copy Literals */
1014
- ZSTD_copy8(op, *litPtr);
1015
- if (sequence.litLength > 8)
1016
- ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1017
- op = oLitEnd;
1018
- *litPtr = iLitEnd; /* update for next sequence */
1019
-
1020
- /* copy Match */
1021
- if (sequence.offset > (size_t)(oLitEnd - base)) {
1022
- /* offset beyond prefix -> go into extDict */
1023
- if (sequence.offset > (size_t)(oLitEnd - vBase))
1024
- return ERROR(corruption_detected);
1025
- match = dictEnd + (match - base);
1026
- if (match + sequence.matchLength <= dictEnd) {
1027
- memmove(oLitEnd, match, sequence.matchLength);
1028
- return sequenceLength;
1029
- }
1030
- /* span extDict & currentPrefixSegment */
1031
- { size_t const length1 = dictEnd - match;
1032
- memmove(oLitEnd, match, length1);
1033
- op = oLitEnd + length1;
1034
- sequence.matchLength -= length1;
1035
- match = base;
1036
- if (op > oend_w || sequence.matchLength < MINMATCH) {
1037
- U32 i;
1038
- for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
1039
- return sequenceLength;
1040
- }
1041
- } }
1042
- /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
1043
-
1044
- /* match within prefix */
1045
- if (sequence.offset < 8) {
1046
- /* close range match, overlap */
1047
- static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
1048
- static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
1049
- int const sub2 = dec64table[sequence.offset];
1050
- op[0] = match[0];
1051
- op[1] = match[1];
1052
- op[2] = match[2];
1053
- op[3] = match[3];
1054
- match += dec32table[sequence.offset];
1055
- ZSTD_copy4(op+4, match);
1056
- match -= sub2;
467
+ if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)
468
+ && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
469
+ frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);
470
+ return frameSizeInfo;
1057
471
  } else {
1058
- ZSTD_copy8(op, match);
1059
- }
1060
- op += 8; match += 8;
472
+ const BYTE* ip = (const BYTE*)src;
473
+ const BYTE* const ipstart = ip;
474
+ size_t remainingSize = srcSize;
475
+ size_t nbBlocks = 0;
476
+ ZSTD_frameHeader zfh;
1061
477
 
1062
- if (oMatchEnd > oend-(16-MINMATCH)) {
1063
- if (op < oend_w) {
1064
- ZSTD_wildcopy(op, match, oend_w - op);
1065
- match += oend_w - op;
1066
- op = oend_w;
478
+ /* Extract Frame Header */
479
+ { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
480
+ if (ZSTD_isError(ret))
481
+ return ZSTD_errorFrameSizeInfo(ret);
482
+ if (ret > 0)
483
+ return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
1067
484
  }
1068
- while (op < oMatchEnd) *op++ = *match++;
1069
- } else {
1070
- ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
1071
- }
1072
- return sequenceLength;
1073
- }
1074
-
1075
-
1076
- static size_t ZSTD_decompressSequences(
1077
- ZSTD_DCtx* dctx,
1078
- void* dst, size_t maxDstSize,
1079
- const void* seqStart, size_t seqSize,
1080
- const ZSTD_longOffset_e isLongOffset)
1081
- {
1082
- const BYTE* ip = (const BYTE*)seqStart;
1083
- const BYTE* const iend = ip + seqSize;
1084
- BYTE* const ostart = (BYTE* const)dst;
1085
- BYTE* const oend = ostart + maxDstSize;
1086
- BYTE* op = ostart;
1087
- const BYTE* litPtr = dctx->litPtr;
1088
- const BYTE* const litEnd = litPtr + dctx->litSize;
1089
- const BYTE* const base = (const BYTE*) (dctx->base);
1090
- const BYTE* const vBase = (const BYTE*) (dctx->vBase);
1091
- const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1092
- int nbSeq;
1093
- DEBUGLOG(5, "ZSTD_decompressSequences");
1094
-
1095
- /* Build Decoding Tables */
1096
- { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1097
- DEBUGLOG(5, "ZSTD_decodeSeqHeaders: size=%u, nbSeq=%i",
1098
- (U32)seqHSize, nbSeq);
1099
- if (ZSTD_isError(seqHSize)) return seqHSize;
1100
- ip += seqHSize;
1101
- }
1102
-
1103
- /* Regen sequences */
1104
- if (nbSeq) {
1105
- seqState_t seqState;
1106
- dctx->fseEntropy = 1;
1107
- { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
1108
- CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
1109
- FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1110
- FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1111
- FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1112
-
1113
- for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
1114
- nbSeq--;
1115
- { seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);
1116
- size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
1117
- DEBUGLOG(6, "regenerated sequence size : %u", (U32)oneSeqSize);
1118
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1119
- op += oneSeqSize;
1120
- } }
1121
485
 
1122
- /* check if reached exact end */
1123
- DEBUGLOG(5, "after decode loop, remaining nbSeq : %i", nbSeq);
1124
- if (nbSeq) return ERROR(corruption_detected);
1125
- /* save reps for next block */
1126
- { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1127
- }
486
+ ip += zfh.headerSize;
487
+ remainingSize -= zfh.headerSize;
1128
488
 
1129
- /* last literal segment */
1130
- { size_t const lastLLSize = litEnd - litPtr;
1131
- if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
1132
- memcpy(op, litPtr, lastLLSize);
1133
- op += lastLLSize;
1134
- }
489
+ /* Iterate over each block */
490
+ while (1) {
491
+ blockProperties_t blockProperties;
492
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
493
+ if (ZSTD_isError(cBlockSize))
494
+ return ZSTD_errorFrameSizeInfo(cBlockSize);
1135
495
 
1136
- return op-ostart;
1137
- }
496
+ if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
497
+ return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
1138
498
 
499
+ ip += ZSTD_blockHeaderSize + cBlockSize;
500
+ remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
501
+ nbBlocks++;
1139
502
 
1140
- HINT_INLINE
1141
- seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)
1142
- {
1143
- seq_t seq;
1144
-
1145
- U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
1146
- U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
1147
- U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= MaxOff, by table construction */
1148
-
1149
- U32 const llBits = LL_bits[llCode];
1150
- U32 const mlBits = ML_bits[mlCode];
1151
- U32 const ofBits = ofCode;
1152
- U32 const totalBits = llBits+mlBits+ofBits;
1153
-
1154
- static const U32 LL_base[MaxLL+1] = {
1155
- 0, 1, 2, 3, 4, 5, 6, 7,
1156
- 8, 9, 10, 11, 12, 13, 14, 15,
1157
- 16, 18, 20, 22, 24, 28, 32, 40,
1158
- 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
1159
- 0x2000, 0x4000, 0x8000, 0x10000 };
1160
-
1161
- static const U32 ML_base[MaxML+1] = {
1162
- 3, 4, 5, 6, 7, 8, 9, 10,
1163
- 11, 12, 13, 14, 15, 16, 17, 18,
1164
- 19, 20, 21, 22, 23, 24, 25, 26,
1165
- 27, 28, 29, 30, 31, 32, 33, 34,
1166
- 35, 37, 39, 41, 43, 47, 51, 59,
1167
- 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
1168
- 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
1169
-
1170
- static const U32 OF_base[MaxOff+1] = {
1171
- 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
1172
- 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
1173
- 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
1174
- 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };
1175
-
1176
- /* sequence */
1177
- { size_t offset;
1178
- if (!ofCode)
1179
- offset = 0;
1180
- else {
1181
- ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);
1182
- ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);
1183
- assert(ofBits <= MaxOff);
1184
- if (MEM_32bits() && longOffsets) {
1185
- U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);
1186
- offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
1187
- if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
1188
- if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
1189
- } else {
1190
- offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
1191
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
1192
- }
503
+ if (blockProperties.lastBlock) break;
1193
504
  }
1194
505
 
1195
- if (ofCode <= 1) {
1196
- offset += (llCode==0);
1197
- if (offset) {
1198
- size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
1199
- temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
1200
- if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
1201
- seqState->prevOffset[1] = seqState->prevOffset[0];
1202
- seqState->prevOffset[0] = offset = temp;
1203
- } else {
1204
- offset = seqState->prevOffset[0];
1205
- }
1206
- } else {
1207
- seqState->prevOffset[2] = seqState->prevOffset[1];
1208
- seqState->prevOffset[1] = seqState->prevOffset[0];
1209
- seqState->prevOffset[0] = offset;
506
+ /* Final frame content checksum */
507
+ if (zfh.checksumFlag) {
508
+ if (remainingSize < 4)
509
+ return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));
510
+ ip += 4;
1210
511
  }
1211
- seq.offset = offset;
1212
- }
1213
512
 
1214
- seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
1215
- if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))
1216
- BIT_reloadDStream(&seqState->DStream);
1217
- if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))
1218
- BIT_reloadDStream(&seqState->DStream);
1219
- /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */
1220
- ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);
1221
-
1222
- seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
1223
- if (MEM_32bits())
1224
- BIT_reloadDStream(&seqState->DStream);
1225
-
1226
- { size_t const pos = seqState->pos + seq.litLength;
1227
- const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;
1228
- seq.match = matchBase + pos - seq.offset; /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.
1229
- * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */
1230
- seqState->pos = pos + seq.matchLength;
513
+ frameSizeInfo.compressedSize = ip - ipstart;
514
+ frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)
515
+ ? zfh.frameContentSize
516
+ : nbBlocks * zfh.blockSizeMax;
517
+ return frameSizeInfo;
1231
518
  }
1232
-
1233
- /* ANS state update */
1234
- FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
1235
- FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
1236
- if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
1237
- FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
1238
-
1239
- return seq;
1240
519
  }
1241
520
 
1242
-
1243
- HINT_INLINE
1244
- size_t ZSTD_execSequenceLong(BYTE* op,
1245
- BYTE* const oend, seq_t sequence,
1246
- const BYTE** litPtr, const BYTE* const litLimit,
1247
- const BYTE* const prefixStart, const BYTE* const dictStart, const BYTE* const dictEnd)
521
+ /** ZSTD_findFrameCompressedSize() :
522
+ * compatible with legacy mode
523
+ * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
524
+ * `srcSize` must be at least as large as the frame contained
525
+ * @return : the compressed size of the frame starting at `src` */
526
+ size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
1248
527
  {
1249
- BYTE* const oLitEnd = op + sequence.litLength;
1250
- size_t const sequenceLength = sequence.litLength + sequence.matchLength;
1251
- BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
1252
- BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
1253
- const BYTE* const iLitEnd = *litPtr + sequence.litLength;
1254
- const BYTE* match = sequence.match;
1255
-
1256
- /* check */
1257
- if (oMatchEnd > oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
1258
- if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
1259
- if (oLitEnd > oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, prefixStart, dictStart, dictEnd);
1260
-
1261
- /* copy Literals */
1262
- ZSTD_copy8(op, *litPtr); /* note : op <= oLitEnd <= oend_w == oend - 8 */
1263
- if (sequence.litLength > 8)
1264
- ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
1265
- op = oLitEnd;
1266
- *litPtr = iLitEnd; /* update for next sequence */
1267
-
1268
- /* copy Match */
1269
- if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {
1270
- /* offset beyond prefix */
1271
- if (sequence.offset > (size_t)(oLitEnd - dictStart)) return ERROR(corruption_detected);
1272
- if (match + sequence.matchLength <= dictEnd) {
1273
- memmove(oLitEnd, match, sequence.matchLength);
1274
- return sequenceLength;
1275
- }
1276
- /* span extDict & currentPrefixSegment */
1277
- { size_t const length1 = dictEnd - match;
1278
- memmove(oLitEnd, match, length1);
1279
- op = oLitEnd + length1;
1280
- sequence.matchLength -= length1;
1281
- match = prefixStart;
1282
- if (op > oend_w || sequence.matchLength < MINMATCH) {
1283
- U32 i;
1284
- for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
1285
- return sequenceLength;
1286
- }
1287
- } }
1288
- assert(op <= oend_w);
1289
- assert(sequence.matchLength >= MINMATCH);
1290
-
1291
- /* match within prefix */
1292
- if (sequence.offset < 8) {
1293
- /* close range match, overlap */
1294
- static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
1295
- static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
1296
- int const sub2 = dec64table[sequence.offset];
1297
- op[0] = match[0];
1298
- op[1] = match[1];
1299
- op[2] = match[2];
1300
- op[3] = match[3];
1301
- match += dec32table[sequence.offset];
1302
- ZSTD_copy4(op+4, match);
1303
- match -= sub2;
1304
- } else {
1305
- ZSTD_copy8(op, match);
1306
- }
1307
- op += 8; match += 8;
1308
-
1309
- if (oMatchEnd > oend-(16-MINMATCH)) {
1310
- if (op < oend_w) {
1311
- ZSTD_wildcopy(op, match, oend_w - op);
1312
- match += oend_w - op;
1313
- op = oend_w;
1314
- }
1315
- while (op < oMatchEnd) *op++ = *match++;
1316
- } else {
1317
- ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
1318
- }
1319
- return sequenceLength;
528
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
529
+ return frameSizeInfo.compressedSize;
1320
530
  }
1321
531
 
1322
- static size_t ZSTD_decompressSequencesLong(
1323
- ZSTD_DCtx* dctx,
1324
- void* dst, size_t maxDstSize,
1325
- const void* seqStart, size_t seqSize,
1326
- const ZSTD_longOffset_e isLongOffset)
1327
- {
1328
- const BYTE* ip = (const BYTE*)seqStart;
1329
- const BYTE* const iend = ip + seqSize;
1330
- BYTE* const ostart = (BYTE* const)dst;
1331
- BYTE* const oend = ostart + maxDstSize;
1332
- BYTE* op = ostart;
1333
- const BYTE* litPtr = dctx->litPtr;
1334
- const BYTE* const litEnd = litPtr + dctx->litSize;
1335
- const BYTE* const prefixStart = (const BYTE*) (dctx->base);
1336
- const BYTE* const dictStart = (const BYTE*) (dctx->vBase);
1337
- const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
1338
- int nbSeq;
1339
-
1340
- /* Build Decoding Tables */
1341
- { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
1342
- if (ZSTD_isError(seqHSize)) return seqHSize;
1343
- ip += seqHSize;
1344
- }
1345
-
1346
- /* Regen sequences */
1347
- if (nbSeq) {
1348
- #define STORED_SEQS 4
1349
- #define STOSEQ_MASK (STORED_SEQS-1)
1350
- #define ADVANCED_SEQS 4
1351
- seq_t sequences[STORED_SEQS];
1352
- int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
1353
- seqState_t seqState;
1354
- int seqNb;
1355
- dctx->fseEntropy = 1;
1356
- { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
1357
- seqState.prefixStart = prefixStart;
1358
- seqState.pos = (size_t)(op-prefixStart);
1359
- seqState.dictEnd = dictEnd;
1360
- CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
1361
- FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
1362
- FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
1363
- FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
1364
-
1365
- /* prepare in advance */
1366
- for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) {
1367
- sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
1368
- }
1369
- if (seqNb<seqAdvance) return ERROR(corruption_detected);
1370
-
1371
- /* decode and decompress */
1372
- for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) {
1373
- seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, isLongOffset);
1374
- size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
1375
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1376
- PREFETCH(sequence.match); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */
1377
- sequences[seqNb&STOSEQ_MASK] = sequence;
1378
- op += oneSeqSize;
1379
- }
1380
- if (seqNb<nbSeq) return ERROR(corruption_detected);
1381
-
1382
- /* finish queue */
1383
- seqNb -= seqAdvance;
1384
- for ( ; seqNb<nbSeq ; seqNb++) {
1385
- size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb&STOSEQ_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);
1386
- if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
1387
- op += oneSeqSize;
1388
- }
1389
532
 
1390
- /* save reps for next block */
1391
- { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
1392
- }
1393
-
1394
- /* last literal segment */
1395
- { size_t const lastLLSize = litEnd - litPtr;
1396
- if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
1397
- memcpy(op, litPtr, lastLLSize);
1398
- op += lastLLSize;
533
+ /** ZSTD_decompressBound() :
534
+ * compatible with legacy mode
535
+ * `src` must point to the start of a ZSTD frame or a skippeable frame
536
+ * `srcSize` must be at least as large as the frame contained
537
+ * @return : the maximum decompressed size of the compressed source
538
+ */
539
+ unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)
540
+ {
541
+ unsigned long long bound = 0;
542
+ /* Iterate over each frame */
543
+ while (srcSize > 0) {
544
+ ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);
545
+ size_t const compressedSize = frameSizeInfo.compressedSize;
546
+ unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;
547
+ if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)
548
+ return ZSTD_CONTENTSIZE_ERROR;
549
+ src = (const BYTE*)src + compressedSize;
550
+ srcSize -= compressedSize;
551
+ bound += decompressedBound;
1399
552
  }
1400
-
1401
- return op-ostart;
553
+ return bound;
1402
554
  }
1403
555
 
1404
556
 
1405
- static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
1406
- void* dst, size_t dstCapacity,
1407
- const void* src, size_t srcSize, const int frame)
1408
- { /* blockType == blockCompressed */
1409
- const BYTE* ip = (const BYTE*)src;
1410
- /* isLongOffset must be true if there are long offsets.
1411
- * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.
1412
- * We don't expect that to be the case in 64-bit mode.
1413
- * If we are in block mode we don't know the window size, so we have to be
1414
- * conservative.
1415
- */
1416
- ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN)));
1417
- /* windowSize could be any value at this point, since it is only validated
1418
- * in the streaming API.
1419
- */
1420
- DEBUGLOG(5, "ZSTD_decompressBlock_internal (size : %u)", (U32)srcSize);
1421
-
1422
- if (srcSize >= ZSTD_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);
1423
-
1424
- /* Decode literals section */
1425
- { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
1426
- DEBUGLOG(5, "ZSTD_decodeLiteralsBlock : %u", (U32)litCSize);
1427
- if (ZSTD_isError(litCSize)) return litCSize;
1428
- ip += litCSize;
1429
- srcSize -= litCSize;
1430
- }
1431
- if (frame && dctx->fParams.windowSize > (1<<23))
1432
- return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
1433
- return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, isLongOffset);
1434
- }
557
+ /*-*************************************************************
558
+ * Frame decoding
559
+ ***************************************************************/
1435
560
 
1436
561
 
1437
- static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
562
+ void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
1438
563
  {
1439
564
  if (dst != dctx->previousDstEnd) { /* not contiguous */
1440
565
  dctx->dictEnd = dctx->previousDstEnd;
1441
- dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1442
- dctx->base = dst;
566
+ dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
567
+ dctx->prefixStart = dst;
1443
568
  dctx->previousDstEnd = dst;
1444
569
  }
1445
570
  }
1446
571
 
1447
- size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
1448
- void* dst, size_t dstCapacity,
1449
- const void* src, size_t srcSize)
1450
- {
1451
- size_t dSize;
1452
- ZSTD_checkContinuity(dctx, dst);
1453
- dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);
1454
- dctx->previousDstEnd = (char*)dst + dSize;
1455
- return dSize;
1456
- }
1457
-
1458
-
1459
572
  /** ZSTD_insertBlock() :
1460
573
  insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
1461
- ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
574
+ size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
1462
575
  {
1463
576
  ZSTD_checkContinuity(dctx, blockStart);
1464
577
  dctx->previousDstEnd = (const char*)blockStart + blockSize;
@@ -1466,69 +579,37 @@ ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, siz
1466
579
  }
1467
580
 
1468
581
 
1469
- static size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
582
+ static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
583
+ const void* src, size_t srcSize)
1470
584
  {
1471
- if (length > dstCapacity) return ERROR(dstSize_tooSmall);
1472
- memset(dst, byte, length);
1473
- return length;
585
+ DEBUGLOG(5, "ZSTD_copyRawBlock");
586
+ if (dst == NULL) {
587
+ if (srcSize == 0) return 0;
588
+ RETURN_ERROR(dstBuffer_null);
589
+ }
590
+ RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall);
591
+ memcpy(dst, src, srcSize);
592
+ return srcSize;
1474
593
  }
1475
594
 
1476
- /** ZSTD_findFrameCompressedSize() :
1477
- * compatible with legacy mode
1478
- * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
1479
- * `srcSize` must be at least as large as the frame contained
1480
- * @return : the compressed size of the frame starting at `src` */
1481
- size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
595
+ static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
596
+ BYTE b,
597
+ size_t regenSize)
1482
598
  {
1483
- #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1484
- if (ZSTD_isLegacy(src, srcSize))
1485
- return ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
1486
- #endif
1487
- if ( (srcSize >= ZSTD_skippableHeaderSize)
1488
- && (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START ) {
1489
- return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize);
1490
- } else {
1491
- const BYTE* ip = (const BYTE*)src;
1492
- const BYTE* const ipstart = ip;
1493
- size_t remainingSize = srcSize;
1494
- ZSTD_frameHeader zfh;
1495
-
1496
- /* Extract Frame Header */
1497
- { size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);
1498
- if (ZSTD_isError(ret)) return ret;
1499
- if (ret > 0) return ERROR(srcSize_wrong);
1500
- }
1501
-
1502
- ip += zfh.headerSize;
1503
- remainingSize -= zfh.headerSize;
1504
-
1505
- /* Loop on each block */
1506
- while (1) {
1507
- blockProperties_t blockProperties;
1508
- size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
1509
- if (ZSTD_isError(cBlockSize)) return cBlockSize;
1510
-
1511
- if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)
1512
- return ERROR(srcSize_wrong);
1513
-
1514
- ip += ZSTD_blockHeaderSize + cBlockSize;
1515
- remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
1516
-
1517
- if (blockProperties.lastBlock) break;
1518
- }
1519
-
1520
- if (zfh.checksumFlag) { /* Final frame content checksum */
1521
- if (remainingSize < 4) return ERROR(srcSize_wrong);
1522
- ip += 4;
1523
- remainingSize -= 4;
1524
- }
1525
-
1526
- return ip - ipstart;
599
+ if (dst == NULL) {
600
+ if (regenSize == 0) return 0;
601
+ RETURN_ERROR(dstBuffer_null);
1527
602
  }
603
+ RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall);
604
+ memset(dst, b, regenSize);
605
+ return regenSize;
1528
606
  }
1529
607
 
608
+
1530
609
  /*! ZSTD_decompressFrame() :
1531
- * @dctx must be properly initialized */
610
+ * @dctx must be properly initialized
611
+ * will update *srcPtr and *srcSizePtr,
612
+ * to make *srcPtr progress by one frame. */
1532
613
  static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1533
614
  void* dst, size_t dstCapacity,
1534
615
  const void** srcPtr, size_t *srcSizePtr)
@@ -1537,31 +618,34 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1537
618
  BYTE* const ostart = (BYTE* const)dst;
1538
619
  BYTE* const oend = ostart + dstCapacity;
1539
620
  BYTE* op = ostart;
1540
- size_t remainingSize = *srcSizePtr;
621
+ size_t remainingSrcSize = *srcSizePtr;
622
+
623
+ DEBUGLOG(4, "ZSTD_decompressFrame (srcSize:%i)", (int)*srcSizePtr);
1541
624
 
1542
625
  /* check */
1543
- if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize)
1544
- return ERROR(srcSize_wrong);
626
+ RETURN_ERROR_IF(
627
+ remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN+ZSTD_blockHeaderSize,
628
+ srcSize_wrong);
1545
629
 
1546
630
  /* Frame Header */
1547
- { size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
631
+ { size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_FRAMEHEADERSIZE_PREFIX);
1548
632
  if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
1549
- if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize)
1550
- return ERROR(srcSize_wrong);
1551
- CHECK_F( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) );
1552
- ip += frameHeaderSize; remainingSize -= frameHeaderSize;
633
+ RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,
634
+ srcSize_wrong);
635
+ FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) );
636
+ ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;
1553
637
  }
1554
638
 
1555
639
  /* Loop on each block */
1556
640
  while (1) {
1557
641
  size_t decodedSize;
1558
642
  blockProperties_t blockProperties;
1559
- size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
643
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);
1560
644
  if (ZSTD_isError(cBlockSize)) return cBlockSize;
1561
645
 
1562
646
  ip += ZSTD_blockHeaderSize;
1563
- remainingSize -= ZSTD_blockHeaderSize;
1564
- if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
647
+ remainingSrcSize -= ZSTD_blockHeaderSize;
648
+ RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong);
1565
649
 
1566
650
  switch(blockProperties.blockType)
1567
651
  {
@@ -1572,11 +656,11 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1572
656
  decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
1573
657
  break;
1574
658
  case bt_rle :
1575
- decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
659
+ decodedSize = ZSTD_setRleBlock(op, oend-op, *ip, blockProperties.origSize);
1576
660
  break;
1577
661
  case bt_reserved :
1578
662
  default:
1579
- return ERROR(corruption_detected);
663
+ RETURN_ERROR(corruption_detected);
1580
664
  }
1581
665
 
1582
666
  if (ZSTD_isError(decodedSize)) return decodedSize;
@@ -1584,33 +668,30 @@ static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
1584
668
  XXH64_update(&dctx->xxhState, op, decodedSize);
1585
669
  op += decodedSize;
1586
670
  ip += cBlockSize;
1587
- remainingSize -= cBlockSize;
671
+ remainingSrcSize -= cBlockSize;
1588
672
  if (blockProperties.lastBlock) break;
1589
673
  }
1590
674
 
1591
675
  if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1592
- if ((U64)(op-ostart) != dctx->fParams.frameContentSize) {
1593
- return ERROR(corruption_detected);
1594
- } }
676
+ RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,
677
+ corruption_detected);
678
+ }
1595
679
  if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
1596
680
  U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
1597
681
  U32 checkRead;
1598
- if (remainingSize<4) return ERROR(checksum_wrong);
682
+ RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong);
1599
683
  checkRead = MEM_readLE32(ip);
1600
- if (checkRead != checkCalc) return ERROR(checksum_wrong);
684
+ RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong);
1601
685
  ip += 4;
1602
- remainingSize -= 4;
686
+ remainingSrcSize -= 4;
1603
687
  }
1604
688
 
1605
689
  /* Allow caller to get size read */
1606
690
  *srcPtr = ip;
1607
- *srcSizePtr = remainingSize;
691
+ *srcSizePtr = remainingSrcSize;
1608
692
  return op-ostart;
1609
693
  }
1610
694
 
1611
- static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict);
1612
- static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict);
1613
-
1614
695
  static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1615
696
  void* dst, size_t dstCapacity,
1616
697
  const void* src, size_t srcSize,
@@ -1618,26 +699,30 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1618
699
  const ZSTD_DDict* ddict)
1619
700
  {
1620
701
  void* const dststart = dst;
702
+ int moreThan1Frame = 0;
703
+
704
+ DEBUGLOG(5, "ZSTD_decompressMultiFrame");
1621
705
  assert(dict==NULL || ddict==NULL); /* either dict or ddict set, not both */
1622
706
 
1623
707
  if (ddict) {
1624
- dict = ZSTD_DDictDictContent(ddict);
1625
- dictSize = ZSTD_DDictDictSize(ddict);
708
+ dict = ZSTD_DDict_dictContent(ddict);
709
+ dictSize = ZSTD_DDict_dictSize(ddict);
1626
710
  }
1627
711
 
1628
- while (srcSize >= ZSTD_frameHeaderSize_prefix) {
1629
- U32 magicNumber;
712
+ while (srcSize >= ZSTD_FRAMEHEADERSIZE_PREFIX) {
1630
713
 
1631
714
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
1632
715
  if (ZSTD_isLegacy(src, srcSize)) {
1633
716
  size_t decodedSize;
1634
717
  size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
1635
718
  if (ZSTD_isError(frameSize)) return frameSize;
1636
- /* legacy support is not compatible with static dctx */
1637
- if (dctx->staticSize) return ERROR(memory_allocation);
719
+ RETURN_ERROR_IF(dctx->staticSize, memory_allocation,
720
+ "legacy support is not compatible with static dctx");
1638
721
 
1639
722
  decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
723
+ if (ZSTD_isError(decodedSize)) return decodedSize;
1640
724
 
725
+ assert(decodedSize <=- dstCapacity);
1641
726
  dst = (BYTE*)dst + decodedSize;
1642
727
  dstCapacity -= decodedSize;
1643
728
 
@@ -1648,45 +733,54 @@ static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
1648
733
  }
1649
734
  #endif
1650
735
 
1651
- magicNumber = MEM_readLE32(src);
1652
- DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
1653
- (U32)magicNumber, (U32)ZSTD_MAGICNUMBER);
1654
- if (magicNumber != ZSTD_MAGICNUMBER) {
1655
- if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
1656
- size_t skippableSize;
1657
- if (srcSize < ZSTD_skippableHeaderSize)
1658
- return ERROR(srcSize_wrong);
1659
- skippableSize = MEM_readLE32((const BYTE*)src + ZSTD_frameIdSize)
1660
- + ZSTD_skippableHeaderSize;
1661
- if (srcSize < skippableSize) return ERROR(srcSize_wrong);
736
+ { U32 const magicNumber = MEM_readLE32(src);
737
+ DEBUGLOG(4, "reading magic number %08X (expecting %08X)",
738
+ (unsigned)magicNumber, ZSTD_MAGICNUMBER);
739
+ if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {
740
+ size_t const skippableSize = readSkippableFrameSize(src, srcSize);
741
+ if (ZSTD_isError(skippableSize))
742
+ return skippableSize;
743
+ RETURN_ERROR_IF(srcSize < skippableSize, srcSize_wrong);
1662
744
 
1663
745
  src = (const BYTE *)src + skippableSize;
1664
746
  srcSize -= skippableSize;
1665
747
  continue;
1666
- }
1667
- return ERROR(prefix_unknown);
1668
- }
748
+ } }
1669
749
 
1670
750
  if (ddict) {
1671
751
  /* we were called from ZSTD_decompress_usingDDict */
1672
- CHECK_F(ZSTD_decompressBegin_usingDDict(dctx, ddict));
752
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict));
1673
753
  } else {
1674
754
  /* this will initialize correctly with no dict if dict == NULL, so
1675
755
  * use this in all cases but ddict */
1676
- CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
756
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
1677
757
  }
1678
758
  ZSTD_checkContinuity(dctx, dst);
1679
759
 
1680
760
  { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
1681
761
  &src, &srcSize);
762
+ RETURN_ERROR_IF(
763
+ (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)
764
+ && (moreThan1Frame==1),
765
+ srcSize_wrong,
766
+ "at least one frame successfully completed, but following "
767
+ "bytes are garbage: it's more likely to be a srcSize error, "
768
+ "specifying more bytes than compressed size of frame(s). This "
769
+ "error message replaces ERROR(prefix_unknown), which would be "
770
+ "confusing, as the first header is actually correct. Note that "
771
+ "one could be unlucky, it might be a corruption error instead, "
772
+ "happening right at the place where we expect zstd magic "
773
+ "bytes. But this is _much_ less likely than a srcSize field "
774
+ "error.");
1682
775
  if (ZSTD_isError(res)) return res;
1683
- /* no need to bound check, ZSTD_decompressFrame already has */
776
+ assert(res <= dstCapacity);
1684
777
  dst = (BYTE*)dst + res;
1685
778
  dstCapacity -= res;
1686
779
  }
780
+ moreThan1Frame = 1;
1687
781
  } /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */
1688
782
 
1689
- if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */
783
+ RETURN_ERROR_IF(srcSize, srcSize_wrong, "input not entirely consumed");
1690
784
 
1691
785
  return (BYTE*)dst - (BYTE*)dststart;
1692
786
  }
@@ -1700,9 +794,26 @@ size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
1700
794
  }
1701
795
 
1702
796
 
797
+ static ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)
798
+ {
799
+ switch (dctx->dictUses) {
800
+ default:
801
+ assert(0 /* Impossible */);
802
+ /* fall-through */
803
+ case ZSTD_dont_use:
804
+ ZSTD_clearDict(dctx);
805
+ return NULL;
806
+ case ZSTD_use_indefinitely:
807
+ return dctx->ddict;
808
+ case ZSTD_use_once:
809
+ dctx->dictUses = ZSTD_dont_use;
810
+ return dctx->ddict;
811
+ }
812
+ }
813
+
1703
814
  size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1704
815
  {
1705
- return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
816
+ return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));
1706
817
  }
1707
818
 
1708
819
 
@@ -1711,12 +822,13 @@ size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t sr
1711
822
  #if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)
1712
823
  size_t regenSize;
1713
824
  ZSTD_DCtx* const dctx = ZSTD_createDCtx();
1714
- if (dctx==NULL) return ERROR(memory_allocation);
825
+ RETURN_ERROR_IF(dctx==NULL, memory_allocation);
1715
826
  regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
1716
827
  ZSTD_freeDCtx(dctx);
1717
828
  return regenSize;
1718
829
  #else /* stack mode */
1719
830
  ZSTD_DCtx dctx;
831
+ ZSTD_initDCtx_internal(&dctx);
1720
832
  return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
1721
833
  #endif
1722
834
  }
@@ -1758,9 +870,9 @@ static int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skip
1758
870
  * or an error code, which can be tested using ZSTD_isError() */
1759
871
  size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
1760
872
  {
1761
- DEBUGLOG(5, "ZSTD_decompressContinue");
873
+ DEBUGLOG(5, "ZSTD_decompressContinue (srcSize:%u)", (unsigned)srcSize);
1762
874
  /* Sanity check */
1763
- if (srcSize != dctx->expected) return ERROR(srcSize_wrong); /* not allowed */
875
+ RETURN_ERROR_IF(srcSize != dctx->expected, srcSize_wrong, "not allowed");
1764
876
  if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
1765
877
 
1766
878
  switch (dctx->stage)
@@ -1768,10 +880,10 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1768
880
  case ZSTDds_getFrameHeaderSize :
1769
881
  assert(src != NULL);
1770
882
  if (dctx->format == ZSTD_f_zstd1) { /* allows header */
1771
- assert(srcSize >= ZSTD_frameIdSize); /* to read skippable magic number */
1772
- if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
883
+ assert(srcSize >= ZSTD_FRAMEIDSIZE); /* to read skippable magic number */
884
+ if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1773
885
  memcpy(dctx->headerBuffer, src, srcSize);
1774
- dctx->expected = ZSTD_skippableHeaderSize - srcSize; /* remaining to load to get full skippable frame header */
886
+ dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize; /* remaining to load to get full skippable frame header */
1775
887
  dctx->stage = ZSTDds_decodeSkippableHeader;
1776
888
  return 0;
1777
889
  } }
@@ -1785,7 +897,7 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1785
897
  case ZSTDds_decodeFrameHeader:
1786
898
  assert(src != NULL);
1787
899
  memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);
1788
- CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
900
+ FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
1789
901
  dctx->expected = ZSTD_blockHeaderSize;
1790
902
  dctx->stage = ZSTDds_decodeBlockHeader;
1791
903
  return 0;
@@ -1819,35 +931,35 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1819
931
 
1820
932
  case ZSTDds_decompressLastBlock:
1821
933
  case ZSTDds_decompressBlock:
1822
- DEBUGLOG(5, "case ZSTDds_decompressBlock");
934
+ DEBUGLOG(5, "ZSTD_decompressContinue: case ZSTDds_decompressBlock");
1823
935
  { size_t rSize;
1824
936
  switch(dctx->bType)
1825
937
  {
1826
938
  case bt_compressed:
1827
- DEBUGLOG(5, "case bt_compressed");
939
+ DEBUGLOG(5, "ZSTD_decompressContinue: case bt_compressed");
1828
940
  rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);
1829
941
  break;
1830
942
  case bt_raw :
1831
943
  rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
1832
944
  break;
1833
945
  case bt_rle :
1834
- rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
946
+ rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);
1835
947
  break;
1836
948
  case bt_reserved : /* should never happen */
1837
949
  default:
1838
- return ERROR(corruption_detected);
950
+ RETURN_ERROR(corruption_detected);
1839
951
  }
1840
952
  if (ZSTD_isError(rSize)) return rSize;
1841
- DEBUGLOG(5, "decoded size from block : %u", (U32)rSize);
953
+ DEBUGLOG(5, "ZSTD_decompressContinue: decoded size from block : %u", (unsigned)rSize);
1842
954
  dctx->decodedSize += rSize;
1843
955
  if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
1844
956
 
1845
957
  if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
1846
- DEBUGLOG(4, "decoded size from frame : %u", (U32)dctx->decodedSize);
1847
- if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {
1848
- if (dctx->decodedSize != dctx->fParams.frameContentSize) {
1849
- return ERROR(corruption_detected);
1850
- } }
958
+ DEBUGLOG(4, "ZSTD_decompressContinue: decoded size from frame : %u", (unsigned)dctx->decodedSize);
959
+ RETURN_ERROR_IF(
960
+ dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN
961
+ && dctx->decodedSize != dctx->fParams.frameContentSize,
962
+ corruption_detected);
1851
963
  if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
1852
964
  dctx->expected = 4;
1853
965
  dctx->stage = ZSTDds_checkChecksum;
@@ -1867,8 +979,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1867
979
  assert(srcSize == 4); /* guaranteed by dctx->expected */
1868
980
  { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
1869
981
  U32 const check32 = MEM_readLE32(src);
1870
- DEBUGLOG(4, "checksum : calculated %08X :: %08X read", h32, check32);
1871
- if (check32 != h32) return ERROR(checksum_wrong);
982
+ DEBUGLOG(4, "ZSTD_decompressContinue: checksum : calculated %08X :: %08X read", (unsigned)h32, (unsigned)check32);
983
+ RETURN_ERROR_IF(check32 != h32, checksum_wrong);
1872
984
  dctx->expected = 0;
1873
985
  dctx->stage = ZSTDds_getFrameHeaderSize;
1874
986
  return 0;
@@ -1876,9 +988,9 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1876
988
 
1877
989
  case ZSTDds_decodeSkippableHeader:
1878
990
  assert(src != NULL);
1879
- assert(srcSize <= ZSTD_skippableHeaderSize);
1880
- memcpy(dctx->headerBuffer + (ZSTD_skippableHeaderSize - srcSize), src, srcSize); /* complete skippable header */
1881
- dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_frameIdSize); /* note : dctx->expected can grow seriously large, beyond local buffer size */
991
+ assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);
992
+ memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize); /* complete skippable header */
993
+ dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE); /* note : dctx->expected can grow seriously large, beyond local buffer size */
1882
994
  dctx->stage = ZSTDds_skipFrame;
1883
995
  return 0;
1884
996
 
@@ -1888,7 +1000,8 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1888
1000
  return 0;
1889
1001
 
1890
1002
  default:
1891
- return ERROR(GENERIC); /* impossible */
1003
+ assert(0); /* impossible */
1004
+ RETURN_ERROR(GENERIC); /* some compiler require default to do something */
1892
1005
  }
1893
1006
  }
1894
1007
 
@@ -1896,64 +1009,91 @@ size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, c
1896
1009
  static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1897
1010
  {
1898
1011
  dctx->dictEnd = dctx->previousDstEnd;
1899
- dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
1900
- dctx->base = dict;
1012
+ dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));
1013
+ dctx->prefixStart = dict;
1901
1014
  dctx->previousDstEnd = (const char*)dict + dictSize;
1902
1015
  return 0;
1903
1016
  }
1904
1017
 
1905
- /* ZSTD_loadEntropy() :
1906
- * dict : must point at beginning of a valid zstd dictionary
1018
+ /*! ZSTD_loadDEntropy() :
1019
+ * dict : must point at beginning of a valid zstd dictionary.
1907
1020
  * @return : size of entropy tables read */
1908
- static size_t ZSTD_loadEntropy(ZSTD_entropyDTables_t* entropy, const void* const dict, size_t const dictSize)
1021
+ size_t
1022
+ ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,
1023
+ const void* const dict, size_t const dictSize)
1909
1024
  {
1910
1025
  const BYTE* dictPtr = (const BYTE*)dict;
1911
1026
  const BYTE* const dictEnd = dictPtr + dictSize;
1912
1027
 
1913
- if (dictSize <= 8) return ERROR(dictionary_corrupted);
1028
+ RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted);
1029
+ assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY); /* dict must be valid */
1914
1030
  dictPtr += 8; /* skip header = magic + dictID */
1915
1031
 
1916
-
1917
- { size_t const hSize = HUF_readDTableX4_wksp(
1918
- entropy->hufTable, dictPtr, dictEnd - dictPtr,
1919
- entropy->workspace, sizeof(entropy->workspace));
1920
- if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
1032
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable));
1033
+ ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable));
1034
+ ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE);
1035
+ { void* const workspace = &entropy->LLTable; /* use fse tables as temporary workspace; implies fse tables are grouped together */
1036
+ size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable);
1037
+ #ifdef HUF_FORCE_DECOMPRESS_X1
1038
+ /* in minimal huffman, we always use X1 variants */
1039
+ size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,
1040
+ dictPtr, dictEnd - dictPtr,
1041
+ workspace, workspaceSize);
1042
+ #else
1043
+ size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,
1044
+ dictPtr, dictEnd - dictPtr,
1045
+ workspace, workspaceSize);
1046
+ #endif
1047
+ RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted);
1921
1048
  dictPtr += hSize;
1922
1049
  }
1923
1050
 
1924
1051
  { short offcodeNCount[MaxOff+1];
1925
- U32 offcodeMaxValue = MaxOff, offcodeLog;
1052
+ unsigned offcodeMaxValue = MaxOff, offcodeLog;
1926
1053
  size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
1927
- if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
1928
- if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
1929
- CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
1054
+ RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);
1055
+ RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted);
1056
+ RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);
1057
+ ZSTD_buildFSETable( entropy->OFTable,
1058
+ offcodeNCount, offcodeMaxValue,
1059
+ OF_base, OF_bits,
1060
+ offcodeLog);
1930
1061
  dictPtr += offcodeHeaderSize;
1931
1062
  }
1932
1063
 
1933
1064
  { short matchlengthNCount[MaxML+1];
1934
1065
  unsigned matchlengthMaxValue = MaxML, matchlengthLog;
1935
1066
  size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
1936
- if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
1937
- if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
1938
- CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
1067
+ RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);
1068
+ RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted);
1069
+ RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);
1070
+ ZSTD_buildFSETable( entropy->MLTable,
1071
+ matchlengthNCount, matchlengthMaxValue,
1072
+ ML_base, ML_bits,
1073
+ matchlengthLog);
1939
1074
  dictPtr += matchlengthHeaderSize;
1940
1075
  }
1941
1076
 
1942
1077
  { short litlengthNCount[MaxLL+1];
1943
1078
  unsigned litlengthMaxValue = MaxLL, litlengthLog;
1944
1079
  size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
1945
- if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
1946
- if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
1947
- CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
1080
+ RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);
1081
+ RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted);
1082
+ RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);
1083
+ ZSTD_buildFSETable( entropy->LLTable,
1084
+ litlengthNCount, litlengthMaxValue,
1085
+ LL_base, LL_bits,
1086
+ litlengthLog);
1948
1087
  dictPtr += litlengthHeaderSize;
1949
1088
  }
1950
1089
 
1951
- if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
1090
+ RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);
1952
1091
  { int i;
1953
1092
  size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
1954
1093
  for (i=0; i<3; i++) {
1955
1094
  U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
1956
- if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted);
1095
+ RETURN_ERROR_IF(rep==0 || rep >= dictContentSize,
1096
+ dictionary_corrupted);
1957
1097
  entropy->rep[i] = rep;
1958
1098
  } }
1959
1099
 
@@ -1967,11 +1107,11 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
1967
1107
  if (magic != ZSTD_MAGIC_DICTIONARY) {
1968
1108
  return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
1969
1109
  } }
1970
- dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
1110
+ dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
1971
1111
 
1972
1112
  /* load entropy tables */
1973
- { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
1974
- if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
1113
+ { size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);
1114
+ RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted);
1975
1115
  dict = (const char*)dict + eSize;
1976
1116
  dictSize -= eSize;
1977
1117
  }
@@ -1981,7 +1121,6 @@ static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict
1981
1121
  return ZSTD_refDictContent(dctx, dict, dictSize);
1982
1122
  }
1983
1123
 
1984
- /* Note : this function cannot fail */
1985
1124
  size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1986
1125
  {
1987
1126
  assert(dctx != NULL);
@@ -1989,8 +1128,8 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
1989
1128
  dctx->stage = ZSTDds_getFrameHeaderSize;
1990
1129
  dctx->decodedSize = 0;
1991
1130
  dctx->previousDstEnd = NULL;
1992
- dctx->base = NULL;
1993
- dctx->vBase = NULL;
1131
+ dctx->prefixStart = NULL;
1132
+ dctx->virtualStart = NULL;
1994
1133
  dctx->dictEnd = NULL;
1995
1134
  dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
1996
1135
  dctx->litEntropy = dctx->fseEntropy = 0;
@@ -2006,183 +1145,36 @@ size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
2006
1145
 
2007
1146
  size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
2008
1147
  {
2009
- CHECK_F( ZSTD_decompressBegin(dctx) );
1148
+ FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
2010
1149
  if (dict && dictSize)
2011
- CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
1150
+ RETURN_ERROR_IF(
1151
+ ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),
1152
+ dictionary_corrupted);
2012
1153
  return 0;
2013
1154
  }
2014
1155
 
2015
1156
 
2016
1157
  /* ====== ZSTD_DDict ====== */
2017
1158
 
2018
- struct ZSTD_DDict_s {
2019
- void* dictBuffer;
2020
- const void* dictContent;
2021
- size_t dictSize;
2022
- ZSTD_entropyDTables_t entropy;
2023
- U32 dictID;
2024
- U32 entropyPresent;
2025
- ZSTD_customMem cMem;
2026
- }; /* typedef'd to ZSTD_DDict within "zstd.h" */
2027
-
2028
- static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict)
2029
- {
2030
- return ddict->dictContent;
2031
- }
2032
-
2033
- static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict)
2034
- {
2035
- return ddict->dictSize;
2036
- }
2037
-
2038
- size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
2039
- {
2040
- CHECK_F( ZSTD_decompressBegin(dstDCtx) );
2041
- if (ddict) { /* support begin on NULL */
2042
- dstDCtx->dictID = ddict->dictID;
2043
- dstDCtx->base = ddict->dictContent;
2044
- dstDCtx->vBase = ddict->dictContent;
2045
- dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
2046
- dstDCtx->previousDstEnd = dstDCtx->dictEnd;
2047
- if (ddict->entropyPresent) {
2048
- dstDCtx->litEntropy = 1;
2049
- dstDCtx->fseEntropy = 1;
2050
- dstDCtx->LLTptr = ddict->entropy.LLTable;
2051
- dstDCtx->MLTptr = ddict->entropy.MLTable;
2052
- dstDCtx->OFTptr = ddict->entropy.OFTable;
2053
- dstDCtx->HUFptr = ddict->entropy.hufTable;
2054
- dstDCtx->entropy.rep[0] = ddict->entropy.rep[0];
2055
- dstDCtx->entropy.rep[1] = ddict->entropy.rep[1];
2056
- dstDCtx->entropy.rep[2] = ddict->entropy.rep[2];
2057
- } else {
2058
- dstDCtx->litEntropy = 0;
2059
- dstDCtx->fseEntropy = 0;
2060
- }
2061
- }
2062
- return 0;
2063
- }
2064
-
2065
- static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
1159
+ size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
2066
1160
  {
2067
- ddict->dictID = 0;
2068
- ddict->entropyPresent = 0;
2069
- if (ddict->dictSize < 8) return 0;
2070
- { U32 const magic = MEM_readLE32(ddict->dictContent);
2071
- if (magic != ZSTD_MAGIC_DICTIONARY) return 0; /* pure content mode */
1161
+ DEBUGLOG(4, "ZSTD_decompressBegin_usingDDict");
1162
+ assert(dctx != NULL);
1163
+ if (ddict) {
1164
+ const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);
1165
+ size_t const dictSize = ZSTD_DDict_dictSize(ddict);
1166
+ const void* const dictEnd = dictStart + dictSize;
1167
+ dctx->ddictIsCold = (dctx->dictEnd != dictEnd);
1168
+ DEBUGLOG(4, "DDict is %s",
1169
+ dctx->ddictIsCold ? "~cold~" : "hot!");
2072
1170
  }
2073
- ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_frameIdSize);
2074
-
2075
- /* load entropy tables */
2076
- CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
2077
- ddict->entropyPresent = 1;
2078
- return 0;
2079
- }
2080
-
2081
-
2082
- static size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
2083
- {
2084
- if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {
2085
- ddict->dictBuffer = NULL;
2086
- ddict->dictContent = dict;
2087
- } else {
2088
- void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);
2089
- ddict->dictBuffer = internalBuffer;
2090
- ddict->dictContent = internalBuffer;
2091
- if (!internalBuffer) return ERROR(memory_allocation);
2092
- memcpy(internalBuffer, dict, dictSize);
1171
+ FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );
1172
+ if (ddict) { /* NULL ddict is equivalent to no dictionary */
1173
+ ZSTD_copyDDictParameters(dctx, ddict);
2093
1174
  }
2094
- ddict->dictSize = dictSize;
2095
- ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
2096
-
2097
- /* parse dictionary content */
2098
- CHECK_F( ZSTD_loadEntropy_inDDict(ddict) );
2099
-
2100
1175
  return 0;
2101
1176
  }
2102
1177
 
2103
- ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_customMem customMem)
2104
- {
2105
- if (!customMem.customAlloc ^ !customMem.customFree) return NULL;
2106
-
2107
- { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
2108
- if (!ddict) return NULL;
2109
- ddict->cMem = customMem;
2110
-
2111
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, dictLoadMethod) )) {
2112
- ZSTD_freeDDict(ddict);
2113
- return NULL;
2114
- }
2115
-
2116
- return ddict;
2117
- }
2118
- }
2119
-
2120
- /*! ZSTD_createDDict() :
2121
- * Create a digested dictionary, to start decompression without startup delay.
2122
- * `dict` content is copied inside DDict.
2123
- * Consequently, `dict` can be released after `ZSTD_DDict` creation */
2124
- ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
2125
- {
2126
- ZSTD_customMem const allocator = { NULL, NULL, NULL };
2127
- return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, allocator);
2128
- }
2129
-
2130
- /*! ZSTD_createDDict_byReference() :
2131
- * Create a digested dictionary, to start decompression without startup delay.
2132
- * Dictionary content is simply referenced, it will be accessed during decompression.
2133
- * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */
2134
- ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
2135
- {
2136
- ZSTD_customMem const allocator = { NULL, NULL, NULL };
2137
- return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, allocator);
2138
- }
2139
-
2140
-
2141
- ZSTD_DDict* ZSTD_initStaticDDict(void* workspace, size_t workspaceSize,
2142
- const void* dict, size_t dictSize,
2143
- ZSTD_dictLoadMethod_e dictLoadMethod)
2144
- {
2145
- size_t const neededSpace =
2146
- sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
2147
- ZSTD_DDict* const ddict = (ZSTD_DDict*)workspace;
2148
- assert(workspace != NULL);
2149
- assert(dict != NULL);
2150
- if ((size_t)workspace & 7) return NULL; /* 8-aligned */
2151
- if (workspaceSize < neededSpace) return NULL;
2152
- if (dictLoadMethod == ZSTD_dlm_byCopy) {
2153
- memcpy(ddict+1, dict, dictSize); /* local copy */
2154
- dict = ddict+1;
2155
- }
2156
- if (ZSTD_isError( ZSTD_initDDict_internal(ddict, dict, dictSize, ZSTD_dlm_byRef) ))
2157
- return NULL;
2158
- return ddict;
2159
- }
2160
-
2161
-
2162
- size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
2163
- {
2164
- if (ddict==NULL) return 0; /* support free on NULL */
2165
- { ZSTD_customMem const cMem = ddict->cMem;
2166
- ZSTD_free(ddict->dictBuffer, cMem);
2167
- ZSTD_free(ddict, cMem);
2168
- return 0;
2169
- }
2170
- }
2171
-
2172
- /*! ZSTD_estimateDDictSize() :
2173
- * Estimate amount of memory that will be needed to create a dictionary for decompression.
2174
- * Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */
2175
- size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)
2176
- {
2177
- return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);
2178
- }
2179
-
2180
- size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
2181
- {
2182
- if (ddict==NULL) return 0; /* support sizeof on NULL */
2183
- return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;
2184
- }
2185
-
2186
1178
  /*! ZSTD_getDictID_fromDict() :
2187
1179
  * Provides the dictID stored within dictionary.
2188
1180
  * if @return == 0, the dictionary is not conformant with Zstandard specification.
@@ -2191,21 +1183,11 @@ unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
2191
1183
  {
2192
1184
  if (dictSize < 8) return 0;
2193
1185
  if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;
2194
- return MEM_readLE32((const char*)dict + ZSTD_frameIdSize);
2195
- }
2196
-
2197
- /*! ZSTD_getDictID_fromDDict() :
2198
- * Provides the dictID of the dictionary loaded into `ddict`.
2199
- * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
2200
- * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
2201
- unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
2202
- {
2203
- if (ddict==NULL) return 0;
2204
- return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
1186
+ return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);
2205
1187
  }
2206
1188
 
2207
1189
  /*! ZSTD_getDictID_fromFrame() :
2208
- * Provides the dictID required to decompresse frame stored within `src`.
1190
+ * Provides the dictID required to decompress frame stored within `src`.
2209
1191
  * If @return == 0, the dictID could not be decoded.
2210
1192
  * This could for one of the following reasons :
2211
1193
  * - The frame does not require a dictionary (most common case).
@@ -2247,6 +1229,7 @@ size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
2247
1229
 
2248
1230
  ZSTD_DStream* ZSTD_createDStream(void)
2249
1231
  {
1232
+ DEBUGLOG(3, "ZSTD_createDStream");
2250
1233
  return ZSTD_createDStream_advanced(ZSTD_defaultCMem);
2251
1234
  }
2252
1235
 
@@ -2266,91 +1249,193 @@ size_t ZSTD_freeDStream(ZSTD_DStream* zds)
2266
1249
  }
2267
1250
 
2268
1251
 
2269
- /* *** Initialization *** */
1252
+ /* *** Initialization *** */
2270
1253
 
2271
1254
  size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; }
2272
1255
  size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }
2273
1256
 
2274
- size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1257
+ size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,
1258
+ const void* dict, size_t dictSize,
1259
+ ZSTD_dictLoadMethod_e dictLoadMethod,
1260
+ ZSTD_dictContentType_e dictContentType)
2275
1261
  {
2276
- zds->streamStage = zdss_loadHeader;
2277
- zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
2278
- ZSTD_freeDDict(zds->ddictLocal);
1262
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
1263
+ ZSTD_clearDict(dctx);
2279
1264
  if (dict && dictSize >= 8) {
2280
- zds->ddictLocal = ZSTD_createDDict(dict, dictSize);
2281
- if (zds->ddictLocal == NULL) return ERROR(memory_allocation);
2282
- } else zds->ddictLocal = NULL;
2283
- zds->ddict = zds->ddictLocal;
2284
- zds->legacyVersion = 0;
2285
- zds->hostageByte = 0;
2286
- return ZSTD_frameHeaderSize_prefix;
1265
+ dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);
1266
+ RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation);
1267
+ dctx->ddict = dctx->ddictLocal;
1268
+ dctx->dictUses = ZSTD_use_indefinitely;
1269
+ }
1270
+ return 0;
1271
+ }
1272
+
1273
+ size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1274
+ {
1275
+ return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);
1276
+ }
1277
+
1278
+ size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
1279
+ {
1280
+ return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);
1281
+ }
1282
+
1283
+ size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)
1284
+ {
1285
+ FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType));
1286
+ dctx->dictUses = ZSTD_use_once;
1287
+ return 0;
1288
+ }
1289
+
1290
+ size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)
1291
+ {
1292
+ return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent);
1293
+ }
1294
+
1295
+
1296
+ /* ZSTD_initDStream_usingDict() :
1297
+ * return : expected size, aka ZSTD_FRAMEHEADERSIZE_PREFIX.
1298
+ * this function cannot fail */
1299
+ size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
1300
+ {
1301
+ DEBUGLOG(4, "ZSTD_initDStream_usingDict");
1302
+ FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) );
1303
+ FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );
1304
+ return ZSTD_FRAMEHEADERSIZE_PREFIX;
2287
1305
  }
2288
1306
 
2289
1307
  /* note : this variant can't fail */
2290
1308
  size_t ZSTD_initDStream(ZSTD_DStream* zds)
2291
1309
  {
2292
- return ZSTD_initDStream_usingDict(zds, NULL, 0);
1310
+ DEBUGLOG(4, "ZSTD_initDStream");
1311
+ return ZSTD_initDStream_usingDDict(zds, NULL);
2293
1312
  }
2294
1313
 
2295
1314
  /* ZSTD_initDStream_usingDDict() :
2296
1315
  * ddict will just be referenced, and must outlive decompression session
2297
1316
  * this function cannot fail */
2298
- size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
1317
+ size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)
2299
1318
  {
2300
- size_t const initResult = ZSTD_initDStream(zds);
2301
- zds->ddict = ddict;
2302
- return initResult;
1319
+ FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) );
1320
+ FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) );
1321
+ return ZSTD_FRAMEHEADERSIZE_PREFIX;
2303
1322
  }
2304
1323
 
2305
- size_t ZSTD_resetDStream(ZSTD_DStream* zds)
1324
+ /* ZSTD_resetDStream() :
1325
+ * return : expected size, aka ZSTD_FRAMEHEADERSIZE_PREFIX.
1326
+ * this function cannot fail */
1327
+ size_t ZSTD_resetDStream(ZSTD_DStream* dctx)
2306
1328
  {
2307
- zds->streamStage = zdss_loadHeader;
2308
- zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
2309
- zds->legacyVersion = 0;
2310
- zds->hostageByte = 0;
2311
- return ZSTD_frameHeaderSize_prefix;
1329
+ FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only));
1330
+ return ZSTD_FRAMEHEADERSIZE_PREFIX;
2312
1331
  }
2313
1332
 
2314
- size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
2315
- ZSTD_DStreamParameter_e paramType, unsigned paramValue)
1333
+
1334
+ size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)
2316
1335
  {
2317
- ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2318
- if ((unsigned)zds->streamStage > (unsigned)zdss_loadHeader)
2319
- return ERROR(stage_wrong);
2320
- switch(paramType)
2321
- {
2322
- default : return ERROR(parameter_unsupported);
2323
- case DStream_p_maxWindowSize :
2324
- DEBUGLOG(4, "setting maxWindowSize = %u KB", paramValue >> 10);
2325
- zds->maxWindowSize = paramValue ? paramValue : (U32)(-1);
2326
- break;
1336
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
1337
+ ZSTD_clearDict(dctx);
1338
+ if (ddict) {
1339
+ dctx->ddict = ddict;
1340
+ dctx->dictUses = ZSTD_use_indefinitely;
2327
1341
  }
2328
1342
  return 0;
2329
1343
  }
2330
1344
 
1345
+ /* ZSTD_DCtx_setMaxWindowSize() :
1346
+ * note : no direct equivalence in ZSTD_DCtx_setParameter,
1347
+ * since this version sets windowSize, and the other sets windowLog */
2331
1348
  size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)
2332
1349
  {
2333
- ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2334
- if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
2335
- return ERROR(stage_wrong);
1350
+ ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);
1351
+ size_t const min = (size_t)1 << bounds.lowerBound;
1352
+ size_t const max = (size_t)1 << bounds.upperBound;
1353
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
1354
+ RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound);
1355
+ RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound);
2336
1356
  dctx->maxWindowSize = maxWindowSize;
2337
1357
  return 0;
2338
1358
  }
2339
1359
 
2340
1360
  size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)
2341
1361
  {
2342
- DEBUGLOG(4, "ZSTD_DCtx_setFormat : %u", (unsigned)format);
2343
- ZSTD_STATIC_ASSERT((unsigned)zdss_loadHeader >= (unsigned)zdss_init);
2344
- if ((unsigned)dctx->streamStage > (unsigned)zdss_loadHeader)
2345
- return ERROR(stage_wrong);
2346
- dctx->format = format;
1362
+ return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, format);
1363
+ }
1364
+
1365
+ ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)
1366
+ {
1367
+ ZSTD_bounds bounds = { 0, 0, 0 };
1368
+ switch(dParam) {
1369
+ case ZSTD_d_windowLogMax:
1370
+ bounds.lowerBound = ZSTD_WINDOWLOG_ABSOLUTEMIN;
1371
+ bounds.upperBound = ZSTD_WINDOWLOG_MAX;
1372
+ return bounds;
1373
+ case ZSTD_d_format:
1374
+ bounds.lowerBound = (int)ZSTD_f_zstd1;
1375
+ bounds.upperBound = (int)ZSTD_f_zstd1_magicless;
1376
+ ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);
1377
+ return bounds;
1378
+ default:;
1379
+ }
1380
+ bounds.error = ERROR(parameter_unsupported);
1381
+ return bounds;
1382
+ }
1383
+
1384
+ /* ZSTD_dParam_withinBounds:
1385
+ * @return 1 if value is within dParam bounds,
1386
+ * 0 otherwise */
1387
+ static int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)
1388
+ {
1389
+ ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam);
1390
+ if (ZSTD_isError(bounds.error)) return 0;
1391
+ if (value < bounds.lowerBound) return 0;
1392
+ if (value > bounds.upperBound) return 0;
1393
+ return 1;
1394
+ }
1395
+
1396
+ #define CHECK_DBOUNDS(p,v) { \
1397
+ RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound); \
1398
+ }
1399
+
1400
+ size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)
1401
+ {
1402
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
1403
+ switch(dParam) {
1404
+ case ZSTD_d_windowLogMax:
1405
+ if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;
1406
+ CHECK_DBOUNDS(ZSTD_d_windowLogMax, value);
1407
+ dctx->maxWindowSize = ((size_t)1) << value;
1408
+ return 0;
1409
+ case ZSTD_d_format:
1410
+ CHECK_DBOUNDS(ZSTD_d_format, value);
1411
+ dctx->format = (ZSTD_format_e)value;
1412
+ return 0;
1413
+ default:;
1414
+ }
1415
+ RETURN_ERROR(parameter_unsupported);
1416
+ }
1417
+
1418
+ size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)
1419
+ {
1420
+ if ( (reset == ZSTD_reset_session_only)
1421
+ || (reset == ZSTD_reset_session_and_parameters) ) {
1422
+ dctx->streamStage = zdss_init;
1423
+ dctx->noForwardProgress = 0;
1424
+ }
1425
+ if ( (reset == ZSTD_reset_parameters)
1426
+ || (reset == ZSTD_reset_session_and_parameters) ) {
1427
+ RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);
1428
+ ZSTD_clearDict(dctx);
1429
+ dctx->format = ZSTD_f_zstd1;
1430
+ dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
1431
+ }
2347
1432
  return 0;
2348
1433
  }
2349
1434
 
2350
1435
 
2351
- size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
1436
+ size_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)
2352
1437
  {
2353
- return ZSTD_sizeof_DCtx(zds);
1438
+ return ZSTD_sizeof_DCtx(dctx);
2354
1439
  }
2355
1440
 
2356
1441
  size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)
@@ -2359,7 +1444,8 @@ size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long
2359
1444
  unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);
2360
1445
  unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);
2361
1446
  size_t const minRBSize = (size_t) neededSize;
2362
- if ((unsigned long long)minRBSize != neededSize) return ERROR(frameParameter_windowTooLarge);
1447
+ RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,
1448
+ frameParameter_windowTooLarge);
2363
1449
  return minRBSize;
2364
1450
  }
2365
1451
 
@@ -2373,13 +1459,13 @@ size_t ZSTD_estimateDStreamSize(size_t windowSize)
2373
1459
 
2374
1460
  size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)
2375
1461
  {
2376
- U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable */
1462
+ U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX; /* note : should be user-selectable, but requires an additional parameter (or a dctx) */
2377
1463
  ZSTD_frameHeader zfh;
2378
1464
  size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);
2379
1465
  if (ZSTD_isError(err)) return err;
2380
- if (err>0) return ERROR(srcSize_wrong);
2381
- if (zfh.windowSize > windowSizeMax)
2382
- return ERROR(frameParameter_windowTooLarge);
1466
+ RETURN_ERROR_IF(err>0, srcSize_wrong);
1467
+ RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,
1468
+ frameParameter_windowTooLarge);
2383
1469
  return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);
2384
1470
  }
2385
1471
 
@@ -2405,51 +1491,60 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2405
1491
  U32 someMoreWork = 1;
2406
1492
 
2407
1493
  DEBUGLOG(5, "ZSTD_decompressStream");
2408
- if (input->pos > input->size) { /* forbidden */
2409
- DEBUGLOG(5, "in: pos: %u vs size: %u",
2410
- (U32)input->pos, (U32)input->size);
2411
- return ERROR(srcSize_wrong);
2412
- }
2413
- if (output->pos > output->size) { /* forbidden */
2414
- DEBUGLOG(5, "out: pos: %u vs size: %u",
2415
- (U32)output->pos, (U32)output->size);
2416
- return ERROR(dstSize_tooSmall);
2417
- }
1494
+ RETURN_ERROR_IF(
1495
+ input->pos > input->size,
1496
+ srcSize_wrong,
1497
+ "forbidden. in: pos: %u vs size: %u",
1498
+ (U32)input->pos, (U32)input->size);
1499
+ RETURN_ERROR_IF(
1500
+ output->pos > output->size,
1501
+ dstSize_tooSmall,
1502
+ "forbidden. out: pos: %u vs size: %u",
1503
+ (U32)output->pos, (U32)output->size);
2418
1504
  DEBUGLOG(5, "input size : %u", (U32)(input->size - input->pos));
2419
1505
 
2420
- #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2421
- if (zds->legacyVersion) {
2422
- /* legacy support is incompatible with static dctx */
2423
- if (zds->staticSize) return ERROR(memory_allocation);
2424
- return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
2425
- }
2426
- #endif
2427
-
2428
1506
  while (someMoreWork) {
2429
1507
  switch(zds->streamStage)
2430
1508
  {
2431
1509
  case zdss_init :
2432
- ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
1510
+ DEBUGLOG(5, "stage zdss_init => transparent reset ");
1511
+ zds->streamStage = zdss_loadHeader;
1512
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
1513
+ zds->legacyVersion = 0;
1514
+ zds->hostageByte = 0;
2433
1515
  /* fall-through */
2434
1516
 
2435
1517
  case zdss_loadHeader :
2436
1518
  DEBUGLOG(5, "stage zdss_loadHeader (srcSize : %u)", (U32)(iend - ip));
2437
- { size_t const hSize = ZSTD_getFrameHeader_internal(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
1519
+ #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
1520
+ if (zds->legacyVersion) {
1521
+ RETURN_ERROR_IF(zds->staticSize, memory_allocation,
1522
+ "legacy support is incompatible with static dctx");
1523
+ { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
1524
+ if (hint==0) zds->streamStage = zdss_init;
1525
+ return hint;
1526
+ } }
1527
+ #endif
1528
+ { size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);
2438
1529
  DEBUGLOG(5, "header size : %u", (U32)hSize);
2439
1530
  if (ZSTD_isError(hSize)) {
2440
1531
  #if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
2441
1532
  U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
2442
1533
  if (legacyVersion) {
2443
- const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL;
2444
- size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
2445
- /* legacy support is incompatible with static dctx */
2446
- if (zds->staticSize) return ERROR(memory_allocation);
2447
- CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext,
1534
+ ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);
1535
+ const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;
1536
+ size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;
1537
+ DEBUGLOG(5, "ZSTD_decompressStream: detected legacy version v0.%u", legacyVersion);
1538
+ RETURN_ERROR_IF(zds->staticSize, memory_allocation,
1539
+ "legacy support is incompatible with static dctx");
1540
+ FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,
2448
1541
  zds->previousLegacyVersion, legacyVersion,
2449
1542
  dict, dictSize));
2450
1543
  zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
2451
- return ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
2452
- }
1544
+ { size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);
1545
+ if (hint==0) zds->streamStage = zdss_init; /* or stay in stage zdss_loadHeader */
1546
+ return hint;
1547
+ } }
2453
1548
  #endif
2454
1549
  return hSize; /* error */
2455
1550
  }
@@ -2463,7 +1558,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2463
1558
  zds->lhSize += remainingInput;
2464
1559
  }
2465
1560
  input->pos = input->size;
2466
- return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
1561
+ return (MAX(ZSTD_FRAMEHEADERSIZE_MIN, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
2467
1562
  }
2468
1563
  assert(ip != NULL);
2469
1564
  memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
@@ -2476,7 +1571,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2476
1571
  size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
2477
1572
  if (cSize <= (size_t)(iend-istart)) {
2478
1573
  /* shortcut : using single-pass mode */
2479
- size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, zds->ddict);
1574
+ size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, ZSTD_getDDict(zds));
2480
1575
  if (ZSTD_isError(decompressedSize)) return decompressedSize;
2481
1576
  DEBUGLOG(4, "shortcut to single-pass ZSTD_decompress_usingDDict()")
2482
1577
  ip = istart + cSize;
@@ -2489,13 +1584,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2489
1584
 
2490
1585
  /* Consume header (see ZSTDds_decodeFrameHeader) */
2491
1586
  DEBUGLOG(4, "Consume header");
2492
- CHECK_F(ZSTD_decompressBegin_usingDDict(zds, zds->ddict));
1587
+ FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)));
2493
1588
 
2494
- if ((MEM_readLE32(zds->headerBuffer) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
2495
- zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_frameIdSize);
1589
+ if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
1590
+ zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);
2496
1591
  zds->stage = ZSTDds_skipFrame;
2497
1592
  } else {
2498
- CHECK_F(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
1593
+ FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));
2499
1594
  zds->expected = ZSTD_blockHeaderSize;
2500
1595
  zds->stage = ZSTDds_decodeBlockHeader;
2501
1596
  }
@@ -2505,7 +1600,8 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2505
1600
  (U32)(zds->fParams.windowSize >>10),
2506
1601
  (U32)(zds->maxWindowSize >> 10) );
2507
1602
  zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
2508
- if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
1603
+ RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,
1604
+ frameParameter_windowTooLarge);
2509
1605
 
2510
1606
  /* Adapt buffer sizes to frame header instructions */
2511
1607
  { size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);
@@ -2519,14 +1615,15 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2519
1615
  if (zds->staticSize) { /* static DCtx */
2520
1616
  DEBUGLOG(4, "staticSize : %u", (U32)zds->staticSize);
2521
1617
  assert(zds->staticSize >= sizeof(ZSTD_DCtx)); /* controlled at init */
2522
- if (bufferSize > zds->staticSize - sizeof(ZSTD_DCtx))
2523
- return ERROR(memory_allocation);
1618
+ RETURN_ERROR_IF(
1619
+ bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),
1620
+ memory_allocation);
2524
1621
  } else {
2525
1622
  ZSTD_free(zds->inBuff, zds->customMem);
2526
1623
  zds->inBuffSize = 0;
2527
1624
  zds->outBuffSize = 0;
2528
1625
  zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);
2529
- if (zds->inBuff == NULL) return ERROR(memory_allocation);
1626
+ RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation);
2530
1627
  }
2531
1628
  zds->inBuffSize = neededInBuffSize;
2532
1629
  zds->outBuff = zds->inBuff + zds->inBuffSize;
@@ -2559,6 +1656,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2559
1656
  if (ip==iend) { someMoreWork = 0; break; } /* no more input */
2560
1657
  zds->streamStage = zdss_load;
2561
1658
  /* fall-through */
1659
+
2562
1660
  case zdss_load:
2563
1661
  { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);
2564
1662
  size_t const toLoad = neededInSize - zds->inPos;
@@ -2567,7 +1665,9 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2567
1665
  if (isSkipFrame) {
2568
1666
  loadedSize = MIN(toLoad, (size_t)(iend-ip));
2569
1667
  } else {
2570
- if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
1668
+ RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,
1669
+ corruption_detected,
1670
+ "should never happen");
2571
1671
  loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
2572
1672
  }
2573
1673
  ip += loadedSize;
@@ -2585,6 +1685,7 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2585
1685
  } }
2586
1686
  zds->streamStage = zdss_flush;
2587
1687
  /* fall-through */
1688
+
2588
1689
  case zdss_flush:
2589
1690
  { size_t const toFlushSize = zds->outEnd - zds->outStart;
2590
1691
  size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
@@ -2605,12 +1706,24 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2605
1706
  someMoreWork = 0;
2606
1707
  break;
2607
1708
 
2608
- default: return ERROR(GENERIC); /* impossible */
1709
+ default:
1710
+ assert(0); /* impossible */
1711
+ RETURN_ERROR(GENERIC); /* some compiler require default to do something */
2609
1712
  } }
2610
1713
 
2611
1714
  /* result */
2612
- input->pos += (size_t)(ip-istart);
2613
- output->pos += (size_t)(op-ostart);
1715
+ input->pos = (size_t)(ip - (const char*)(input->src));
1716
+ output->pos = (size_t)(op - (char*)(output->dst));
1717
+ if ((ip==istart) && (op==ostart)) { /* no forward progress */
1718
+ zds->noForwardProgress ++;
1719
+ if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {
1720
+ RETURN_ERROR_IF(op==oend, dstSize_tooSmall);
1721
+ RETURN_ERROR_IF(ip==iend, srcSize_wrong);
1722
+ assert(0);
1723
+ }
1724
+ } else {
1725
+ zds->noForwardProgress = 0;
1726
+ }
2614
1727
  { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);
2615
1728
  if (!nextSrcSizeHint) { /* frame fully decoded */
2616
1729
  if (zds->outEnd == zds->outStart) { /* output fully flushed */
@@ -2631,19 +1744,13 @@ size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inB
2631
1744
  return 1;
2632
1745
  } /* nextSrcSizeHint==0 */
2633
1746
  nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block); /* preload header of next block */
2634
- if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
2635
- nextSrcSizeHint -= zds->inPos; /* already loaded*/
1747
+ assert(zds->inPos <= nextSrcSizeHint);
1748
+ nextSrcSizeHint -= zds->inPos; /* part already loaded*/
2636
1749
  return nextSrcSizeHint;
2637
1750
  }
2638
1751
  }
2639
1752
 
2640
-
2641
- size_t ZSTD_decompress_generic(ZSTD_DCtx* dctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
2642
- {
2643
- return ZSTD_decompressStream(dctx, output, input);
2644
- }
2645
-
2646
- size_t ZSTD_decompress_generic_simpleArgs (
1753
+ size_t ZSTD_decompressStream_simpleArgs (
2647
1754
  ZSTD_DCtx* dctx,
2648
1755
  void* dst, size_t dstCapacity, size_t* dstPos,
2649
1756
  const void* src, size_t srcSize, size_t* srcPos)
@@ -2651,15 +1758,8 @@ size_t ZSTD_decompress_generic_simpleArgs (
2651
1758
  ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };
2652
1759
  ZSTD_inBuffer input = { src, srcSize, *srcPos };
2653
1760
  /* ZSTD_compress_generic() will check validity of dstPos and srcPos */
2654
- size_t const cErr = ZSTD_decompress_generic(dctx, &output, &input);
1761
+ size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);
2655
1762
  *dstPos = output.pos;
2656
1763
  *srcPos = input.pos;
2657
1764
  return cErr;
2658
1765
  }
2659
-
2660
- void ZSTD_DCtx_reset(ZSTD_DCtx* dctx)
2661
- {
2662
- (void)ZSTD_initDStream(dctx);
2663
- dctx->format = ZSTD_f_zstd1;
2664
- dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
2665
- }