Esempio n. 1
0
static SRes SzReadSubStreamsInfo(
      CSzData *sd,
      uint32_t numFolders,
      CSzFolder *folders,
      uint32_t *numUnpackStreams,
      uint64_t **unpackSizes,
      uint8_t **digestsDefined,
      uint32_t **digests,
      ISzAlloc *allocTemp)
{
   uint64_t type = 0;
   uint32_t i;
   uint32_t si = 0;
   uint32_t numDigests = 0;

   for (i = 0; i < numFolders; i++)
      folders[i].NumUnpackStreams = 1;
   *numUnpackStreams = numFolders;

   for (;;)
   {
      RINOK(SzReadID(sd, &type));
      if (type == k7zIdNumUnpackStream)
      {
         *numUnpackStreams = 0;
         for (i = 0; i < numFolders; i++)
         {
            uint32_t numStreams;
            RINOK(SzReadNumber32(sd, &numStreams));
            folders[i].NumUnpackStreams = numStreams;
            *numUnpackStreams += numStreams;
         }
         continue;
      }
      if (type == k7zIdCRC || type == k7zIdSize)
         break;
      if (type == k7zIdEnd)
         break;
      RINOK(SzSkeepData(sd));
   }

   if (*numUnpackStreams == 0)
   {
      *unpackSizes = 0;
      *digestsDefined = 0;
      *digests = 0;
   }
   else
   {
      *unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t));
      RINOM(*unpackSizes);
      *digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t));
      RINOM(*digestsDefined);
      *digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t));
      RINOM(*digests);
   }

   for (i = 0; i < numFolders; i++)
   {
      /*
         v3.13 incorrectly worked with empty folders
         v4.07: we check that folder is empty
         */
      uint64_t sum = 0;
      uint32_t j;
      uint32_t numSubstreams = folders[i].NumUnpackStreams;
      if (numSubstreams == 0)
         continue;
      if (type == k7zIdSize)
         for (j = 1; j < numSubstreams; j++)
         {
            uint64_t size;
            RINOK(SzReadNumber(sd, &size));
            (*unpackSizes)[si++] = size;
            sum += size;
         }
      (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum;
   }
   if (type == k7zIdSize)
   {
      RINOK(SzReadID(sd, &type));
   }

   for (i = 0; i < *numUnpackStreams; i++)
   {
      (*digestsDefined)[i] = 0;
      (*digests)[i] = 0;
   }


   for (i = 0; i < numFolders; i++)
   {
      uint32_t numSubstreams = folders[i].NumUnpackStreams;
      if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
         numDigests += numSubstreams;
   }


   si = 0;
   for (;;)
   {
      if (type == k7zIdCRC)
      {
         int digestIndex = 0;
         uint8_t *digestsDefined2 = 0;
         uint32_t *digests2 = 0;
         SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp);
         if (res == SZ_OK)
         {
            for (i = 0; i < numFolders; i++)
            {
               CSzFolder *folder = folders + i;
               uint32_t numSubstreams = folder->NumUnpackStreams;
               if (numSubstreams == 1 && folder->UnpackCRCDefined)
               {
                  (*digestsDefined)[si] = 1;
                  (*digests)[si] = folder->UnpackCRC;
                  si++;
               }
               else
               {
                  uint32_t j;
                  for (j = 0; j < numSubstreams; j++, digestIndex++)
                  {
                     (*digestsDefined)[si] = digestsDefined2[digestIndex];
                     (*digests)[si] = digests2[digestIndex];
                     si++;
                  }
               }
            }
         }
         IAlloc_Free(allocTemp, digestsDefined2);
         IAlloc_Free(allocTemp, digests2);
         RINOK(res);
      }
      else if (type == k7zIdEnd)
         return SZ_OK;
      else
      {
         RINOK(SzSkeepData(sd));
      }
      RINOK(SzReadID(sd, &type));
   }
}
Esempio n. 2
0
SRes SzArEx_Extract(
      const CSzArEx *p,
      ILookInStream *inStream,
      uint32_t fileIndex,
      uint32_t *blockIndex,
      uint8_t **outBuffer,
      size_t *outBufferSize,
      size_t *offset,
      size_t *outSizeProcessed,
      ISzAlloc *allocMain,
      ISzAlloc *allocTemp)
{
   uint32_t folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
   SRes res = SZ_OK;
   *offset = 0;
   *outSizeProcessed = 0;
   if (folderIndex == (uint32_t)-1)
   {
      IAlloc_Free(allocMain, *outBuffer);
      *blockIndex = folderIndex;
      *outBuffer = 0;
      *outBufferSize = 0;
      return SZ_OK;
   }

   if (*outBuffer == 0 || *blockIndex != folderIndex)
   {
      CSzFolder *folder = p->db.Folders + folderIndex;
      uint64_t unpackSizeSpec = SzFolder_GetUnpackSize(folder);
      size_t unpackSize = (size_t)unpackSizeSpec;
      uint64_t startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);

      if (unpackSize != unpackSizeSpec)
         return SZ_ERROR_MEM;
      *blockIndex = folderIndex;
      IAlloc_Free(allocMain, *outBuffer);
      *outBuffer = 0;

      RINOK(LookInStream_SeekTo(inStream, startOffset));

      if (res == SZ_OK)
      {
         *outBufferSize = unpackSize;
         if (unpackSize != 0)
         {
            *outBuffer = (uint8_t *)IAlloc_Alloc(allocMain, unpackSize);
            if (*outBuffer == 0)
               res = SZ_ERROR_MEM;
         }
         if (res == SZ_OK)
         {
            res = SzFolder_Decode(folder,
                  p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
                  inStream, startOffset,
                  *outBuffer, unpackSize, allocTemp);
            if (res == SZ_OK)
            {
               if (folder->UnpackCRCDefined)
               {
                  if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC)
                     res = SZ_ERROR_CRC;
               }
            }
         }
      }
   }
   if (res == SZ_OK)
   {
      uint32_t i;
      CSzFileItem *fileItem = p->db.Files + fileIndex;
      *offset = 0;
      for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
         *offset += (uint32_t)p->db.Files[i].Size;
      *outSizeProcessed = (size_t)fileItem->Size;
      if (*offset + *outSizeProcessed > *outBufferSize)
         return SZ_ERROR_FAIL;
      if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc)
         res = SZ_ERROR_CRC;
   }
   return res;
}
Esempio n. 3
0
static SRes SzFolder_Decode2(const CSzFolder *folder, const UInt64 *packSizes,
    ILookInStream *inStream, UInt64 startPos,
    Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
    Byte *tempBuf[])
{
  UInt32 ci;
  SizeT tempSizes[3] = { 0, 0, 0};
  SizeT tempSize3 = 0;
  Byte *tempBuf3 = 0;

  RINOK(CheckSupportedFolder(folder));

  for (ci = 0; ci < folder->NumCoders; ci++)
  {
    CSzCoderInfo *coder = &folder->Coders[ci];

    if (IS_MAIN_METHOD((UInt32)coder->MethodID))
    {
      UInt32 si = 0;
      UInt64 offset;
      UInt64 inSize;
      Byte *outBufCur = outBuffer;
      SizeT outSizeCur = outSize;
      if (folder->NumCoders == 4)
      {
        UInt32 indices[] = { 3, 2, 0 };
        UInt64 unpackSize = folder->UnpackSizes[ci];
        si = indices[ci];
        if (ci < 2)
        {
          Byte *temp;
          outSizeCur = (SizeT)unpackSize;
          if (outSizeCur != unpackSize)
            return SZ_ERROR_MEM;
          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
          if (temp == 0 && outSizeCur != 0)
            return SZ_ERROR_MEM;
          outBufCur = tempBuf[1 - ci] = temp;
          tempSizes[1 - ci] = outSizeCur;
        }
        else if (ci == 2)
        {
          if (unpackSize > outSize) /* check it */
            return SZ_ERROR_PARAM;
          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
          tempSize3 = outSizeCur = (SizeT)unpackSize;
        }
        else
          return SZ_ERROR_UNSUPPORTED;
      }
      offset = GetSum(packSizes, si);
      inSize = packSizes[si];
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));

      if (coder->MethodID == k_Copy)
      {
        if (inSize != outSizeCur) /* check it */
          return SZ_ERROR_DATA;
        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
      }
      else if (coder->MethodID == k_LZMA)
      {
        RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
      }
      else if (coder->MethodID == k_LZMA2)
      {
        #ifdef _7ZIP_LZMA2_SUPPPORT
        RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
        #else
        return SZ_ERROR_UNSUPPORTED;
        #endif
      }
      else
      {
        #ifdef _7ZIP_PPMD_SUPPPORT
        RINOK(SzDecodePpmd(coder, inSize, inStream, outBufCur, outSizeCur, allocMain));
        #else
        return SZ_ERROR_UNSUPPORTED;
        #endif
      }
    }
    else if (coder->MethodID == k_BCJ2)
    {
      UInt64 offset = GetSum(packSizes, 1);
      UInt64 s3Size = packSizes[1];
      SRes res;
      if (ci != 3)
        return SZ_ERROR_UNSUPPORTED;
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
      tempSizes[2] = (SizeT)s3Size;
      if (tempSizes[2] != s3Size)
        return SZ_ERROR_MEM;
      tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
      if (tempBuf[2] == 0 && tempSizes[2] != 0)
        return SZ_ERROR_MEM;
      res = SzDecodeCopy(s3Size, inStream, tempBuf[2]);
      RINOK(res)

      res = Bcj2_Decode(
          tempBuf3, tempSize3,
          tempBuf[0], tempSizes[0],
          tempBuf[1], tempSizes[1],
          tempBuf[2], tempSizes[2],
          outBuffer, outSize);
      RINOK(res)
    }
    else
    {
      if (ci != 1)
Esempio n. 4
0
SRes SzAr_Extract(
    const CSzArEx *p,
    ISzInStream *inStream, 
    UInt32 fileIndex,
    UInt32 *blockIndex,
    Byte **outBuffer, 
    size_t *outBufferSize,
    size_t *offset, 
    size_t *outSizeProcessed, 
    ISzAlloc *allocMain,
    ISzAlloc *allocTemp)
{
  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
  SRes res = SZ_OK;
  *offset = 0;
  *outSizeProcessed = 0;
  if (folderIndex == (UInt32)-1)
  {
    IAlloc_Free(allocMain, *outBuffer);
    *blockIndex = folderIndex;
    *outBuffer = 0;
    *outBufferSize = 0;
    return SZ_OK;
  }

  if (*outBuffer == 0 || *blockIndex != folderIndex)
  {
    CSzFolder *folder = p->db.Folders + folderIndex;
    CFileSize unPackSizeSpec = SzFolder_GetUnPackSize(folder);
    size_t unPackSize = (size_t)unPackSizeSpec;
    CFileSize startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);

    if (unPackSize != unPackSizeSpec)
      return SZ_ERROR_MEM;
    *blockIndex = folderIndex;
    IAlloc_Free(allocMain, *outBuffer);
    *outBuffer = 0;
    
    RINOK(inStream->Seek(inStream, startOffset, SZ_SEEK_SET));
    
    if (res == SZ_OK)
    {
      *outBufferSize = unPackSize;
      if (unPackSize != 0)
      {
        *outBuffer = (Byte *)IAlloc_Alloc(allocMain, unPackSize);
        if (*outBuffer == 0)
          res = SZ_ERROR_MEM;
      }
      if (res == SZ_OK)
      {
        res = SzDecode(p->db.PackSizes + 
          p->FolderStartPackStreamIndex[folderIndex], folder, 
          inStream, startOffset, 
          *outBuffer, unPackSize, allocTemp);
        if (res == SZ_OK)
        {
          if (folder->UnPackCRCDefined)
          {
            if (CrcCalc(*outBuffer, unPackSize) != folder->UnPackCRC)
              res = SZ_ERROR_CRC;
          }
        }
      }
    }
  }
  if (res == SZ_OK)
  {
    UInt32 i; 
    CSzFileItem *fileItem = p->db.Files + fileIndex;
    *offset = 0;
    for(i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
      *offset += (UInt32)p->db.Files[i].Size;
    *outSizeProcessed = (size_t)fileItem->Size;
    if (*offset + *outSizeProcessed > *outBufferSize)
      return SZ_ERROR_FAIL;
    {
      if (fileItem->IsFileCRCDefined)
      {
        if (CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->FileCRC)
          res = SZ_ERROR_CRC;
      }
    }
  }
  return res;
}
Esempio n. 5
0
SRes SzArEx_Extract(
    const CSzArEx *p,
    ILookInStream *inStream,
    UInt32 fileIndex,
    SzArEx_DictCache *dictCache,
    ISzAlloc *allocMain,
    ISzAlloc *allocTemp)
{
  UInt32 folderIndex = p->FileIndexToFolderIndexMap[fileIndex];
  SRes res = SZ_OK;
  dictCache->entryOffset = 0;
  dictCache->outSizeProcessed = 0;
  if (folderIndex == (UInt32)-1)
  {
    SzArEx_DictCache_free(dictCache);
    dictCache->blockIndex = folderIndex;
    return SZ_OK;
  }

  if (dictCache->outBuffer == 0 || dictCache->blockIndex != folderIndex)
  {
    CSzFolder *folder = p->db.Folders + folderIndex;
    UInt64 unpackSizeSpec = SzFolder_GetUnpackSize(folder);
    size_t unpackSize = (size_t)unpackSizeSpec;
    UInt64 startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0);

    if (unpackSize != unpackSizeSpec)
      return SZ_ERROR_MEM;
    
    SzArEx_DictCache_free(dictCache);
    dictCache->blockIndex = folderIndex;

    RINOK(LookInStream_SeekTo(inStream, startOffset));
    
    if (res == SZ_OK)
    {
      dictCache->outBufferSize = unpackSize;
      if (unpackSize != 0)
      {
        if (dictCache->mapFilename && (unpackSize >= k7zUnpackMapDictionaryInMemoryMaxNumBytes)) {
          // map to disk is enabled and file is larger than 1 megabyte.
          // note that an error condition is checked by seeing if
          // dictCache->outBuffer after a map attempt
          SzArEx_DictCache_mmap(dictCache);
        } else {
          dictCache->outBuffer = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
        }
        if (dictCache->outBuffer == 0)
          res = SZ_ERROR_MEM;
      }
      if (res == SZ_OK)
      {
        res = SzFolder_Decode(folder,
          p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex],
          inStream, startOffset,
          dictCache->outBuffer, unpackSize, allocTemp);
        if (res == SZ_OK)
        {
          if (folder->UnpackCRCDefined)
          {
#ifdef _7ZIP_CRC_SUPPORT
            if (CrcCalc(dictCache->outBuffer, unpackSize) != folder->UnpackCRC)
              res = SZ_ERROR_CRC;
#endif
          }
        }
      }
    }
  }
  if (res == SZ_OK)
  {
    UInt32 i;
    CSzFileItem *fileItem = p->db.Files + fileIndex;
    dictCache->entryOffset = 0;
    for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++)
      dictCache->entryOffset += (UInt32)p->db.Files[i].Size;
    dictCache->outSizeProcessed = (size_t)fileItem->Size;
    if (dictCache->entryOffset + dictCache->outSizeProcessed > dictCache->outBufferSize)
      return SZ_ERROR_FAIL;
#ifdef _7ZIP_CRC_SUPPORT
    if (fileItem->CrcDefined && CrcCalc(dictCache->outBuffer + dictCache->entryOffset, dictCache->outSizeProcessed) != fileItem->Crc)
      res = SZ_ERROR_CRC;
#endif
  }
  return res;
}
Esempio n. 6
0
SRes SzDecode2(const CFileSize *packSizes, const CSzFolder *folder,
    /*
    #ifdef _LZMA_IN_CB
    */
    ISzInStream *inStream, CFileSize startPos,
    /*
    #else
    const Byte *inBuffer,
    #endif
    */
    Byte *outBuffer, size_t outSize, ISzAlloc *allocMain,
    Byte *tempBuf[])
{
  UInt32 ci;
  size_t tempSizes[3] = { 0, 0, 0};
  size_t tempSize3 = 0;
  Byte *tempBuf3 = 0;

  RINOK(CheckSupportedFolder(folder));

  for (ci = 0; ci < folder->NumCoders; ci++)
  {
    CSzCoderInfo *coder = &folder->Coders[ci];

    if (coder->MethodID == k_Copy || coder->MethodID == k_LZMA || coder->MethodID == k_BZ2 || coder->MethodID == k_PPMD)
    {
      UInt32 si = 0;
      CFileSize offset;
      CFileSize inSize;
      Byte *outBufCur = outBuffer;
      size_t outSizeCur = outSize;
      if (folder->NumCoders == 4)
      {
        UInt32 indices[] = { 3, 2, 0 };
        CFileSize unpackSize = folder->UnpackSizes[ci];
        si = indices[ci];
        if (ci < 2)
        {
          Byte *temp;
          outSizeCur = (size_t)unpackSize;
          if (outSizeCur != unpackSize)
            return SZ_ERROR_MEM;
          temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
          if (temp == 0 && outSizeCur != 0)
            return SZ_ERROR_MEM;
          outBufCur = tempBuf[1 - ci] = temp;
          tempSizes[1 - ci] = outSizeCur;
        }
        else if (ci == 2)
        {
          if (unpackSize > outSize) // check it
            return SZ_ERROR_PARAM; // check it
          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
          tempSize3 = outSizeCur = (size_t)unpackSize;
        }
        else
          return SZ_ERROR_UNSUPPORTED;
      }
      offset = GetSum(packSizes, si);
      inSize = packSizes[si];
      /*
      #ifdef _LZMA_IN_CB
      */
      RINOK(inStream->Seek(inStream, startPos + offset, SZ_SEEK_SET));
      /*
      #endif
      */

      if (coder->MethodID == k_Copy)
      {
        if (inSize != outSizeCur) // check it
          return SZ_ERROR_DATA;
        
        /*
        #ifdef _LZMA_IN_CB
        */
        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
        /*
        #else
        memcpy(outBufCur, inBuffer + (size_t)offset, (size_t)inSize);
        #endif
        */
      }
      else if(coder->MethodID == k_PPMD)
      {
		SRes res = SZ_OK;
		struct PPMdProps pprops;

		pprops.maxorder = coder->Props.data[0];
		pprops.suballocsize = (coder->Props.data[1]) |
						(coder->Props.data[2] << 8) |
						(coder->Props.data[3] << 16) |
						(coder->Props.data[4] << 24);

		PPMdSubAllocatorVariantH *alloc=CreateSubAllocatorVariantH(pprops.suballocsize);

		PPMdModelVariantH model;
		StartPPMdModelVariantH(&model,inStream,alloc,pprops.maxorder,TRUE);
		outSizeCur = 0;

		while(outSizeCur < outSize)
		{
    		int byte=NextPPMdVariantHByte(&model);
    		if(byte<0) break;
    		*outBufCur = byte;
			outBufCur++;
			outSizeCur++;
		}

		FreeSubAllocatorVariantH(alloc);
   //     RINOK(res)
      }
      else if(coder->MethodID == k_BZ2)
      {
		int bzres = BZ_OK;
		SRes res = SZ_OK;
		bz_stream bzstrm;

		bzstrm.bzalloc = BzAlloc;
		bzstrm.bzfree = BzFree;
		bzstrm.opaque = NULL;

		void *inBuffer = NULL;
		size_t size = inSize;

		bzres = BZ2_bzDecompressInit(&bzstrm,0,0);
		if(bzres == BZ_OK) res = SZ_OK; else res=SZ_ERROR_MEM;
        RINOK(res)

		bzstrm.next_out = outBufCur;
		bzstrm.avail_out = outSizeCur;

		do
		{
			size=inSize;

	    	RINOK(inStream->Read(inStream, (void **)&inBuffer, &size));
			inSize -= size;

			bzstrm.next_in = (char *)(inBuffer);
			bzstrm.avail_in = size;

			do
			{
				bzres = BZ2_bzDecompress(&bzstrm);
			}while(bzstrm.avail_in>0 && bzres==BZ_OK);

		}while (bzres==BZ_OK);

		BZ2_bzDecompressEnd(&bzstrm);

		switch(bzres)
		{
			case BZ_CONFIG_ERROR:
			case BZ_PARAM_ERROR:
				res=SZ_ERROR_FAIL;
			break;
			case BZ_MEM_ERROR:
			case BZ_OUTBUFF_FULL:
				res=SZ_ERROR_MEM;
			break;
			case BZ_DATA_ERROR_MAGIC:
			case BZ_UNEXPECTED_EOF:
				res=SZ_ERROR_DATA;
			break;
			case BZ_DATA_ERROR:
				res=SZ_ERROR_CRC;
			break;
			case BZ_OK:
				res=SZ_OK;
			break;
			default:
				res=SZ_OK;
			break;
		}
        RINOK(res)
      }
      else
      {