tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Lzma2Dec.c (13158B)


      1 /* Lzma2Dec.c -- LZMA2 Decoder
      2 2018-02-19 : Igor Pavlov : Public domain */
      3 
      4 /* #define SHOW_DEBUG_INFO */
      5 
      6 #include "Precomp.h"
      7 
      8 #ifdef SHOW_DEBUG_INFO
      9 #include <stdio.h>
     10 #endif
     11 
     12 #include <string.h>
     13 
     14 #include "Lzma2Dec.h"
     15 
     16 /*
     17 00000000  -  End of data
     18 00000001 U U  -  Uncompressed, reset dic, need reset state and set new prop
     19 00000010 U U  -  Uncompressed, no reset
     20 100uuuuu U U P P  -  LZMA, no reset
     21 101uuuuu U U P P  -  LZMA, reset state
     22 110uuuuu U U P P S  -  LZMA, reset state + set new prop
     23 111uuuuu U U P P S  -  LZMA, reset state + set new prop, reset dic
     24 
     25  u, U - Unpack Size
     26  P - Pack Size
     27  S - Props
     28 */
     29 
     30 #define LZMA2_CONTROL_COPY_RESET_DIC 1
     31 
     32 #define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
     33 
     34 #define LZMA2_LCLP_MAX 4
     35 #define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
     36 
     37 #ifdef SHOW_DEBUG_INFO
     38 #define PRF(x) x
     39 #else
     40 #define PRF(x)
     41 #endif
     42 
     43 typedef enum
     44 {
     45  LZMA2_STATE_CONTROL,
     46  LZMA2_STATE_UNPACK0,
     47  LZMA2_STATE_UNPACK1,
     48  LZMA2_STATE_PACK0,
     49  LZMA2_STATE_PACK1,
     50  LZMA2_STATE_PROP,
     51  LZMA2_STATE_DATA,
     52  LZMA2_STATE_DATA_CONT,
     53  LZMA2_STATE_FINISHED,
     54  LZMA2_STATE_ERROR
     55 } ELzma2State;
     56 
     57 static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
     58 {
     59  UInt32 dicSize;
     60  if (prop > 40)
     61    return SZ_ERROR_UNSUPPORTED;
     62  dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
     63  props[0] = (Byte)LZMA2_LCLP_MAX;
     64  props[1] = (Byte)(dicSize);
     65  props[2] = (Byte)(dicSize >> 8);
     66  props[3] = (Byte)(dicSize >> 16);
     67  props[4] = (Byte)(dicSize >> 24);
     68  return SZ_OK;
     69 }
     70 
     71 SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
     72 {
     73  Byte props[LZMA_PROPS_SIZE];
     74  RINOK(Lzma2Dec_GetOldProps(prop, props));
     75  return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
     76 }
     77 
     78 SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
     79 {
     80  Byte props[LZMA_PROPS_SIZE];
     81  RINOK(Lzma2Dec_GetOldProps(prop, props));
     82  return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
     83 }
     84 
     85 void Lzma2Dec_Init(CLzma2Dec *p)
     86 {
     87  p->state = LZMA2_STATE_CONTROL;
     88  p->needInitLevel = 0xE0;
     89  p->isExtraMode = False;
     90  p->unpackSize = 0;
     91  
     92  // p->decoder.dicPos = 0; // we can use it instead of full init
     93  LzmaDec_Init(&p->decoder);
     94 }
     95 
     96 static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
     97 {
     98  switch (p->state)
     99  {
    100    case LZMA2_STATE_CONTROL:
    101      p->isExtraMode = False;
    102      p->control = b;
    103      PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
    104      PRF(printf(" %02X", (unsigned)b));
    105      if (b == 0)
    106        return LZMA2_STATE_FINISHED;
    107      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
    108      {
    109        if (b == LZMA2_CONTROL_COPY_RESET_DIC)
    110          p->needInitLevel = 0xC0;
    111        else if (b > 2 || p->needInitLevel == 0xE0)
    112          return LZMA2_STATE_ERROR;
    113      }
    114      else
    115      {
    116        if (b < p->needInitLevel)
    117          return LZMA2_STATE_ERROR;
    118        p->needInitLevel = 0;
    119        p->unpackSize = (UInt32)(b & 0x1F) << 16;
    120      }
    121      return LZMA2_STATE_UNPACK0;
    122    
    123    case LZMA2_STATE_UNPACK0:
    124      p->unpackSize |= (UInt32)b << 8;
    125      return LZMA2_STATE_UNPACK1;
    126    
    127    case LZMA2_STATE_UNPACK1:
    128      p->unpackSize |= (UInt32)b;
    129      p->unpackSize++;
    130      PRF(printf(" %7u", (unsigned)p->unpackSize));
    131      return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
    132    
    133    case LZMA2_STATE_PACK0:
    134      p->packSize = (UInt32)b << 8;
    135      return LZMA2_STATE_PACK1;
    136 
    137    case LZMA2_STATE_PACK1:
    138      p->packSize |= (UInt32)b;
    139      p->packSize++;
    140      // if (p->packSize < 5) return LZMA2_STATE_ERROR;
    141      PRF(printf(" %5u", (unsigned)p->packSize));
    142      return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
    143 
    144    case LZMA2_STATE_PROP:
    145    {
    146      unsigned lc, lp;
    147      if (b >= (9 * 5 * 5))
    148        return LZMA2_STATE_ERROR;
    149      lc = b % 9;
    150      b /= 9;
    151      p->decoder.prop.pb = (Byte)(b / 5);
    152      lp = b % 5;
    153      if (lc + lp > LZMA2_LCLP_MAX)
    154        return LZMA2_STATE_ERROR;
    155      p->decoder.prop.lc = (Byte)lc;
    156      p->decoder.prop.lp = (Byte)lp;
    157      return LZMA2_STATE_DATA;
    158    }
    159  }
    160  return LZMA2_STATE_ERROR;
    161 }
    162 
    163 static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
    164 {
    165  memcpy(p->dic + p->dicPos, src, size);
    166  p->dicPos += size;
    167  if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
    168    p->checkDicSize = p->prop.dicSize;
    169  p->processedPos += (UInt32)size;
    170 }
    171 
    172 void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
    173 
    174 
    175 SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
    176    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
    177 {
    178  SizeT inSize = *srcLen;
    179  *srcLen = 0;
    180  *status = LZMA_STATUS_NOT_SPECIFIED;
    181 
    182  while (p->state != LZMA2_STATE_ERROR)
    183  {
    184    SizeT dicPos;
    185 
    186    if (p->state == LZMA2_STATE_FINISHED)
    187    {
    188      *status = LZMA_STATUS_FINISHED_WITH_MARK;
    189      return SZ_OK;
    190    }
    191    
    192    dicPos = p->decoder.dicPos;
    193    
    194    if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
    195    {
    196      *status = LZMA_STATUS_NOT_FINISHED;
    197      return SZ_OK;
    198    }
    199 
    200    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
    201    {
    202      if (*srcLen == inSize)
    203      {
    204        *status = LZMA_STATUS_NEEDS_MORE_INPUT;
    205        return SZ_OK;
    206      }
    207      (*srcLen)++;
    208      p->state = Lzma2Dec_UpdateState(p, *src++);
    209      if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
    210        break;
    211      continue;
    212    }
    213    
    214    {
    215      SizeT inCur = inSize - *srcLen;
    216      SizeT outCur = dicLimit - dicPos;
    217      ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
    218      
    219      if (outCur >= p->unpackSize)
    220      {
    221        outCur = (SizeT)p->unpackSize;
    222        curFinishMode = LZMA_FINISH_END;
    223      }
    224 
    225      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
    226      {
    227        if (inCur == 0)
    228        {
    229          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
    230          return SZ_OK;
    231        }
    232 
    233        if (p->state == LZMA2_STATE_DATA)
    234        {
    235          Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
    236          LzmaDec_InitDicAndState(&p->decoder, initDic, False);
    237        }
    238 
    239        if (inCur > outCur)
    240          inCur = outCur;
    241        if (inCur == 0)
    242          break;
    243 
    244        LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
    245 
    246        src += inCur;
    247        *srcLen += inCur;
    248        p->unpackSize -= (UInt32)inCur;
    249        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
    250      }
    251      else
    252      {
    253        SRes res;
    254 
    255        if (p->state == LZMA2_STATE_DATA)
    256        {
    257          Bool initDic = (p->control >= 0xE0);
    258          Bool initState = (p->control >= 0xA0);
    259          LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
    260          p->state = LZMA2_STATE_DATA_CONT;
    261        }
    262  
    263        if (inCur > p->packSize)
    264          inCur = (SizeT)p->packSize;
    265        
    266        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
    267 
    268        src += inCur;
    269        *srcLen += inCur;
    270        p->packSize -= (UInt32)inCur;
    271        outCur = p->decoder.dicPos - dicPos;
    272        p->unpackSize -= (UInt32)outCur;
    273 
    274        if (res != 0)
    275          break;
    276        
    277        if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
    278        {
    279          if (p->packSize == 0)
    280            break;
    281          return SZ_OK;
    282        }
    283 
    284        if (inCur == 0 && outCur == 0)
    285        {
    286          if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
    287              || p->unpackSize != 0
    288              || p->packSize != 0)
    289            break;
    290          p->state = LZMA2_STATE_CONTROL;
    291        }
    292        
    293        *status = LZMA_STATUS_NOT_SPECIFIED;
    294      }
    295    }
    296  }
    297  
    298  *status = LZMA_STATUS_NOT_SPECIFIED;
    299  p->state = LZMA2_STATE_ERROR;
    300  return SZ_ERROR_DATA;
    301 }
    302 
    303 
    304 
    305 
    306 ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
    307    SizeT outSize,
    308    const Byte *src, SizeT *srcLen,
    309    int checkFinishBlock)
    310 {
    311  SizeT inSize = *srcLen;
    312  *srcLen = 0;
    313 
    314  while (p->state != LZMA2_STATE_ERROR)
    315  {
    316    if (p->state == LZMA2_STATE_FINISHED)
    317      return LZMA_STATUS_FINISHED_WITH_MARK;
    318 
    319    if (outSize == 0 && !checkFinishBlock)
    320      return LZMA_STATUS_NOT_FINISHED;
    321    
    322    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
    323    {
    324      if (*srcLen == inSize)
    325        return LZMA_STATUS_NEEDS_MORE_INPUT;
    326      (*srcLen)++;
    327 
    328      p->state = Lzma2Dec_UpdateState(p, *src++);
    329 
    330      if (p->state == LZMA2_STATE_UNPACK0)
    331      {
    332        // if (p->decoder.dicPos != 0)
    333        if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
    334          return LZMA2_PARSE_STATUS_NEW_BLOCK;
    335        // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
    336      }
    337 
    338      // The following code can be commented.
    339      // It's not big problem, if we read additional input bytes.
    340      // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
    341 
    342      if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
    343      {
    344        // checkFinishBlock is true. So we expect that block must be finished,
    345        // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
    346        // break;
    347        return LZMA_STATUS_NOT_FINISHED;
    348      }
    349 
    350      if (p->state == LZMA2_STATE_DATA)
    351        return LZMA2_PARSE_STATUS_NEW_CHUNK;
    352 
    353      continue;
    354    }
    355 
    356    if (outSize == 0)
    357      return LZMA_STATUS_NOT_FINISHED;
    358 
    359    {
    360      SizeT inCur = inSize - *srcLen;
    361 
    362      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
    363      {
    364        if (inCur == 0)
    365          return LZMA_STATUS_NEEDS_MORE_INPUT;
    366        if (inCur > p->unpackSize)
    367          inCur = p->unpackSize;
    368        if (inCur > outSize)
    369          inCur = outSize;
    370        p->decoder.dicPos += inCur;
    371        src += inCur;
    372        *srcLen += inCur;
    373        outSize -= inCur;
    374        p->unpackSize -= (UInt32)inCur;
    375        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
    376      }
    377      else
    378      {
    379        p->isExtraMode = True;
    380 
    381        if (inCur == 0)
    382        {
    383          if (p->packSize != 0)
    384            return LZMA_STATUS_NEEDS_MORE_INPUT;
    385        }
    386        else if (p->state == LZMA2_STATE_DATA)
    387        {
    388          p->state = LZMA2_STATE_DATA_CONT;
    389          if (*src != 0)
    390          {
    391            // first byte of lzma chunk must be Zero
    392            *srcLen += 1;
    393            p->packSize--;
    394            break;
    395          }
    396        }
    397  
    398        if (inCur > p->packSize)
    399          inCur = (SizeT)p->packSize;
    400 
    401        src += inCur;
    402        *srcLen += inCur;
    403        p->packSize -= (UInt32)inCur;
    404 
    405        if (p->packSize == 0)
    406        {
    407          SizeT rem = outSize;
    408          if (rem > p->unpackSize)
    409            rem = p->unpackSize;
    410          p->decoder.dicPos += rem;
    411          p->unpackSize -= (UInt32)rem;
    412          outSize -= rem;
    413          if (p->unpackSize == 0)
    414            p->state = LZMA2_STATE_CONTROL;
    415        }
    416      }
    417    }
    418  }
    419  
    420  p->state = LZMA2_STATE_ERROR;
    421  return LZMA_STATUS_NOT_SPECIFIED;
    422 }
    423 
    424 
    425 
    426 
    427 SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
    428 {
    429  SizeT outSize = *destLen, inSize = *srcLen;
    430  *srcLen = *destLen = 0;
    431  
    432  for (;;)
    433  {
    434    SizeT inCur = inSize, outCur, dicPos;
    435    ELzmaFinishMode curFinishMode;
    436    SRes res;
    437    
    438    if (p->decoder.dicPos == p->decoder.dicBufSize)
    439      p->decoder.dicPos = 0;
    440    dicPos = p->decoder.dicPos;
    441    curFinishMode = LZMA_FINISH_ANY;
    442    outCur = p->decoder.dicBufSize - dicPos;
    443    
    444    if (outCur >= outSize)
    445    {
    446      outCur = outSize;
    447      curFinishMode = finishMode;
    448    }
    449 
    450    res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
    451    
    452    src += inCur;
    453    inSize -= inCur;
    454    *srcLen += inCur;
    455    outCur = p->decoder.dicPos - dicPos;
    456    memcpy(dest, p->decoder.dic + dicPos, outCur);
    457    dest += outCur;
    458    outSize -= outCur;
    459    *destLen += outCur;
    460    if (res != 0)
    461      return res;
    462    if (outCur == 0 || outSize == 0)
    463      return SZ_OK;
    464  }
    465 }
    466 
    467 
    468 SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
    469    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
    470 {
    471  CLzma2Dec p;
    472  SRes res;
    473  SizeT outSize = *destLen, inSize = *srcLen;
    474  *destLen = *srcLen = 0;
    475  *status = LZMA_STATUS_NOT_SPECIFIED;
    476  Lzma2Dec_Construct(&p);
    477  RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
    478  p.decoder.dic = dest;
    479  p.decoder.dicBufSize = outSize;
    480  Lzma2Dec_Init(&p);
    481  *srcLen = inSize;
    482  res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
    483  *destLen = p.decoder.dicPos;
    484  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
    485    res = SZ_ERROR_INPUT_EOF;
    486  Lzma2Dec_FreeProbs(&p, alloc);
    487  return res;
    488 }