1 /*
2 * Copyright (c) 2016-2020, 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 #ifndef ZSTD_LEGACY_H
12 #define ZSTD_LEGACY_H
13
14 #if defined (__cplusplus)
15 extern "C" {
16 #endif
17
18 /* *************************************
19 * Includes
20 ***************************************/
21 #include "../common/mem.h" /* MEM_STATIC */
22 #include "../common/error_private.h" /* ERROR */
23 #include "../common/zstd_internal.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTD_frameSizeInfo */
24
25 #if !defined (ZSTD_LEGACY_SUPPORT) || (ZSTD_LEGACY_SUPPORT == 0)
26 # undef ZSTD_LEGACY_SUPPORT
27 # define ZSTD_LEGACY_SUPPORT 8
28 #endif
29
30 #if (ZSTD_LEGACY_SUPPORT <= 1)
31 # include "zstd_v01.h"
32 #endif
33 #if (ZSTD_LEGACY_SUPPORT <= 2)
34 # include "zstd_v02.h"
35 #endif
36 #if (ZSTD_LEGACY_SUPPORT <= 3)
37 # include "zstd_v03.h"
38 #endif
39 #if (ZSTD_LEGACY_SUPPORT <= 4)
40 # include "zstd_v04.h"
41 #endif
42 #if (ZSTD_LEGACY_SUPPORT <= 5)
43 # include "zstd_v05.h"
44 #endif
45 #if (ZSTD_LEGACY_SUPPORT <= 6)
46 # include "zstd_v06.h"
47 #endif
48 #if (ZSTD_LEGACY_SUPPORT <= 7)
49 # include "zstd_v07.h"
50 #endif
51
52 /** ZSTD_isLegacy() :
53 @return : > 0 if supported by legacy decoder. 0 otherwise.
54 return value is the version.
55 */
ZSTD_isLegacy(const void * src,size_t srcSize)56 MEM_STATIC unsigned ZSTD_isLegacy(const void* src, size_t srcSize)
57 {
58 U32 magicNumberLE;
59 if (srcSize<4) return 0;
60 magicNumberLE = MEM_readLE32(src);
61 switch(magicNumberLE)
62 {
63 #if (ZSTD_LEGACY_SUPPORT <= 1)
64 case ZSTDv01_magicNumberLE:return 1;
65 #endif
66 #if (ZSTD_LEGACY_SUPPORT <= 2)
67 case ZSTDv02_magicNumber : return 2;
68 #endif
69 #if (ZSTD_LEGACY_SUPPORT <= 3)
70 case ZSTDv03_magicNumber : return 3;
71 #endif
72 #if (ZSTD_LEGACY_SUPPORT <= 4)
73 case ZSTDv04_magicNumber : return 4;
74 #endif
75 #if (ZSTD_LEGACY_SUPPORT <= 5)
76 case ZSTDv05_MAGICNUMBER : return 5;
77 #endif
78 #if (ZSTD_LEGACY_SUPPORT <= 6)
79 case ZSTDv06_MAGICNUMBER : return 6;
80 #endif
81 #if (ZSTD_LEGACY_SUPPORT <= 7)
82 case ZSTDv07_MAGICNUMBER : return 7;
83 #endif
84 default : return 0;
85 }
86 }
87
88
ZSTD_getDecompressedSize_legacy(const void * src,size_t srcSize)89 MEM_STATIC unsigned long long ZSTD_getDecompressedSize_legacy(const void* src, size_t srcSize)
90 {
91 U32 const version = ZSTD_isLegacy(src, srcSize);
92 if (version < 5) return 0; /* no decompressed size in frame header, or not a legacy format */
93 #if (ZSTD_LEGACY_SUPPORT <= 5)
94 if (version==5) {
95 ZSTDv05_parameters fParams;
96 size_t const frResult = ZSTDv05_getFrameParams(&fParams, src, srcSize);
97 if (frResult != 0) return 0;
98 return fParams.srcSize;
99 }
100 #endif
101 #if (ZSTD_LEGACY_SUPPORT <= 6)
102 if (version==6) {
103 ZSTDv06_frameParams fParams;
104 size_t const frResult = ZSTDv06_getFrameParams(&fParams, src, srcSize);
105 if (frResult != 0) return 0;
106 return fParams.frameContentSize;
107 }
108 #endif
109 #if (ZSTD_LEGACY_SUPPORT <= 7)
110 if (version==7) {
111 ZSTDv07_frameParams fParams;
112 size_t const frResult = ZSTDv07_getFrameParams(&fParams, src, srcSize);
113 if (frResult != 0) return 0;
114 return fParams.frameContentSize;
115 }
116 #endif
117 return 0; /* should not be possible */
118 }
119
120
ZSTD_decompressLegacy(void * dst,size_t dstCapacity,const void * src,size_t compressedSize,const void * dict,size_t dictSize)121 MEM_STATIC size_t ZSTD_decompressLegacy(
122 void* dst, size_t dstCapacity,
123 const void* src, size_t compressedSize,
124 const void* dict,size_t dictSize)
125 {
126 U32 const version = ZSTD_isLegacy(src, compressedSize);
127 (void)dst; (void)dstCapacity; (void)dict; (void)dictSize; /* unused when ZSTD_LEGACY_SUPPORT >= 8 */
128 switch(version)
129 {
130 #if (ZSTD_LEGACY_SUPPORT <= 1)
131 case 1 :
132 return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize);
133 #endif
134 #if (ZSTD_LEGACY_SUPPORT <= 2)
135 case 2 :
136 return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize);
137 #endif
138 #if (ZSTD_LEGACY_SUPPORT <= 3)
139 case 3 :
140 return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize);
141 #endif
142 #if (ZSTD_LEGACY_SUPPORT <= 4)
143 case 4 :
144 return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize);
145 #endif
146 #if (ZSTD_LEGACY_SUPPORT <= 5)
147 case 5 :
148 { size_t result;
149 ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
150 if (zd==NULL) return ERROR(memory_allocation);
151 result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
152 ZSTDv05_freeDCtx(zd);
153 return result;
154 }
155 #endif
156 #if (ZSTD_LEGACY_SUPPORT <= 6)
157 case 6 :
158 { size_t result;
159 ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
160 if (zd==NULL) return ERROR(memory_allocation);
161 result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
162 ZSTDv06_freeDCtx(zd);
163 return result;
164 }
165 #endif
166 #if (ZSTD_LEGACY_SUPPORT <= 7)
167 case 7 :
168 { size_t result;
169 ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx();
170 if (zd==NULL) return ERROR(memory_allocation);
171 result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
172 ZSTDv07_freeDCtx(zd);
173 return result;
174 }
175 #endif
176 default :
177 return ERROR(prefix_unknown);
178 }
179 }
180
ZSTD_findFrameSizeInfoLegacy(const void * src,size_t srcSize)181 MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size_t srcSize)
182 {
183 ZSTD_frameSizeInfo frameSizeInfo;
184 U32 const version = ZSTD_isLegacy(src, srcSize);
185 switch(version)
186 {
187 #if (ZSTD_LEGACY_SUPPORT <= 1)
188 case 1 :
189 ZSTDv01_findFrameSizeInfoLegacy(src, srcSize,
190 &frameSizeInfo.compressedSize,
191 &frameSizeInfo.decompressedBound);
192 break;
193 #endif
194 #if (ZSTD_LEGACY_SUPPORT <= 2)
195 case 2 :
196 ZSTDv02_findFrameSizeInfoLegacy(src, srcSize,
197 &frameSizeInfo.compressedSize,
198 &frameSizeInfo.decompressedBound);
199 break;
200 #endif
201 #if (ZSTD_LEGACY_SUPPORT <= 3)
202 case 3 :
203 ZSTDv03_findFrameSizeInfoLegacy(src, srcSize,
204 &frameSizeInfo.compressedSize,
205 &frameSizeInfo.decompressedBound);
206 break;
207 #endif
208 #if (ZSTD_LEGACY_SUPPORT <= 4)
209 case 4 :
210 ZSTDv04_findFrameSizeInfoLegacy(src, srcSize,
211 &frameSizeInfo.compressedSize,
212 &frameSizeInfo.decompressedBound);
213 break;
214 #endif
215 #if (ZSTD_LEGACY_SUPPORT <= 5)
216 case 5 :
217 ZSTDv05_findFrameSizeInfoLegacy(src, srcSize,
218 &frameSizeInfo.compressedSize,
219 &frameSizeInfo.decompressedBound);
220 break;
221 #endif
222 #if (ZSTD_LEGACY_SUPPORT <= 6)
223 case 6 :
224 ZSTDv06_findFrameSizeInfoLegacy(src, srcSize,
225 &frameSizeInfo.compressedSize,
226 &frameSizeInfo.decompressedBound);
227 break;
228 #endif
229 #if (ZSTD_LEGACY_SUPPORT <= 7)
230 case 7 :
231 ZSTDv07_findFrameSizeInfoLegacy(src, srcSize,
232 &frameSizeInfo.compressedSize,
233 &frameSizeInfo.decompressedBound);
234 break;
235 #endif
236 default :
237 frameSizeInfo.compressedSize = ERROR(prefix_unknown);
238 frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
239 break;
240 }
241 if (!ZSTD_isError(frameSizeInfo.compressedSize) && frameSizeInfo.compressedSize > srcSize) {
242 frameSizeInfo.compressedSize = ERROR(srcSize_wrong);
243 frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
244 }
245 return frameSizeInfo;
246 }
247
ZSTD_findFrameCompressedSizeLegacy(const void * src,size_t srcSize)248 MEM_STATIC size_t ZSTD_findFrameCompressedSizeLegacy(const void *src, size_t srcSize)
249 {
250 ZSTD_frameSizeInfo frameSizeInfo = ZSTD_findFrameSizeInfoLegacy(src, srcSize);
251 return frameSizeInfo.compressedSize;
252 }
253
ZSTD_freeLegacyStreamContext(void * legacyContext,U32 version)254 MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
255 {
256 switch(version)
257 {
258 default :
259 case 1 :
260 case 2 :
261 case 3 :
262 (void)legacyContext;
263 return ERROR(version_unsupported);
264 #if (ZSTD_LEGACY_SUPPORT <= 4)
265 case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext);
266 #endif
267 #if (ZSTD_LEGACY_SUPPORT <= 5)
268 case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext);
269 #endif
270 #if (ZSTD_LEGACY_SUPPORT <= 6)
271 case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext);
272 #endif
273 #if (ZSTD_LEGACY_SUPPORT <= 7)
274 case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext);
275 #endif
276 }
277 }
278
279
ZSTD_initLegacyStream(void ** legacyContext,U32 prevVersion,U32 newVersion,const void * dict,size_t dictSize)280 MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
281 const void* dict, size_t dictSize)
282 {
283 DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u", newVersion);
284 if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
285 switch(newVersion)
286 {
287 default :
288 case 1 :
289 case 2 :
290 case 3 :
291 (void)dict; (void)dictSize;
292 return 0;
293 #if (ZSTD_LEGACY_SUPPORT <= 4)
294 case 4 :
295 {
296 ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext;
297 if (dctx==NULL) return ERROR(memory_allocation);
298 ZBUFFv04_decompressInit(dctx);
299 ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize);
300 *legacyContext = dctx;
301 return 0;
302 }
303 #endif
304 #if (ZSTD_LEGACY_SUPPORT <= 5)
305 case 5 :
306 {
307 ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext;
308 if (dctx==NULL) return ERROR(memory_allocation);
309 ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize);
310 *legacyContext = dctx;
311 return 0;
312 }
313 #endif
314 #if (ZSTD_LEGACY_SUPPORT <= 6)
315 case 6 :
316 {
317 ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext;
318 if (dctx==NULL) return ERROR(memory_allocation);
319 ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize);
320 *legacyContext = dctx;
321 return 0;
322 }
323 #endif
324 #if (ZSTD_LEGACY_SUPPORT <= 7)
325 case 7 :
326 {
327 ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext;
328 if (dctx==NULL) return ERROR(memory_allocation);
329 ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize);
330 *legacyContext = dctx;
331 return 0;
332 }
333 #endif
334 }
335 }
336
337
338
ZSTD_decompressLegacyStream(void * legacyContext,U32 version,ZSTD_outBuffer * output,ZSTD_inBuffer * input)339 MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
340 ZSTD_outBuffer* output, ZSTD_inBuffer* input)
341 {
342 DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u", version);
343 switch(version)
344 {
345 default :
346 case 1 :
347 case 2 :
348 case 3 :
349 (void)legacyContext; (void)output; (void)input;
350 return ERROR(version_unsupported);
351 #if (ZSTD_LEGACY_SUPPORT <= 4)
352 case 4 :
353 {
354 ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext;
355 const void* src = (const char*)input->src + input->pos;
356 size_t readSize = input->size - input->pos;
357 void* dst = (char*)output->dst + output->pos;
358 size_t decodedSize = output->size - output->pos;
359 size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
360 output->pos += decodedSize;
361 input->pos += readSize;
362 return hintSize;
363 }
364 #endif
365 #if (ZSTD_LEGACY_SUPPORT <= 5)
366 case 5 :
367 {
368 ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext;
369 const void* src = (const char*)input->src + input->pos;
370 size_t readSize = input->size - input->pos;
371 void* dst = (char*)output->dst + output->pos;
372 size_t decodedSize = output->size - output->pos;
373 size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
374 output->pos += decodedSize;
375 input->pos += readSize;
376 return hintSize;
377 }
378 #endif
379 #if (ZSTD_LEGACY_SUPPORT <= 6)
380 case 6 :
381 {
382 ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext;
383 const void* src = (const char*)input->src + input->pos;
384 size_t readSize = input->size - input->pos;
385 void* dst = (char*)output->dst + output->pos;
386 size_t decodedSize = output->size - output->pos;
387 size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
388 output->pos += decodedSize;
389 input->pos += readSize;
390 return hintSize;
391 }
392 #endif
393 #if (ZSTD_LEGACY_SUPPORT <= 7)
394 case 7 :
395 {
396 ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext;
397 const void* src = (const char*)input->src + input->pos;
398 size_t readSize = input->size - input->pos;
399 void* dst = (char*)output->dst + output->pos;
400 size_t decodedSize = output->size - output->pos;
401 size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
402 output->pos += decodedSize;
403 input->pos += readSize;
404 return hintSize;
405 }
406 #endif
407 }
408 }
409
410
411 #if defined (__cplusplus)
412 }
413 #endif
414
415 #endif /* ZSTD_LEGACY_H */
416