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) 15extern "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*/ 56MEM_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 89MEM_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 121MEM_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 181MEM_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 248MEM_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 254MEM_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 280MEM_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 339MEM_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