예제 #1
0
파일: 7zIn.cpp 프로젝트: bks/qz7
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
    RINOK(ReadStream_FALSE(stream, _header, kHeaderSize));

    if (TestSignatureCandidate(_header))
        return S_OK;

    CByteBuffer byteBuffer;
    const UInt32 kBufferSize = (1 << 16);
    byteBuffer.SetCapacity(kBufferSize);
    Byte *buffer = byteBuffer;
    UInt32 numPrevBytes = kHeaderSize - 1;
    memcpy(buffer, _header + 1, numPrevBytes);
    UInt64 curTestPos = _arhiveBeginStreamPosition + 1;
    for (;;)
    {
        if (searchHeaderSizeLimit != NULL)
            if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
                break;
        do
        {
            UInt32 numReadBytes = kBufferSize - numPrevBytes;
            UInt32 processedSize;
            RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
            numPrevBytes += processedSize;
            if (processedSize == 0)
                return S_FALSE;
        }
        while (numPrevBytes < kHeaderSize);
        UInt32 numTests = numPrevBytes - kHeaderSize + 1;
        for (UInt32 pos = 0; pos < numTests; pos++)
        {
            for (; buffer[pos] != '7' && pos < numTests; pos++);
            if (pos == numTests)
                break;
            if (TestSignatureCandidate(buffer + pos))
            {
                memcpy(_header, buffer + pos, kHeaderSize);
                curTestPos += pos;
                _arhiveBeginStreamPosition = curTestPos;
                return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
            }
        }
        curTestPos += numTests;
        numPrevBytes -= numTests;
        memmove(buffer, buffer + numTests, numPrevBytes);
    }
    return S_FALSE;
}
예제 #2
0
static int LZMA_isArchive(const char *filename, int forWriting)
{
    PHYSFS_uint8 sig[k7zSignatureSize];
    PHYSFS_uint8 res;
    void *in;

    BAIL_IF_MACRO(forWriting, ERR_ARC_IS_READ_ONLY, 0);

    in = __PHYSFS_platformOpenRead(filename);
    BAIL_IF_MACRO(in == NULL, NULL, 0);

    if (__PHYSFS_platformRead(in, sig, k7zSignatureSize, 1) != 1)
        BAIL_MACRO(NULL, 0);

    /* Test whether sig is the 7z signature */
    res = TestSignatureCandidate(sig);

    __PHYSFS_platformClose(in);

    return res;
} /* LZMA_isArchive */
예제 #3
0
파일: 7zIn.c 프로젝트: Brunnis/RetroArch
static SRes SzArEx_Open2(
      CSzArEx *p,
      ILookInStream *inStream,
      ISzAlloc *allocMain,
      ISzAlloc *allocTemp)
{
   uint8_t header[k7zStartHeaderSize];
   int64_t startArcPos;
   uint64_t nextHeaderOffset, nextHeaderSize;
   size_t nextHeaderSizeT;
   uint32_t nextHeaderCRC;
   CBuf buffer;
   SRes res;

   startArcPos = 0;
   RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));

   RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));

   if (!TestSignatureCandidate(header))
      return SZ_ERROR_NO_ARCHIVE;
   if (header[6] != k7zMajorVersion)
      return SZ_ERROR_UNSUPPORTED;

   nextHeaderOffset = GetUi64(header + 12);
   nextHeaderSize = GetUi64(header + 20);
   nextHeaderCRC = GetUi32(header + 28);

   p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;

   if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
      return SZ_ERROR_CRC;

   nextHeaderSizeT = (size_t)nextHeaderSize;
   if (nextHeaderSizeT != nextHeaderSize)
      return SZ_ERROR_MEM;
   if (nextHeaderSizeT == 0)
      return SZ_OK;
   if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
         nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
      return SZ_ERROR_NO_ARCHIVE;

   {
      int64_t pos = 0;
      RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
      if ((uint64_t)pos < startArcPos + nextHeaderOffset ||
            (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
            (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
         return SZ_ERROR_INPUT_EOF;
   }

   RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));

   if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
      return SZ_ERROR_MEM;

   res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
   if (res == SZ_OK)
   {
      res = SZ_ERROR_ARCHIVE;
      if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
      {
         CSzData sd;
         uint64_t type;
         sd.Data = buffer.data;
         sd.Size = buffer.size;
         res = SzReadID(&sd, &type);
         if (res == SZ_OK)
         {
            if (type == k7zIdEncodedHeader)
            {
               CBuf outBuffer;
               Buf_Init(&outBuffer);
               res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
               if (res != SZ_OK)
                  Buf_Free(&outBuffer, allocTemp);
               else
               {
                  Buf_Free(&buffer, allocTemp);
                  buffer.data = outBuffer.data;
                  buffer.size = outBuffer.size;
                  sd.Data = buffer.data;
                  sd.Size = buffer.size;
                  res = SzReadID(&sd, &type);
               }
            }
         }
         if (res == SZ_OK)
         {
            if (type == k7zIdHeader)
               res = SzReadHeader(p, &sd, allocMain, allocTemp);
            else
               res = SZ_ERROR_UNSUPPORTED;
         }
      }
   }
   Buf_Free(&buffer, allocTemp);
   return res;
}
예제 #4
0
static void *LZMA_openArchive(PHYSFS_Io *io, const char *name, int forWriting)
{
    PHYSFS_uint8 sig[k7zSignatureSize];
    size_t len = 0;
    LZMAarchive *archive = NULL;

    assert(io != NULL);  /* shouldn't ever happen. */

    BAIL_IF_MACRO(forWriting, PHYSFS_ERR_READ_ONLY, NULL);

    if (io->read(io, sig, k7zSignatureSize) != k7zSignatureSize)
        return 0;
    BAIL_IF_MACRO(!TestSignatureCandidate(sig), PHYSFS_ERR_UNSUPPORTED, NULL);
    BAIL_IF_MACRO(!io->seek(io, 0), ERRPASS, NULL);

    archive = (LZMAarchive *) allocator.Malloc(sizeof (LZMAarchive));
    BAIL_IF_MACRO(archive == NULL, PHYSFS_ERR_OUT_OF_MEMORY, NULL);

    lzma_archive_init(archive);
    archive->stream.io = io;

    CrcGenerateTable();
    SzArDbExInit(&archive->db);
    if (lzma_err(SzArchiveOpen(&archive->stream.inStream,
                               &archive->db,
                               &archive->stream.allocImp,
                               &archive->stream.allocTempImp)) != SZ_OK)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        return NULL; /* Error is set by lzma_err! */
    } /* if */

    len = archive->db.Database.NumFiles * sizeof (LZMAfile);
    archive->files = (LZMAfile *) allocator.Malloc(len);
    if (archive->files == NULL)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    }

    /*
     * Init with 0 so we know when a folder is already cached
     * Values will be set by LZMA_openRead()
     */
    memset(archive->files, 0, len);

    len = archive->db.Database.NumFolders * sizeof (LZMAfolder);
    archive->folders = (LZMAfolder *) allocator.Malloc(len);
    if (archive->folders == NULL)
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
    }

    /*
     * Init with 0 so we know when a folder is already cached
     * Values will be set by LZMA_read()
     */
    memset(archive->folders, 0, len);

    if(!lzma_files_init(archive))
    {
        SzArDbExFree(&archive->db, SzFreePhysicsFS);
        lzma_archive_exit(archive);
        BAIL_MACRO(PHYSFS_ERR_OTHER_ERROR, NULL);
    }

    return archive;
} /* LZMA_openArchive */
예제 #5
0
파일: 7zIn.c 프로젝트: huairen/JArchive
static SRes SzArEx_Open2(
    CSzArEx *p,
    ISeekInStream *inStream,
    ISzAlloc *allocMain,
    ISzAlloc *allocTemp)
{
  Byte header[k7zStartHeaderSize];
  Int64 startArcPos;
  UInt64 nextHeaderOffset, nextHeaderSize;
  size_t nextHeaderSizeT;
  UInt32 nextHeaderCRC;
  CBuf buffer;
  SRes res;
  size_t readSize;

  startArcPos = 0;
  RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));

  readSize = k7zStartHeaderSize;
  res = inStream->Read(inStream, header, &readSize);
  if(res != SZ_OK)
	  return SZ_ERROR_NO_ARCHIVE;

  if (!TestSignatureCandidate(header))
    return SZ_ERROR_NO_ARCHIVE;
  if (header[6] != k7zMajorVersion)
    return SZ_ERROR_UNSUPPORTED;

  nextHeaderOffset = GetUi64(header + 12);
  nextHeaderSize = GetUi64(header + 20);
  nextHeaderCRC = GetUi32(header + 28);

  p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
  
  if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
    return SZ_ERROR_CRC;

  nextHeaderSizeT = (size_t)nextHeaderSize;
  if (nextHeaderSizeT != nextHeaderSize)
    return SZ_ERROR_MEM;
  if (nextHeaderSizeT == 0)
    return SZ_OK;
  if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
      nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
    return SZ_ERROR_NO_ARCHIVE;

  {
	  Int64 pos = 0;
	  RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
	  if ((UInt64)pos < startArcPos + nextHeaderOffset ||
		  (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
		  (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
		  return SZ_ERROR_INPUT_EOF;

	  pos = startArcPos + k7zStartHeaderSize + nextHeaderOffset;
	  RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_SET));
  }


  if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
    return SZ_ERROR_MEM;

  readSize = nextHeaderSizeT;
  res = inStream->Read(inStream, buffer.data, &readSize);
  if (res == SZ_OK)
  {
    res = SZ_ERROR_ARCHIVE;
    if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
    {
      CSzData sd;
      UInt64 type;
      sd.Data = buffer.data;
      sd.Size = buffer.size;
      res = SzReadID(&sd, &type);
      if (res == SZ_OK)
      {
        if (type == k7zIdEncodedHeader)
        {
		  CMemOutStream outStream;
		  MemOutStream_Init(&outStream);
          res = SzReadAndDecodePackedStreams(inStream, &sd, &outStream.s, p->startPosAfterHeader, allocTemp);
          if (res != SZ_OK)
            Buf_Free((CBuf*)&outStream.data, allocTemp);
          else
          {
            Buf_Free(&buffer, allocTemp);
            buffer.data = outStream.data;
            buffer.size = outStream.size;
            sd.Data = buffer.data;
            sd.Size = buffer.size;
            res = SzReadID(&sd, &type);
          }
        }
      }
      if (res == SZ_OK)
      {
        if (type == k7zIdHeader)
          res = SzReadHeader(p, &sd, allocMain, allocTemp);
        else
          res = SZ_ERROR_UNSUPPORTED;
      }
    }
  }
  Buf_Free(&buffer, allocTemp);
  return res;
}