"Fossies" - the Fresh Open Source Software Archive

Member "hashcat-6.2.6/deps/LZMA-SDK/C/7zDec.c" (2 Sep 2022, 16131 Bytes) of package /linux/privat/hashcat-6.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "7zDec.c": 6.2.1_vs_6.2.2.

    1 /* 7zDec.c -- Decoding from 7z folder
    2 2021-02-09 : Igor Pavlov : Public domain */
    3 
    4 #include "Precomp.h"
    5 
    6 #include <string.h>
    7 
    8 /* #define _7ZIP_PPMD_SUPPPORT */
    9 
   10 #include "7z.h"
   11 #include "7zCrc.h"
   12 
   13 #include "Bcj2.h"
   14 #include "Bra.h"
   15 #include "CpuArch.h"
   16 #include "Delta.h"
   17 #include "LzmaDec.h"
   18 #include "Lzma2Dec.h"
   19 #ifdef _7ZIP_PPMD_SUPPPORT
   20 #include "Ppmd7.h"
   21 #endif
   22 
   23 #define k_Copy 0
   24 #ifndef _7Z_NO_METHOD_LZMA2
   25 #define k_LZMA2 0x21
   26 #endif
   27 #define k_LZMA  0x30101
   28 #define k_BCJ2  0x303011B
   29 #ifndef _7Z_NO_METHODS_FILTERS
   30 #define k_Delta 3
   31 #define k_BCJ   0x3030103
   32 #define k_PPC   0x3030205
   33 #define k_IA64  0x3030401
   34 #define k_ARM   0x3030501
   35 #define k_ARMT  0x3030701
   36 #define k_SPARC 0x3030805
   37 #endif
   38 
   39 #ifdef _7ZIP_PPMD_SUPPPORT
   40 
   41 #define k_PPMD 0x30401
   42 
   43 typedef struct
   44 {
   45   IByteIn vt;
   46   const Byte *cur;
   47   const Byte *end;
   48   const Byte *begin;
   49   UInt64 processed;
   50   BoolInt extra;
   51   SRes res;
   52   const ILookInStream *inStream;
   53 } CByteInToLook;
   54 
   55 static Byte ReadByte(const IByteIn *pp)
   56 {
   57   CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
   58   if (p->cur != p->end)
   59     return *p->cur++;
   60   if (p->res == SZ_OK)
   61   {
   62     size_t size = (size_t)(p->cur - p->begin);
   63     p->processed += size;
   64     p->res = ILookInStream_Skip(p->inStream, size);
   65     size = (1 << 25);
   66     p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
   67     p->cur = p->begin;
   68     p->end = p->begin + size;
   69     if (size != 0)
   70       return *p->cur++;;
   71   }
   72   p->extra = True;
   73   return 0;
   74 }
   75 
   76 static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
   77     Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
   78 {
   79   CPpmd7 ppmd;
   80   CByteInToLook s;
   81   SRes res = SZ_OK;
   82 
   83   s.vt.Read = ReadByte;
   84   s.inStream = inStream;
   85   s.begin = s.end = s.cur = NULL;
   86   s.extra = False;
   87   s.res = SZ_OK;
   88   s.processed = 0;
   89 
   90   if (propsSize != 5)
   91     return SZ_ERROR_UNSUPPORTED;
   92 
   93   {
   94     unsigned order = props[0];
   95     UInt32 memSize = GetUi32(props + 1);
   96     if (order < PPMD7_MIN_ORDER ||
   97         order > PPMD7_MAX_ORDER ||
   98         memSize < PPMD7_MIN_MEM_SIZE ||
   99         memSize > PPMD7_MAX_MEM_SIZE)
  100       return SZ_ERROR_UNSUPPORTED;
  101     Ppmd7_Construct(&ppmd);
  102     if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
  103       return SZ_ERROR_MEM;
  104     Ppmd7_Init(&ppmd, order);
  105   }
  106   {
  107     ppmd.rc.dec.Stream = &s.vt;
  108     if (!Ppmd7z_RangeDec_Init(&ppmd.rc.dec))
  109       res = SZ_ERROR_DATA;
  110     else if (!s.extra)
  111     {
  112       Byte *buf = outBuffer;
  113       const Byte *lim = buf + outSize;
  114       for (; buf != lim; buf++)
  115       {
  116         int sym = Ppmd7z_DecodeSymbol(&ppmd);
  117         if (s.extra || sym < 0)
  118           break;
  119         *buf = (Byte)sym;
  120       }
  121       if (buf != lim)
  122         res = SZ_ERROR_DATA;
  123       else if (!Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec))
  124       {
  125         /* if (Ppmd7z_DecodeSymbol(&ppmd) != PPMD7_SYM_END || !Ppmd7z_RangeDec_IsFinishedOK(&ppmd.rc.dec)) */
  126         res = SZ_ERROR_DATA;
  127       }
  128     }
  129     if (s.extra)
  130       res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
  131     else if (s.processed + (size_t)(s.cur - s.begin) != inSize)
  132       res = SZ_ERROR_DATA;
  133   }
  134   Ppmd7_Free(&ppmd, allocMain);
  135   return res;
  136 }
  137 
  138 #endif
  139 
  140 
  141 static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
  142     Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
  143 {
  144   CLzmaDec state;
  145   SRes res = SZ_OK;
  146 
  147   LzmaDec_Construct(&state);
  148   RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
  149   state.dic = outBuffer;
  150   state.dicBufSize = outSize;
  151   LzmaDec_Init(&state);
  152 
  153   for (;;)
  154   {
  155     const void *inBuf = NULL;
  156     size_t lookahead = (1 << 18);
  157     if (lookahead > inSize)
  158       lookahead = (size_t)inSize;
  159     res = ILookInStream_Look(inStream, &inBuf, &lookahead);
  160     if (res != SZ_OK)
  161       break;
  162 
  163     {
  164       SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
  165       ELzmaStatus status;
  166       res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
  167       lookahead -= inProcessed;
  168       inSize -= inProcessed;
  169       if (res != SZ_OK)
  170         break;
  171 
  172       if (status == LZMA_STATUS_FINISHED_WITH_MARK)
  173       {
  174         if (outSize != state.dicPos || inSize != 0)
  175           res = SZ_ERROR_DATA;
  176         break;
  177       }
  178 
  179       if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
  180         break;
  181 
  182       if (inProcessed == 0 && dicPos == state.dicPos)
  183       {
  184         res = SZ_ERROR_DATA;
  185         break;
  186       }
  187 
  188       res = ILookInStream_Skip(inStream, inProcessed);
  189       if (res != SZ_OK)
  190         break;
  191     }
  192   }
  193 
  194   LzmaDec_FreeProbs(&state, allocMain);
  195   return res;
  196 }
  197 
  198 
  199 #ifndef _7Z_NO_METHOD_LZMA2
  200 
  201 static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
  202     Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
  203 {
  204   CLzma2Dec state;
  205   SRes res = SZ_OK;
  206 
  207   Lzma2Dec_Construct(&state);
  208   if (propsSize != 1)
  209     return SZ_ERROR_DATA;
  210   RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
  211   state.decoder.dic = outBuffer;
  212   state.decoder.dicBufSize = outSize;
  213   Lzma2Dec_Init(&state);
  214 
  215   for (;;)
  216   {
  217     const void *inBuf = NULL;
  218     size_t lookahead = (1 << 18);
  219     if (lookahead > inSize)
  220       lookahead = (size_t)inSize;
  221     res = ILookInStream_Look(inStream, &inBuf, &lookahead);
  222     if (res != SZ_OK)
  223       break;
  224 
  225     {
  226       SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
  227       ELzmaStatus status;
  228       res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
  229       lookahead -= inProcessed;
  230       inSize -= inProcessed;
  231       if (res != SZ_OK)
  232         break;
  233 
  234       if (status == LZMA_STATUS_FINISHED_WITH_MARK)
  235       {
  236         if (outSize != state.decoder.dicPos || inSize != 0)
  237           res = SZ_ERROR_DATA;
  238         break;
  239       }
  240 
  241       if (inProcessed == 0 && dicPos == state.decoder.dicPos)
  242       {
  243         res = SZ_ERROR_DATA;
  244         break;
  245       }
  246 
  247       res = ILookInStream_Skip(inStream, inProcessed);
  248       if (res != SZ_OK)
  249         break;
  250     }
  251   }
  252 
  253   Lzma2Dec_FreeProbs(&state, allocMain);
  254   return res;
  255 }
  256 
  257 #endif
  258 
  259 
  260 static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
  261 {
  262   while (inSize > 0)
  263   {
  264     const void *inBuf;
  265     size_t curSize = (1 << 18);
  266     if (curSize > inSize)
  267       curSize = (size_t)inSize;
  268     RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
  269     if (curSize == 0)
  270       return SZ_ERROR_INPUT_EOF;
  271     memcpy(outBuffer, inBuf, curSize);
  272     outBuffer += curSize;
  273     inSize -= curSize;
  274     RINOK(ILookInStream_Skip(inStream, curSize));
  275   }
  276   return SZ_OK;
  277 }
  278 
  279 static BoolInt IS_MAIN_METHOD(UInt32 m)
  280 {
  281   switch (m)
  282   {
  283     case k_Copy:
  284     case k_LZMA:
  285     #ifndef _7Z_NO_METHOD_LZMA2
  286     case k_LZMA2:
  287     #endif
  288     #ifdef _7ZIP_PPMD_SUPPPORT
  289     case k_PPMD:
  290     #endif
  291       return True;
  292   }
  293   return False;
  294 }
  295 
  296 static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
  297 {
  298   return
  299       c->NumStreams == 1
  300       /* && c->MethodID <= (UInt32)0xFFFFFFFF */
  301       && IS_MAIN_METHOD((UInt32)c->MethodID);
  302 }
  303 
  304 #define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
  305 
  306 static SRes CheckSupportedFolder(const CSzFolder *f)
  307 {
  308   if (f->NumCoders < 1 || f->NumCoders > 4)
  309     return SZ_ERROR_UNSUPPORTED;
  310   if (!IS_SUPPORTED_CODER(&f->Coders[0]))
  311     return SZ_ERROR_UNSUPPORTED;
  312   if (f->NumCoders == 1)
  313   {
  314     if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
  315       return SZ_ERROR_UNSUPPORTED;
  316     return SZ_OK;
  317   }
  318   
  319   
  320   #ifndef _7Z_NO_METHODS_FILTERS
  321 
  322   if (f->NumCoders == 2)
  323   {
  324     const CSzCoderInfo *c = &f->Coders[1];
  325     if (
  326         /* c->MethodID > (UInt32)0xFFFFFFFF || */
  327         c->NumStreams != 1
  328         || f->NumPackStreams != 1
  329         || f->PackStreams[0] != 0
  330         || f->NumBonds != 1
  331         || f->Bonds[0].InIndex != 1
  332         || f->Bonds[0].OutIndex != 0)
  333       return SZ_ERROR_UNSUPPORTED;
  334     switch ((UInt32)c->MethodID)
  335     {
  336       case k_Delta:
  337       case k_BCJ:
  338       case k_PPC:
  339       case k_IA64:
  340       case k_SPARC:
  341       case k_ARM:
  342       case k_ARMT:
  343         break;
  344       default:
  345         return SZ_ERROR_UNSUPPORTED;
  346     }
  347     return SZ_OK;
  348   }
  349 
  350   #endif
  351 
  352   
  353   if (f->NumCoders == 4)
  354   {
  355     if (!IS_SUPPORTED_CODER(&f->Coders[1])
  356         || !IS_SUPPORTED_CODER(&f->Coders[2])
  357         || !IS_BCJ2(&f->Coders[3]))
  358       return SZ_ERROR_UNSUPPORTED;
  359     if (f->NumPackStreams != 4
  360         || f->PackStreams[0] != 2
  361         || f->PackStreams[1] != 6
  362         || f->PackStreams[2] != 1
  363         || f->PackStreams[3] != 0
  364         || f->NumBonds != 3
  365         || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
  366         || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
  367         || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
  368       return SZ_ERROR_UNSUPPORTED;
  369     return SZ_OK;
  370   }
  371   
  372   return SZ_ERROR_UNSUPPORTED;
  373 }
  374 
  375 #ifndef _7Z_NO_METHODS_FILTERS
  376 #define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
  377 #endif
  378 
  379 static SRes SzFolder_Decode2(const CSzFolder *folder,
  380     const Byte *propsData,
  381     const UInt64 *unpackSizes,
  382     const UInt64 *packPositions,
  383     ILookInStream *inStream, UInt64 startPos,
  384     Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
  385     Byte *tempBuf[])
  386 {
  387   UInt32 ci;
  388   SizeT tempSizes[3] = { 0, 0, 0};
  389   SizeT tempSize3 = 0;
  390   Byte *tempBuf3 = 0;
  391 
  392   RINOK(CheckSupportedFolder(folder));
  393 
  394   for (ci = 0; ci < folder->NumCoders; ci++)
  395   {
  396     const CSzCoderInfo *coder = &folder->Coders[ci];
  397 
  398     if (IS_MAIN_METHOD((UInt32)coder->MethodID))
  399     {
  400       UInt32 si = 0;
  401       UInt64 offset;
  402       UInt64 inSize;
  403       Byte *outBufCur = outBuffer;
  404       SizeT outSizeCur = outSize;
  405       if (folder->NumCoders == 4)
  406       {
  407         UInt32 indices[] = { 3, 2, 0 };
  408         UInt64 unpackSize = unpackSizes[ci];
  409         si = indices[ci];
  410         if (ci < 2)
  411         {
  412           Byte *temp;
  413           outSizeCur = (SizeT)unpackSize;
  414           if (outSizeCur != unpackSize)
  415             return SZ_ERROR_MEM;
  416           temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
  417           if (!temp && outSizeCur != 0)
  418             return SZ_ERROR_MEM;
  419           outBufCur = tempBuf[1 - ci] = temp;
  420           tempSizes[1 - ci] = outSizeCur;
  421         }
  422         else if (ci == 2)
  423         {
  424           if (unpackSize > outSize) /* check it */
  425             return SZ_ERROR_PARAM;
  426           tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
  427           tempSize3 = outSizeCur = (SizeT)unpackSize;
  428         }
  429         else
  430           return SZ_ERROR_UNSUPPORTED;
  431       }
  432       offset = packPositions[si];
  433       inSize = packPositions[(size_t)si + 1] - offset;
  434       RINOK(LookInStream_SeekTo(inStream, startPos + offset));
  435 
  436       if (coder->MethodID == k_Copy)
  437       {
  438         if (inSize != outSizeCur) /* check it */
  439           return SZ_ERROR_DATA;
  440         RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
  441       }
  442       else if (coder->MethodID == k_LZMA)
  443       {
  444         RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
  445       }
  446       #ifndef _7Z_NO_METHOD_LZMA2
  447       else if (coder->MethodID == k_LZMA2)
  448       {
  449         RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
  450       }
  451       #endif
  452       #ifdef _7ZIP_PPMD_SUPPPORT
  453       else if (coder->MethodID == k_PPMD)
  454       {
  455         RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
  456       }
  457       #endif
  458       else
  459         return SZ_ERROR_UNSUPPORTED;
  460     }
  461     else if (coder->MethodID == k_BCJ2)
  462     {
  463       UInt64 offset = packPositions[1];
  464       UInt64 s3Size = packPositions[2] - offset;
  465       
  466       if (ci != 3)
  467         return SZ_ERROR_UNSUPPORTED;
  468       
  469       tempSizes[2] = (SizeT)s3Size;
  470       if (tempSizes[2] != s3Size)
  471         return SZ_ERROR_MEM;
  472       tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
  473       if (!tempBuf[2] && tempSizes[2] != 0)
  474         return SZ_ERROR_MEM;
  475       
  476       RINOK(LookInStream_SeekTo(inStream, startPos + offset));
  477       RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
  478 
  479       if ((tempSizes[0] & 3) != 0 ||
  480           (tempSizes[1] & 3) != 0 ||
  481           tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
  482         return SZ_ERROR_DATA;
  483 
  484       {
  485         CBcj2Dec p;
  486         
  487         p.bufs[0] = tempBuf3;   p.lims[0] = tempBuf3 + tempSize3;
  488         p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
  489         p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
  490         p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
  491         
  492         p.dest = outBuffer;
  493         p.destLim = outBuffer + outSize;
  494         
  495         Bcj2Dec_Init(&p);
  496         RINOK(Bcj2Dec_Decode(&p));
  497 
  498         {
  499           unsigned i;
  500           for (i = 0; i < 4; i++)
  501             if (p.bufs[i] != p.lims[i])
  502               return SZ_ERROR_DATA;
  503           
  504           if (!Bcj2Dec_IsFinished(&p))
  505             return SZ_ERROR_DATA;
  506 
  507           if (p.dest != p.destLim
  508              || p.state != BCJ2_STREAM_MAIN)
  509             return SZ_ERROR_DATA;
  510         }
  511       }
  512     }
  513     #ifndef _7Z_NO_METHODS_FILTERS
  514     else if (ci == 1)
  515     {
  516       if (coder->MethodID == k_Delta)
  517       {
  518         if (coder->PropsSize != 1)
  519           return SZ_ERROR_UNSUPPORTED;
  520         {
  521           Byte state[DELTA_STATE_SIZE];
  522           Delta_Init(state);
  523           Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
  524         }
  525       }
  526       else
  527       {
  528         if (coder->PropsSize != 0)
  529           return SZ_ERROR_UNSUPPORTED;
  530         switch (coder->MethodID)
  531         {
  532           case k_BCJ:
  533           {
  534             UInt32 state;
  535             x86_Convert_Init(state);
  536             x86_Convert(outBuffer, outSize, 0, &state, 0);
  537             break;
  538           }
  539           CASE_BRA_CONV(PPC)
  540           CASE_BRA_CONV(IA64)
  541           CASE_BRA_CONV(SPARC)
  542           CASE_BRA_CONV(ARM)
  543           CASE_BRA_CONV(ARMT)
  544           default:
  545             return SZ_ERROR_UNSUPPORTED;
  546         }
  547       }
  548     }
  549     #endif
  550     else
  551       return SZ_ERROR_UNSUPPORTED;
  552   }
  553 
  554   return SZ_OK;
  555 }
  556 
  557 
  558 SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
  559     ILookInStream *inStream, UInt64 startPos,
  560     Byte *outBuffer, size_t outSize,
  561     ISzAllocPtr allocMain)
  562 {
  563   SRes res;
  564   CSzFolder folder;
  565   CSzData sd;
  566   
  567   const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
  568   sd.Data = data;
  569   sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
  570   
  571   res = SzGetNextFolderItem(&folder, &sd);
  572   
  573   if (res != SZ_OK)
  574     return res;
  575 
  576   if (sd.Size != 0
  577       || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
  578       || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
  579     return SZ_ERROR_FAIL;
  580   {
  581     unsigned i;
  582     Byte *tempBuf[3] = { 0, 0, 0};
  583 
  584     res = SzFolder_Decode2(&folder, data,
  585         &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
  586         p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
  587         inStream, startPos,
  588         outBuffer, (SizeT)outSize, allocMain, tempBuf);
  589     
  590     for (i = 0; i < 3; i++)
  591       ISzAlloc_Free(allocMain, tempBuf[i]);
  592 
  593     if (res == SZ_OK)
  594       if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
  595         if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
  596           res = SZ_ERROR_CRC;
  597 
  598     return res;
  599   }
  600 }