Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'C/Archive/7z/7zIn.c')
-rwxr-xr-xC/Archive/7z/7zIn.c265
1 files changed, 100 insertions, 165 deletions
diff --git a/C/Archive/7z/7zIn.c b/C/Archive/7z/7zIn.c
index 6592e7f4..fa10ecff 100755
--- a/C/Archive/7z/7zIn.c
+++ b/C/Archive/7z/7zIn.c
@@ -1,12 +1,11 @@
/* 7zIn.c -- 7z Input functions
-2008-08-17
-Igor Pavlov
-Copyright (c) 1999-2008 Igor Pavlov
-Read 7zIn.h for license options */
+2008-11-23 : Igor Pavlov : Public domain */
-#include "7zIn.h"
-#include "7zDecode.h"
#include "../../7zCrc.h"
+#include "../../CpuArch.h"
+
+#include "7zDecode.h"
+#include "7zIn.h"
#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; }
@@ -30,12 +29,12 @@ void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
}
/*
-CFileSize GetFolderPackStreamSize(int folderIndex, int streamIndex) const
+UInt64 GetFolderPackStreamSize(int folderIndex, int streamIndex) const
{
return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex];
}
-CFileSize GetFilePackSize(int fileIndex) const
+UInt64 GetFilePackSize(int fileIndex) const
{
int folderIndex = FileIndexToFolderIndexMap[fileIndex];
if (folderIndex >= 0)
@@ -54,7 +53,7 @@ CFileSize GetFilePackSize(int fileIndex) const
static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
{
UInt32 startPos = 0;
- CFileSize startPosSize = 0;
+ UInt64 startPosSize = 0;
UInt32 i;
UInt32 folderIndex = 0;
UInt32 indexInFolder = 0;
@@ -65,7 +64,7 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
startPos += p->db.Folders[i].NumPackStreams;
}
- MY_ALLOC(CFileSize, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
+ MY_ALLOC(UInt64, p->PackStreamStartPositions, p->db.NumPackStreams, alloc);
for (i = 0; i < p->db.NumPackStreams; i++)
{
@@ -115,22 +114,22 @@ static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc)
}
-CFileSize SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
+UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder)
{
- return p->ArchiveInfo.DataStartPosition +
+ return p->dataPos +
p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder];
}
-int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, CFileSize *resSize)
+int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize)
{
UInt32 packStreamIndex = p->FolderStartPackStreamIndex[folderIndex];
CSzFolder *folder = p->db.Folders + folderIndex;
- CFileSize size = 0;
+ UInt64 size = 0;
UInt32 i;
for (i = 0; i < folder->NumPackStreams; i++)
{
- CFileSize t = size + p->db.PackSizes[packStreamIndex + i];
- if (t < size) // check it
+ UInt64 t = size + p->db.PackSizes[packStreamIndex + i];
+ if (t < size) /* check it */
return SZ_ERROR_FAIL;
size = t;
}
@@ -173,58 +172,6 @@ SRes SzReadTime(const CObjectVector<CBuf> &dataVector,
}
*/
-static SRes SafeReadDirect(ISzInStream *inStream, Byte *data, size_t size)
-{
- while (size > 0)
- {
- void *inBufferSpec;
- size_t processedSize = size;
- const Byte *inBuffer;
- RINOK(inStream->Read(inStream, (void **)&inBufferSpec, &processedSize));
- inBuffer = (const Byte *)inBufferSpec;
- if (processedSize == 0)
- return SZ_ERROR_INPUT_EOF;
- size -= processedSize;
- do
- *data++ = *inBuffer++;
- while (--processedSize != 0);
- }
- return SZ_OK;
-}
-
-static SRes SafeReadDirectByte(ISzInStream *inStream, Byte *data)
-{
- return SafeReadDirect(inStream, data, 1);
-}
-
-static SRes SafeReadDirectUInt32(ISzInStream *inStream, UInt32 *value, UInt32 *crc)
-{
- int i;
- *value = 0;
- for (i = 0; i < 4; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt32)b << (8 * i));
- *crc = CRC_UPDATE_BYTE(*crc, b);
- }
- return SZ_OK;
-}
-
-static SRes SafeReadDirectUInt64(ISzInStream *inStream, UInt64 *value, UInt32 *crc)
-{
- int i;
- *value = 0;
- for (i = 0; i < 8; i++)
- {
- Byte b;
- RINOK(SafeReadDirectByte(inStream, &b));
- *value |= ((UInt64)b << (8 * i));
- *crc = CRC_UPDATE_BYTE(*crc, b);
- }
- return SZ_OK;
-}
-
static int TestSignatureCandidate(Byte *testBytes)
{
size_t i;
@@ -295,14 +242,6 @@ static SRes SzReadNumber(CSzData *sd, UInt64 *value)
return SZ_OK;
}
-static SRes SzReadSize(CSzData *sd, CFileSize *value)
-{
- UInt64 value64;
- RINOK(SzReadNumber(sd, &value64));
- *value = (CFileSize)value64;
- return SZ_OK;
-}
-
static SRes SzReadNumber32(CSzData *sd, UInt32 *value)
{
UInt64 value64;
@@ -415,24 +354,24 @@ static SRes SzReadHashDigests(
static SRes SzReadPackInfo(
CSzData *sd,
- CFileSize *dataOffset,
+ UInt64 *dataOffset,
UInt32 *numPackStreams,
- CFileSize **packSizes,
+ UInt64 **packSizes,
Byte **packCRCsDefined,
UInt32 **packCRCs,
ISzAlloc *alloc)
{
UInt32 i;
- RINOK(SzReadSize(sd, dataOffset));
+ RINOK(SzReadNumber(sd, dataOffset));
RINOK(SzReadNumber32(sd, numPackStreams));
RINOK(SzWaitAttribute(sd, k7zIdSize));
- MY_ALLOC(CFileSize, *packSizes, (size_t)*numPackStreams, alloc);
+ MY_ALLOC(UInt64, *packSizes, (size_t)*numPackStreams, alloc);
for (i = 0; i < *numPackStreams; i++)
{
- RINOK(SzReadSize(sd, (*packSizes) + i));
+ RINOK(SzReadNumber(sd, (*packSizes) + i));
}
for (;;)
@@ -498,7 +437,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
return SZ_ERROR_UNSUPPORTED;
coder->MethodID = 0;
for (j = 0; j < idSize; j++)
- coder->MethodID |= (CMethodID)longID[idSize - 1 - j] << (8 * j);
+ coder->MethodID |= (UInt64)longID[idSize - 1 - j] << (8 * j);
if ((mainByte & 0x10) != 0)
{
@@ -548,7 +487,7 @@ static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc)
for (i = 0; i < numBindPairs; i++)
{
- CBindPair *bindPair = folder->BindPairs + i;;
+ CBindPair *bindPair = folder->BindPairs + i;
RINOK(SzReadNumber32(sd, &bindPair->InIndex));
RINOK(SzReadNumber32(sd, &bindPair->OutIndex));
}
@@ -609,11 +548,11 @@ static SRes SzReadUnpackInfo(
CSzFolder *folder = (*folders) + i;
UInt32 numOutStreams = SzFolder_GetNumOutStreams(folder);
- MY_ALLOC(CFileSize, folder->UnpackSizes, (size_t)numOutStreams, alloc);
+ MY_ALLOC(UInt64, folder->UnpackSizes, (size_t)numOutStreams, alloc);
for (j = 0; j < numOutStreams; j++)
{
- RINOK(SzReadSize(sd, folder->UnpackSizes + j));
+ RINOK(SzReadNumber(sd, folder->UnpackSizes + j));
}
}
@@ -652,7 +591,7 @@ static SRes SzReadSubStreamsInfo(
UInt32 numFolders,
CSzFolder *folders,
UInt32 *numUnpackStreams,
- CFileSize **unpackSizes,
+ UInt64 **unpackSizes,
Byte **digestsDefined,
UInt32 **digests,
ISzAlloc *allocTemp)
@@ -696,7 +635,7 @@ static SRes SzReadSubStreamsInfo(
}
else
{
- *unpackSizes = (CFileSize *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(CFileSize));
+ *unpackSizes = (UInt64 *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(UInt64));
RINOM(*unpackSizes);
*digestsDefined = (Byte *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(Byte));
RINOM(*digestsDefined);
@@ -710,7 +649,7 @@ static SRes SzReadSubStreamsInfo(
v3.13 incorrectly worked with empty folders
v4.07: we check that folder is empty
*/
- CFileSize sum = 0;
+ UInt64 sum = 0;
UInt32 j;
UInt32 numSubstreams = folders[i].NumUnpackStreams;
if (numSubstreams == 0)
@@ -718,8 +657,8 @@ static SRes SzReadSubStreamsInfo(
if (type == k7zIdSize)
for (j = 1; j < numSubstreams; j++)
{
- CFileSize size;
- RINOK(SzReadSize(sd, &size));
+ UInt64 size;
+ RINOK(SzReadNumber(sd, &size));
(*unpackSizes)[si++] = size;
sum += size;
}
@@ -795,10 +734,10 @@ static SRes SzReadSubStreamsInfo(
static SRes SzReadStreamsInfo(
CSzData *sd,
- CFileSize *dataOffset,
+ UInt64 *dataOffset,
CSzAr *p,
UInt32 *numUnpackStreams,
- CFileSize **unpackSizes, /* allocTemp */
+ UInt64 **unpackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */
ISzAlloc *alloc,
@@ -917,7 +856,7 @@ static SRes SzReadFileNames(CSzData *sd, UInt32 numFiles, CSzFileItem *files, IS
static SRes SzReadHeader2(
CSzArEx *p, /* allocMain */
CSzData *sd,
- CFileSize **unpackSizes, /* allocTemp */
+ UInt64 **unpackSizes, /* allocTemp */
Byte **digestsDefined, /* allocTemp */
UInt32 **digests, /* allocTemp */
Byte **emptyStreamVector, /* allocTemp */
@@ -945,13 +884,13 @@ static SRes SzReadHeader2(
if (type == k7zIdMainStreamsInfo)
{
RINOK(SzReadStreamsInfo(sd,
- &p->ArchiveInfo.DataStartPosition,
+ &p->dataPos,
&p->db,
&numUnpackStreams,
unpackSizes,
digestsDefined,
digests, allocMain, allocTemp));
- p->ArchiveInfo.DataStartPosition += p->ArchiveInfo.StartPositionAfterHeader;
+ p->dataPos += p->startPosAfterHeader;
RINOK(SzReadID(sd, &type));
}
@@ -1070,7 +1009,7 @@ static SRes SzReadHeader(
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
- CFileSize *unpackSizes = 0;
+ UInt64 *unpackSizes = 0;
Byte *digestsDefined = 0;
UInt32 *digests = 0;
Byte *emptyStreamVector = 0;
@@ -1090,21 +1029,21 @@ static SRes SzReadHeader(
}
static SRes SzReadAndDecodePackedStreams2(
- ISzInStream *inStream,
+ ILookInStream *inStream,
CSzData *sd,
CBuf *outBuffer,
- CFileSize baseOffset,
+ UInt64 baseOffset,
CSzAr *p,
- CFileSize **unpackSizes,
+ UInt64 **unpackSizes,
Byte **digestsDefined,
UInt32 **digests,
ISzAlloc *allocTemp)
{
UInt32 numUnpackStreams = 0;
- CFileSize dataStartPos;
+ UInt64 dataStartPos;
CSzFolder *folder;
- CFileSize unpackSize;
+ UInt64 unpackSize;
SRes res;
RINOK(SzReadStreamsInfo(sd, &dataStartPos, p,
@@ -1118,7 +1057,7 @@ static SRes SzReadAndDecodePackedStreams2(
folder = p->Folders;
unpackSize = SzFolder_GetUnpackSize(folder);
- RINOK(inStream->Seek(inStream, dataStartPos, SZ_SEEK_SET));
+ RINOK(LookInStream_SeekTo(inStream, dataStartPos));
if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp))
return SZ_ERROR_MEM;
@@ -1134,14 +1073,14 @@ static SRes SzReadAndDecodePackedStreams2(
}
static SRes SzReadAndDecodePackedStreams(
- ISzInStream *inStream,
+ ILookInStream *inStream,
CSzData *sd,
CBuf *outBuffer,
- CFileSize baseOffset,
+ UInt64 baseOffset,
ISzAlloc *allocTemp)
{
CSzAr p;
- CFileSize *unpackSizes = 0;
+ UInt64 *unpackSizes = 0;
Byte *digestsDefined = 0;
UInt32 *digests = 0;
SRes res;
@@ -1158,105 +1097,101 @@ static SRes SzReadAndDecodePackedStreams(
static SRes SzArEx_Open2(
CSzArEx *p,
- ISzInStream *inStream,
+ ILookInStream *inStream,
ISzAlloc *allocMain,
ISzAlloc *allocTemp)
{
- Byte signature[k7zSignatureSize];
- Byte version;
- UInt32 crcFromArchive;
- UInt64 nextHeaderOffset;
- UInt64 nextHeaderSize;
+ Byte header[k7zStartHeaderSize];
+ UInt64 nextHeaderOffset, nextHeaderSize;
+ size_t nextHeaderSizeT;
UInt32 nextHeaderCRC;
- UInt32 crc = 0;
- CFileSize pos = 0;
CBuf buffer;
- CSzData sd;
SRes res;
- if (SafeReadDirect(inStream, signature, k7zSignatureSize) != SZ_OK)
- return SZ_ERROR_NO_ARCHIVE;
+ RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
- if (!TestSignatureCandidate(signature))
+ if (!TestSignatureCandidate(header))
return SZ_ERROR_NO_ARCHIVE;
-
- /*
- p.Clear();
- p.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
- */
- RINOK(SafeReadDirectByte(inStream, &version));
- if (version != k7zMajorVersion)
+ if (header[6] != k7zMajorVersion)
return SZ_ERROR_UNSUPPORTED;
- RINOK(SafeReadDirectByte(inStream, &version));
- RINOK(SafeReadDirectUInt32(inStream, &crcFromArchive, &crc));
+ nextHeaderOffset = GetUi64(header + 12);
+ nextHeaderSize = GetUi64(header + 20);
+ nextHeaderCRC = GetUi32(header + 28);
- crc = CRC_INIT_VAL;
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderOffset, &crc));
- RINOK(SafeReadDirectUInt64(inStream, &nextHeaderSize, &crc));
- RINOK(SafeReadDirectUInt32(inStream, &nextHeaderCRC, &crc));
-
- pos = k7zStartHeaderSize;
- p->ArchiveInfo.StartPositionAfterHeader = pos;
+ p->startPosAfterHeader = k7zStartHeaderSize;
- if (CRC_GET_DIGEST(crc) != crcFromArchive)
+ if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
return SZ_ERROR_CRC;
- if (nextHeaderSize == 0)
+ 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 < nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset ||
+ (UInt64)pos < k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
+ return SZ_ERROR_INPUT_EOF;
+ }
- RINOK(inStream->Seek(inStream, (CFileSize)(pos + nextHeaderOffset), SZ_SEEK_SET));
+ RINOK(LookInStream_SeekTo(inStream, k7zStartHeaderSize + nextHeaderOffset));
- if (!Buf_Create(&buffer, (size_t)nextHeaderSize, allocTemp))
+ if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp))
return SZ_ERROR_MEM;
- res = SafeReadDirect(inStream, buffer.data, (size_t)nextHeaderSize);
+ res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT);
if (res == SZ_OK)
{
res = SZ_ERROR_ARCHIVE;
- if (CrcCalc(buffer.data, (size_t)nextHeaderSize) == nextHeaderCRC)
+ if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC)
{
- for (;;)
+ CSzData sd;
+ UInt64 type;
+ sd.Data = buffer.data;
+ sd.Size = buffer.size;
+ res = SzReadID(&sd, &type);
+ if (res == SZ_OK)
{
- UInt64 type;
- sd.Data = buffer.data;
- sd.Size = buffer.size;
- res = SzReadID(&sd, &type);
- if (res != SZ_OK)
- break;
- if (type == k7zIdHeader)
- {
- res = SzReadHeader(p, &sd, allocMain, allocTemp);
- break;
- }
- if (type != k7zIdEncodedHeader)
- {
- res = SZ_ERROR_UNSUPPORTED;
- break;
- }
+ if (type == k7zIdEncodedHeader)
{
CBuf outBuffer;
Buf_Init(&outBuffer);
- res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer,
- p->ArchiveInfo.StartPositionAfterHeader,
- allocTemp);
+ res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp);
if (res != SZ_OK)
- {
Buf_Free(&outBuffer, allocTemp);
- break;
+ 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);
}
- Buf_Free(&buffer, allocTemp);
- buffer.data = outBuffer.data;
- buffer.size = outBuffer.size;
}
}
+ if (res == SZ_OK)
+ {
+ if (type == k7zIdHeader)
+ res = SzReadHeader(p, &sd, allocMain, allocTemp);
+ else
+ res = SZ_ERROR_UNSUPPORTED;
+ }
}
}
Buf_Free(&buffer, allocTemp);
return res;
}
-SRes SzArEx_Open(CSzArEx *p, ISzInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
+SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp)
{
SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
if (res != SZ_OK)