extzstd 0.2 → 0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }