"Fossies" - the Fresh Open Source Software Archive

Member "unrar/unpack.cpp" (4 May 2022, 10638 Bytes) of package /linux/misc/unrarsrc-6.1.7.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. For more information about "unpack.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 #include "coder.cpp"
    4 #include "suballoc.cpp"
    5 #include "model.cpp"
    6 #include "unpackinline.cpp"
    7 #ifdef RAR_SMP
    8 #include "unpack50mt.cpp"
    9 #endif
   10 #ifndef SFX_MODULE
   11 #include "unpack15.cpp"
   12 #include "unpack20.cpp"
   13 #endif
   14 #include "unpack30.cpp"
   15 #include "unpack50.cpp"
   16 #include "unpack50frag.cpp"
   17 
   18 Unpack::Unpack(ComprDataIO *DataIO)
   19 :Inp(true),VMCodeInp(true)
   20 {
   21   UnpIO=DataIO;
   22   Window=NULL;
   23   Fragmented=false;
   24   Suspended=false;
   25   UnpAllBuf=false;
   26   UnpSomeRead=false;
   27 #ifdef RAR_SMP
   28   MaxUserThreads=1;
   29   UnpThreadPool=NULL;
   30   ReadBufMT=NULL;
   31   UnpThreadData=NULL;
   32 #endif
   33   MaxWinSize=0;
   34   MaxWinMask=0;
   35 
   36   // Perform initialization, which should be done only once for all files.
   37   // It prevents crash if first DoUnpack call is later made with wrong
   38   // (true) 'Solid' value.
   39   UnpInitData(false);
   40 #ifndef SFX_MODULE
   41   // RAR 1.5 decompression initialization
   42   UnpInitData15(false);
   43   InitHuff();
   44 #endif
   45 }
   46 
   47 
   48 Unpack::~Unpack()
   49 {
   50   InitFilters30(false);
   51 
   52   if (Window!=NULL)
   53     free(Window);
   54 #ifdef RAR_SMP
   55   delete UnpThreadPool;
   56   delete[] ReadBufMT;
   57   delete[] UnpThreadData;
   58 #endif
   59 }
   60 
   61 
   62 #ifdef RAR_SMP
   63 void Unpack::SetThreads(uint Threads)
   64 {
   65   // More than 8 threads are unlikely to provide noticeable gain
   66   // for unpacking, but would use the additional memory.
   67   MaxUserThreads=Min(Threads,8);
   68   UnpThreadPool=new ThreadPool(MaxUserThreads);
   69 }
   70 #endif
   71 
   72 
   73 void Unpack::Init(size_t WinSize,bool Solid)
   74 {
   75   // If 32-bit RAR unpacks an archive with 4 GB dictionary, the window size
   76   // will be 0 because of size_t overflow. Let's issue the memory error.
   77   if (WinSize==0)
   78     ErrHandler.MemoryError();
   79 
   80   // Minimum window size must be at least twice more than maximum possible
   81   // size of filter block, which is 0x10000 in RAR now. If window size is
   82   // smaller, we can have a block with never cleared flt->NextWindow flag
   83   // in UnpWriteBuf(). Minimum window size 0x20000 would be enough, but let's
   84   // use 0x40000 for extra safety and possible filter area size expansion.
   85   const size_t MinAllocSize=0x40000;
   86   if (WinSize<MinAllocSize)
   87     WinSize=MinAllocSize;
   88 
   89   if (WinSize<=MaxWinSize) // Use the already allocated window.
   90     return;
   91   if ((WinSize>>16)>0x10000) // Window size must not exceed 4 GB.
   92     return;
   93 
   94   // Archiving code guarantees that window size does not grow in the same
   95   // solid stream. So if we are here, we are either creating a new window
   96   // or increasing the size of non-solid window. So we could safely reject
   97   // current window data without copying them to a new window, though being
   98   // extra cautious, we still handle the solid window grow case below.
   99   bool Grow=Solid && (Window!=NULL || Fragmented);
  100 
  101   // We do not handle growth for existing fragmented window.
  102   if (Grow && Fragmented)
  103     throw std::bad_alloc();
  104 
  105   byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize);
  106 
  107   if (NewWindow==NULL)
  108     if (Grow || WinSize<0x1000000)
  109     {
  110       // We do not support growth for new fragmented window.
  111       // Also exclude RAR4 and small dictionaries.
  112       throw std::bad_alloc();
  113     }
  114     else
  115     {
  116       if (Window!=NULL) // If allocated by preceding files.
  117       {
  118         free(Window);
  119         Window=NULL;
  120       }
  121       FragWindow.Init(WinSize);
  122       Fragmented=true;
  123     }
  124 
  125   if (!Fragmented)
  126   {
  127     // Clean the window to generate the same output when unpacking corrupt
  128     // RAR files, which may access unused areas of sliding dictionary.
  129     memset(NewWindow,0,WinSize);
  130 
  131     // If Window is not NULL, it means that window size has grown.
  132     // In solid streams we need to copy data to a new window in such case.
  133     // RAR archiving code does not allow it in solid streams now,
  134     // but let's implement it anyway just in case we'll change it sometimes.
  135     if (Grow)
  136       for (size_t I=1;I<=MaxWinSize;I++)
  137         NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
  138 
  139     if (Window!=NULL)
  140       free(Window);
  141     Window=NewWindow;
  142   }
  143 
  144   MaxWinSize=WinSize;
  145   MaxWinMask=MaxWinSize-1;
  146 }
  147 
  148 
  149 void Unpack::DoUnpack(uint Method,bool Solid)
  150 {
  151   // Methods <50 will crash in Fragmented mode when accessing NULL Window.
  152   // They cannot be called in such mode now, but we check it below anyway
  153   // just for extra safety.
  154   switch(Method)
  155   {
  156 #ifndef SFX_MODULE
  157     case 15: // rar 1.5 compression
  158       if (!Fragmented)
  159         Unpack15(Solid);
  160       break;
  161     case 20: // rar 2.x compression
  162     case 26: // files larger than 2GB
  163       if (!Fragmented)
  164         Unpack20(Solid);
  165       break;
  166 #endif
  167     case 29: // rar 3.x compression
  168       if (!Fragmented)
  169         Unpack29(Solid);
  170       break;
  171     case 50: // RAR 5.0 compression algorithm.
  172 #ifdef RAR_SMP
  173       if (MaxUserThreads>1)
  174       {
  175 //      We do not use the multithreaded unpack routine to repack RAR archives
  176 //      in 'suspended' mode, because unlike the single threaded code it can
  177 //      write more than one dictionary for same loop pass. So we would need
  178 //      larger buffers of unknown size. Also we do not support multithreading
  179 //      in fragmented window mode.
  180           if (!Fragmented)
  181           {
  182             Unpack5MT(Solid);
  183             break;
  184           }
  185       }
  186 #endif
  187       Unpack5(Solid);
  188       break;
  189   }
  190 }
  191 
  192 
  193 void Unpack::UnpInitData(bool Solid)
  194 {
  195   if (!Solid)
  196   {
  197     memset(OldDist,0,sizeof(OldDist));
  198     OldDistPtr=0;
  199     LastDist=LastLength=0;
  200 //    memset(Window,0,MaxWinSize);
  201     memset(&BlockTables,0,sizeof(BlockTables));
  202     UnpPtr=WrPtr=0;
  203     WriteBorder=Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
  204   }
  205   // Filters never share several solid files, so we can safely reset them
  206   // even in solid archive.
  207   InitFilters();
  208 
  209   Inp.InitBitInput();
  210   WrittenFileSize=0;
  211   ReadTop=0;
  212   ReadBorder=0;
  213 
  214   memset(&BlockHeader,0,sizeof(BlockHeader));
  215   BlockHeader.BlockSize=-1;  // '-1' means not defined yet.
  216 #ifndef SFX_MODULE
  217   UnpInitData20(Solid);
  218 #endif
  219   UnpInitData30(Solid);
  220   UnpInitData50(Solid);
  221 }
  222 
  223 
  224 // LengthTable contains the length in bits for every element of alphabet.
  225 // Dec is the structure to decode Huffman code/
  226 // Size is size of length table and DecodeNum field in Dec structure,
  227 void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
  228 {
  229   // Size of alphabet and DecodePos array.
  230   Dec->MaxNum=Size;
  231 
  232   // Calculate how many entries for every bit length in LengthTable we have.
  233   uint LengthCount[16];
  234   memset(LengthCount,0,sizeof(LengthCount));
  235   for (size_t I=0;I<Size;I++)
  236     LengthCount[LengthTable[I] & 0xf]++;
  237 
  238   // We must not calculate the number of zero length codes.
  239   LengthCount[0]=0;
  240 
  241   // Set the entire DecodeNum to zero.
  242   memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
  243 
  244   // Initialize not really used entry for zero length code.
  245   Dec->DecodePos[0]=0;
  246 
  247   // Start code for bit length 1 is 0.
  248   Dec->DecodeLen[0]=0;
  249 
  250   // Right aligned upper limit code for current bit length.
  251   uint UpperLimit=0;
  252 
  253   for (size_t I=1;I<16;I++)
  254   {
  255     // Adjust the upper limit code.
  256     UpperLimit+=LengthCount[I];
  257 
  258     // Left aligned upper limit code.
  259     uint LeftAligned=UpperLimit<<(16-I);
  260 
  261     // Prepare the upper limit code for next bit length.
  262     UpperLimit*=2;
  263 
  264     // Store the left aligned upper limit code.
  265     Dec->DecodeLen[I]=(uint)LeftAligned;
  266 
  267     // Every item of this array contains the sum of all preceding items.
  268     // So it contains the start position in code list for every bit length. 
  269     Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
  270   }
  271 
  272   // Prepare the copy of DecodePos. We'll modify this copy below,
  273   // so we cannot use the original DecodePos.
  274   uint CopyDecodePos[ASIZE(Dec->DecodePos)];
  275   memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
  276 
  277   // For every bit length in the bit length table and so for every item
  278   // of alphabet.
  279   for (uint I=0;I<Size;I++)
  280   {
  281     // Get the current bit length.
  282     byte CurBitLength=LengthTable[I] & 0xf;
  283 
  284     if (CurBitLength!=0)
  285     {
  286       // Last position in code list for current bit length.
  287       uint LastPos=CopyDecodePos[CurBitLength];
  288 
  289       // Prepare the decode table, so this position in code list will be
  290       // decoded to current alphabet item number.
  291       Dec->DecodeNum[LastPos]=(ushort)I;
  292 
  293       // We'll use next position number for this bit length next time.
  294       // So we pass through the entire range of positions available
  295       // for every bit length.
  296       CopyDecodePos[CurBitLength]++;
  297     }
  298   }
  299 
  300   // Define the number of bits to process in quick mode. We use more bits
  301   // for larger alphabets. More bits means that more codes will be processed
  302   // in quick mode, but also that more time will be spent to preparation
  303   // of tables for quick decode.
  304   switch (Size)
  305   {
  306     case NC:
  307     case NC20:
  308     case NC30:
  309       Dec->QuickBits=MAX_QUICK_DECODE_BITS;
  310       break;
  311     default:
  312       Dec->QuickBits=MAX_QUICK_DECODE_BITS-3;
  313       break;
  314   }
  315 
  316   // Size of tables for quick mode.
  317   uint QuickDataSize=1<<Dec->QuickBits;
  318 
  319   // Bit length for current code, start from 1 bit codes. It is important
  320   // to use 1 bit instead of 0 for minimum code length, so we are moving
  321   // forward even when processing a corrupt archive.
  322   uint CurBitLength=1;
  323 
  324   // For every right aligned bit string which supports the quick decoding.
  325   for (uint Code=0;Code<QuickDataSize;Code++)
  326   {
  327     // Left align the current code, so it will be in usual bit field format.
  328     uint BitField=Code<<(16-Dec->QuickBits);
  329 
  330     // Prepare the table for quick decoding of bit lengths.
  331   
  332     // Find the upper limit for current bit field and adjust the bit length
  333     // accordingly if necessary.
  334     while (CurBitLength<ASIZE(Dec->DecodeLen) && BitField>=Dec->DecodeLen[CurBitLength])
  335       CurBitLength++;
  336 
  337     // Translation of right aligned bit string to bit length.
  338     Dec->QuickLen[Code]=CurBitLength;
  339 
  340     // Prepare the table for quick translation of position in code list
  341     // to position in alphabet.
  342 
  343     // Calculate the distance from the start code for current bit length.
  344     uint Dist=BitField-Dec->DecodeLen[CurBitLength-1];
  345 
  346     // Right align the distance.
  347     Dist>>=(16-CurBitLength);
  348 
  349     // Now we can calculate the position in the code list. It is the sum
  350     // of first position for current bit length and right aligned distance
  351     // between our bit field and start code for current bit length.
  352     uint Pos;
  353     if (CurBitLength<ASIZE(Dec->DecodePos) &&
  354         (Pos=Dec->DecodePos[CurBitLength]+Dist)<Size)
  355     {
  356       // Define the code to alphabet number translation.
  357       Dec->QuickNum[Code]=Dec->DecodeNum[Pos];
  358     }
  359     else
  360     {
  361       // Can be here for length table filled with zeroes only (empty).
  362       Dec->QuickNum[Code]=0;
  363     }
  364   }
  365 }