Home | History | Annotate | Line # | Download | only in legacy
      1 /*
      2  * Copyright (c) Meta Platforms, Inc. and affiliates.
      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 */
     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 
     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 
    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     char x;
    128     /* Avoid passing NULL to legacy decoding. */
    129     if (dst == NULL) {
    130         assert(dstCapacity == 0);
    131         dst = &x;
    132     }
    133     if (src == NULL) {
    134         assert(compressedSize == 0);
    135         src = &x;
    136     }
    137     if (dict == NULL) {
    138         assert(dictSize == 0);
    139         dict = &x;
    140     }
    141     (void)dst; (void)dstCapacity; (void)dict; (void)dictSize;  /* unused when ZSTD_LEGACY_SUPPORT >= 8 */
    142     switch(version)
    143     {
    144 #if (ZSTD_LEGACY_SUPPORT <= 1)
    145         case 1 :
    146             return ZSTDv01_decompress(dst, dstCapacity, src, compressedSize);
    147 #endif
    148 #if (ZSTD_LEGACY_SUPPORT <= 2)
    149         case 2 :
    150             return ZSTDv02_decompress(dst, dstCapacity, src, compressedSize);
    151 #endif
    152 #if (ZSTD_LEGACY_SUPPORT <= 3)
    153         case 3 :
    154             return ZSTDv03_decompress(dst, dstCapacity, src, compressedSize);
    155 #endif
    156 #if (ZSTD_LEGACY_SUPPORT <= 4)
    157         case 4 :
    158             return ZSTDv04_decompress(dst, dstCapacity, src, compressedSize);
    159 #endif
    160 #if (ZSTD_LEGACY_SUPPORT <= 5)
    161         case 5 :
    162             {   size_t result;
    163                 ZSTDv05_DCtx* const zd = ZSTDv05_createDCtx();
    164                 if (zd==NULL) return ERROR(memory_allocation);
    165                 result = ZSTDv05_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
    166                 ZSTDv05_freeDCtx(zd);
    167                 return result;
    168             }
    169 #endif
    170 #if (ZSTD_LEGACY_SUPPORT <= 6)
    171         case 6 :
    172             {   size_t result;
    173                 ZSTDv06_DCtx* const zd = ZSTDv06_createDCtx();
    174                 if (zd==NULL) return ERROR(memory_allocation);
    175                 result = ZSTDv06_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
    176                 ZSTDv06_freeDCtx(zd);
    177                 return result;
    178             }
    179 #endif
    180 #if (ZSTD_LEGACY_SUPPORT <= 7)
    181         case 7 :
    182             {   size_t result;
    183                 ZSTDv07_DCtx* const zd = ZSTDv07_createDCtx();
    184                 if (zd==NULL) return ERROR(memory_allocation);
    185                 result = ZSTDv07_decompress_usingDict(zd, dst, dstCapacity, src, compressedSize, dict, dictSize);
    186                 ZSTDv07_freeDCtx(zd);
    187                 return result;
    188             }
    189 #endif
    190         default :
    191             return ERROR(prefix_unknown);
    192     }
    193 }
    194 
    195 MEM_STATIC ZSTD_frameSizeInfo ZSTD_findFrameSizeInfoLegacy(const void *src, size_t srcSize)
    196 {
    197     ZSTD_frameSizeInfo frameSizeInfo;
    198     U32 const version = ZSTD_isLegacy(src, srcSize);
    199     switch(version)
    200     {
    201 #if (ZSTD_LEGACY_SUPPORT <= 1)
    202         case 1 :
    203             ZSTDv01_findFrameSizeInfoLegacy(src, srcSize,
    204                 &frameSizeInfo.compressedSize,
    205                 &frameSizeInfo.decompressedBound);
    206             break;
    207 #endif
    208 #if (ZSTD_LEGACY_SUPPORT <= 2)
    209         case 2 :
    210             ZSTDv02_findFrameSizeInfoLegacy(src, srcSize,
    211                 &frameSizeInfo.compressedSize,
    212                 &frameSizeInfo.decompressedBound);
    213             break;
    214 #endif
    215 #if (ZSTD_LEGACY_SUPPORT <= 3)
    216         case 3 :
    217             ZSTDv03_findFrameSizeInfoLegacy(src, srcSize,
    218                 &frameSizeInfo.compressedSize,
    219                 &frameSizeInfo.decompressedBound);
    220             break;
    221 #endif
    222 #if (ZSTD_LEGACY_SUPPORT <= 4)
    223         case 4 :
    224             ZSTDv04_findFrameSizeInfoLegacy(src, srcSize,
    225                 &frameSizeInfo.compressedSize,
    226                 &frameSizeInfo.decompressedBound);
    227             break;
    228 #endif
    229 #if (ZSTD_LEGACY_SUPPORT <= 5)
    230         case 5 :
    231             ZSTDv05_findFrameSizeInfoLegacy(src, srcSize,
    232                 &frameSizeInfo.compressedSize,
    233                 &frameSizeInfo.decompressedBound);
    234             break;
    235 #endif
    236 #if (ZSTD_LEGACY_SUPPORT <= 6)
    237         case 6 :
    238             ZSTDv06_findFrameSizeInfoLegacy(src, srcSize,
    239                 &frameSizeInfo.compressedSize,
    240                 &frameSizeInfo.decompressedBound);
    241             break;
    242 #endif
    243 #if (ZSTD_LEGACY_SUPPORT <= 7)
    244         case 7 :
    245             ZSTDv07_findFrameSizeInfoLegacy(src, srcSize,
    246                 &frameSizeInfo.compressedSize,
    247                 &frameSizeInfo.decompressedBound);
    248             break;
    249 #endif
    250         default :
    251             frameSizeInfo.compressedSize = ERROR(prefix_unknown);
    252             frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
    253             break;
    254     }
    255     if (!ZSTD_isError(frameSizeInfo.compressedSize) && frameSizeInfo.compressedSize > srcSize) {
    256         frameSizeInfo.compressedSize = ERROR(srcSize_wrong);
    257         frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;
    258     }
    259     /* In all cases, decompressedBound == nbBlocks * ZSTD_BLOCKSIZE_MAX.
    260      * So we can compute nbBlocks without having to change every function.
    261      */
    262     if (frameSizeInfo.decompressedBound != ZSTD_CONTENTSIZE_ERROR) {
    263         assert((frameSizeInfo.decompressedBound & (ZSTD_BLOCKSIZE_MAX - 1)) == 0);
    264         frameSizeInfo.nbBlocks = (size_t)(frameSizeInfo.decompressedBound / ZSTD_BLOCKSIZE_MAX);
    265     }
    266     return frameSizeInfo;
    267 }
    268 
    269 MEM_STATIC size_t ZSTD_findFrameCompressedSizeLegacy(const void *src, size_t srcSize)
    270 {
    271     ZSTD_frameSizeInfo frameSizeInfo = ZSTD_findFrameSizeInfoLegacy(src, srcSize);
    272     return frameSizeInfo.compressedSize;
    273 }
    274 
    275 MEM_STATIC size_t ZSTD_freeLegacyStreamContext(void* legacyContext, U32 version)
    276 {
    277     switch(version)
    278     {
    279         default :
    280         case 1 :
    281         case 2 :
    282         case 3 :
    283             (void)legacyContext;
    284             return ERROR(version_unsupported);
    285 #if (ZSTD_LEGACY_SUPPORT <= 4)
    286         case 4 : return ZBUFFv04_freeDCtx((ZBUFFv04_DCtx*)legacyContext);
    287 #endif
    288 #if (ZSTD_LEGACY_SUPPORT <= 5)
    289         case 5 : return ZBUFFv05_freeDCtx((ZBUFFv05_DCtx*)legacyContext);
    290 #endif
    291 #if (ZSTD_LEGACY_SUPPORT <= 6)
    292         case 6 : return ZBUFFv06_freeDCtx((ZBUFFv06_DCtx*)legacyContext);
    293 #endif
    294 #if (ZSTD_LEGACY_SUPPORT <= 7)
    295         case 7 : return ZBUFFv07_freeDCtx((ZBUFFv07_DCtx*)legacyContext);
    296 #endif
    297     }
    298 }
    299 
    300 
    301 MEM_STATIC size_t ZSTD_initLegacyStream(void** legacyContext, U32 prevVersion, U32 newVersion,
    302                                         const void* dict, size_t dictSize)
    303 {
    304     char x;
    305     /* Avoid passing NULL to legacy decoding. */
    306     if (dict == NULL) {
    307         assert(dictSize == 0);
    308         dict = &x;
    309     }
    310     DEBUGLOG(5, "ZSTD_initLegacyStream for v0.%u", newVersion);
    311     if (prevVersion != newVersion) ZSTD_freeLegacyStreamContext(*legacyContext, prevVersion);
    312     switch(newVersion)
    313     {
    314         default :
    315         case 1 :
    316         case 2 :
    317         case 3 :
    318             (void)dict; (void)dictSize;
    319             return 0;
    320 #if (ZSTD_LEGACY_SUPPORT <= 4)
    321         case 4 :
    322         {
    323             ZBUFFv04_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv04_createDCtx() : (ZBUFFv04_DCtx*)*legacyContext;
    324             if (dctx==NULL) return ERROR(memory_allocation);
    325             ZBUFFv04_decompressInit(dctx);
    326             ZBUFFv04_decompressWithDictionary(dctx, dict, dictSize);
    327             *legacyContext = dctx;
    328             return 0;
    329         }
    330 #endif
    331 #if (ZSTD_LEGACY_SUPPORT <= 5)
    332         case 5 :
    333         {
    334             ZBUFFv05_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv05_createDCtx() : (ZBUFFv05_DCtx*)*legacyContext;
    335             if (dctx==NULL) return ERROR(memory_allocation);
    336             ZBUFFv05_decompressInitDictionary(dctx, dict, dictSize);
    337             *legacyContext = dctx;
    338             return 0;
    339         }
    340 #endif
    341 #if (ZSTD_LEGACY_SUPPORT <= 6)
    342         case 6 :
    343         {
    344             ZBUFFv06_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv06_createDCtx() : (ZBUFFv06_DCtx*)*legacyContext;
    345             if (dctx==NULL) return ERROR(memory_allocation);
    346             ZBUFFv06_decompressInitDictionary(dctx, dict, dictSize);
    347             *legacyContext = dctx;
    348             return 0;
    349         }
    350 #endif
    351 #if (ZSTD_LEGACY_SUPPORT <= 7)
    352         case 7 :
    353         {
    354             ZBUFFv07_DCtx* dctx = (prevVersion != newVersion) ? ZBUFFv07_createDCtx() : (ZBUFFv07_DCtx*)*legacyContext;
    355             if (dctx==NULL) return ERROR(memory_allocation);
    356             ZBUFFv07_decompressInitDictionary(dctx, dict, dictSize);
    357             *legacyContext = dctx;
    358             return 0;
    359         }
    360 #endif
    361     }
    362 }
    363 
    364 
    365 
    366 MEM_STATIC size_t ZSTD_decompressLegacyStream(void* legacyContext, U32 version,
    367                                               ZSTD_outBuffer* output, ZSTD_inBuffer* input)
    368 {
    369     static char x;
    370     /* Avoid passing NULL to legacy decoding. */
    371     if (output->dst == NULL) {
    372         assert(output->size == 0);
    373         output->dst = &x;
    374     }
    375     if (input->src == NULL) {
    376         assert(input->size == 0);
    377         input->src = &x;
    378     }
    379     DEBUGLOG(5, "ZSTD_decompressLegacyStream for v0.%u", version);
    380     switch(version)
    381     {
    382         default :
    383         case 1 :
    384         case 2 :
    385         case 3 :
    386             (void)legacyContext; (void)output; (void)input;
    387             return ERROR(version_unsupported);
    388 #if (ZSTD_LEGACY_SUPPORT <= 4)
    389         case 4 :
    390             {
    391                 ZBUFFv04_DCtx* dctx = (ZBUFFv04_DCtx*) legacyContext;
    392                 const void* src = (const char*)input->src + input->pos;
    393                 size_t readSize = input->size - input->pos;
    394                 void* dst = (char*)output->dst + output->pos;
    395                 size_t decodedSize = output->size - output->pos;
    396                 size_t const hintSize = ZBUFFv04_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
    397                 output->pos += decodedSize;
    398                 input->pos += readSize;
    399                 return hintSize;
    400             }
    401 #endif
    402 #if (ZSTD_LEGACY_SUPPORT <= 5)
    403         case 5 :
    404             {
    405                 ZBUFFv05_DCtx* dctx = (ZBUFFv05_DCtx*) legacyContext;
    406                 const void* src = (const char*)input->src + input->pos;
    407                 size_t readSize = input->size - input->pos;
    408                 void* dst = (char*)output->dst + output->pos;
    409                 size_t decodedSize = output->size - output->pos;
    410                 size_t const hintSize = ZBUFFv05_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
    411                 output->pos += decodedSize;
    412                 input->pos += readSize;
    413                 return hintSize;
    414             }
    415 #endif
    416 #if (ZSTD_LEGACY_SUPPORT <= 6)
    417         case 6 :
    418             {
    419                 ZBUFFv06_DCtx* dctx = (ZBUFFv06_DCtx*) legacyContext;
    420                 const void* src = (const char*)input->src + input->pos;
    421                 size_t readSize = input->size - input->pos;
    422                 void* dst = (char*)output->dst + output->pos;
    423                 size_t decodedSize = output->size - output->pos;
    424                 size_t const hintSize = ZBUFFv06_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
    425                 output->pos += decodedSize;
    426                 input->pos += readSize;
    427                 return hintSize;
    428             }
    429 #endif
    430 #if (ZSTD_LEGACY_SUPPORT <= 7)
    431         case 7 :
    432             {
    433                 ZBUFFv07_DCtx* dctx = (ZBUFFv07_DCtx*) legacyContext;
    434                 const void* src = (const char*)input->src + input->pos;
    435                 size_t readSize = input->size - input->pos;
    436                 void* dst = (char*)output->dst + output->pos;
    437                 size_t decodedSize = output->size - output->pos;
    438                 size_t const hintSize = ZBUFFv07_decompressContinue(dctx, dst, &decodedSize, src, &readSize);
    439                 output->pos += decodedSize;
    440                 input->pos += readSize;
    441                 return hintSize;
    442             }
    443 #endif
    444     }
    445 }
    446 
    447 
    448 #if defined (__cplusplus)
    449 }
    450 #endif
    451 
    452 #endif   /* ZSTD_LEGACY_H */
    453