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 'CPP/7zip/Archive/Zip/ZipIn.h')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/Archive/Zip/ZipIn.h178
1 files changed, 122 insertions, 56 deletions
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index 0565339a..f6b349b1 100755..100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -3,121 +3,187 @@
#ifndef __ZIP_IN_H
#define __ZIP_IN_H
-#include "Common/MyCom.h"
+#include "../../../Common/MyCom.h"
#include "../../IStream.h"
#include "../../Common/InBuffer.h"
#include "ZipHeader.h"
-#include "ZipItemEx.h"
+#include "ZipItem.h"
+
+API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size);
namespace NArchive {
namespace NZip {
-class CInArchiveException
+class CItemEx: public CItem
{
public:
- enum ECauseType
- {
- kUnexpectedEndOfArchive = 0,
- kArchiceHeaderCRCError,
- kFileHeaderCRCError,
- kIncorrectArchive,
- kDataDescroptorsAreNotSupported,
- kMultiVolumeArchiveAreNotSupported,
- kReadStreamError,
- kSeekStreamError
- }
- Cause;
- CInArchiveException(ECauseType cause): Cause(cause) {}
+ UInt32 LocalFullHeaderSize; // including Name and Extra
+
+ UInt64 GetLocalFullSize() const
+ { return LocalFullHeaderSize + PackSize + (HasDescriptor() ? kDataDescriptorSize : 0); }
+ UInt64 GetDataPosition() const
+ { return LocalHeaderPos + LocalFullHeaderSize; };
};
-class CInArchiveInfo
+struct CInArchiveInfo
{
-public:
- UInt64 Base;
- UInt64 StartPosition;
- UInt64 FinishPosition;
+ Int64 Base; /* Base offset of start of archive in stream.
+ Offsets in headers must be calculated from that Base.
+ Base is equal to MarkerPos for normal ZIPs.
+ Base can point to PE stub for some ZIP SFXs.
+ if CentralDir was read,
+ Base can be negative, if start of data is not available,
+ if CentralDirs was not read,
+ Base = ArcInfo.MarkerPos; */
+
+ /* The following *Pos variables contain absolute offsets in Stream */
+ UInt64 MarkerPos; /* Pos of first signature, it can point to PK00 signature
+ = MarkerPos2 in most archives
+ = MarkerPos2 - 4 if there is PK00 signature */
+ UInt64 MarkerPos2; // Pos of first local item signature in stream
+ UInt64 FinishPos; // Finish pos of archive data
+ UInt64 FileEndPos; // Finish pos of stream
+
+ UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
+ = 0 in most archives
+ = size of stub for some SFXs */
+ bool CdWasRead;
+
CByteBuffer Comment;
- CInArchiveInfo(): Base(0), StartPosition(0) {}
- UInt64 GetPhySize() const { return FinishPosition - StartPosition; }
+ CInArchiveInfo(): Base(0), MarkerPos(0), MarkerPos2(0), FinishPos(0), FileEndPos(0),
+ FirstItemRelatOffset(0), CdWasRead(false) {}
+
+ UInt64 GetPhySize() const { return FinishPos - Base; }
+ UInt64 GetEmbeddedStubSize() const
+ {
+ if (CdWasRead)
+ return FirstItemRelatOffset;
+ return MarkerPos2 - Base;
+ }
+ bool ThereIsTail() const { return FileEndPos > FinishPos; }
+
void Clear()
{
Base = 0;
- StartPosition = 0;
- Comment.SetCapacity(0);
+ MarkerPos = 0;
+ MarkerPos2 = 0;
+ FinishPos = 0;
+ FileEndPos = 0;
+
+ FirstItemRelatOffset = 0;
+ CdWasRead = false;
+
+ Comment.Free();
}
};
-class CProgressVirt
+struct CProgressVirt
{
-public:
- STDMETHOD(SetTotal)(UInt64 numFiles) PURE;
- STDMETHOD(SetCompleted)(UInt64 numFiles) PURE;
+ virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes) = 0;
+ virtual HRESULT SetTotalCD(UInt64 numFiles) = 0;
+ virtual HRESULT SetCompletedCD(UInt64 numFiles) = 0;
};
struct CCdInfo
{
- // UInt64 NumEntries;
+ UInt64 NumEntries;
UInt64 Size;
UInt64 Offset;
+
+ void ParseEcd(const Byte *p);
+ void ParseEcd64(const Byte *p);
};
class CInArchive
{
- CMyComPtr<IInStream> m_Stream;
+ CInBuffer _inBuffer;
+ bool _inBufMode;
UInt32 m_Signature;
- UInt64 m_StreamStartPosition;
UInt64 m_Position;
-
- bool _inBufMode;
- CInBuffer _inBuffer;
HRESULT Seek(UInt64 offset);
-
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
- void ReadFileName(UInt32 nameSize, AString &dest);
-
+ HRESULT IncreaseRealPosition(UInt64 addValue);
+
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
- bool ReadBytesAndTestSize(void *data, UInt32 size);
- void SafeReadBytes(void *data, UInt32 size);
- void ReadBuffer(CByteBuffer &buffer, UInt32 size);
+ void SafeReadBytes(void *data, unsigned size);
+ void ReadBuffer(CByteBuffer &buffer, unsigned size);
Byte ReadByte();
UInt16 ReadUInt16();
UInt32 ReadUInt32();
UInt64 ReadUInt64();
- bool ReadUInt32(UInt32 &signature);
-
- void Skip(UInt64 num);
- void IncreaseRealPosition(UInt64 addValue);
-
- void ReadExtra(UInt32 extraSize, CExtraBlock &extraBlock,
+ void Skip(unsigned num);
+ void Skip64(UInt64 num);
+ void ReadFileName(unsigned nameSize, AString &dest);
+
+ bool ReadExtra(unsigned extraSize, CExtraBlock &extraBlock,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber);
- HRESULT ReadLocalItem(CItemEx &item);
+ bool ReadLocalItem(CItemEx &item);
HRESULT ReadLocalItemDescriptor(CItemEx &item);
HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(CCdInfo &cdInfo);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress);
- HRESULT ReadLocalsAndCd(CObjectVector<CItemEx> &items, CProgressVirt *progress, UInt64 &cdOffset, int &numCdItems);
+ HRESULT ReadLocals(CObjectVector<CItemEx> &localItems, CProgressVirt *progress);
+
+ HRESULT ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress);
public:
CInArchiveInfo ArcInfo;
+
+ bool IsArc;
bool IsZip64;
- bool IsOkHeaders;
-
+ bool HeadersError;
+ bool HeadersWarning;
+ bool ExtraMinorError;
+ bool UnexpectedEnd;
+ bool NoCentralDir;
+
+ CMyComPtr<IInStream> Stream;
+
+ void Close();
+ HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
+
+ bool IsOpen() const { return Stream != NULL; }
+ bool AreThereErrors() const { return HeadersError || UnexpectedEnd; }
+
+ bool IsLocalOffsetOK(const CItemEx &item) const
+ {
+ if (item.FromLocal)
+ return true;
+ return /* ArcInfo.Base >= 0 || */ ArcInfo.Base + (Int64)item.LocalHeaderPos >= 0;
+ }
+
HRESULT ReadLocalItemAfterCdItem(CItemEx &item);
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
- HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
- void Close();
- bool SeekInArchive(UInt64 position);
+
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size);
- IInStream* CreateStream();
- bool IsOpen() const { return m_Stream != NULL; }
+ UInt64 GetOffsetInStream(UInt64 offsetFromArc) const { return ArcInfo.Base + offsetFromArc; }
+
+ bool CanUpdate() const
+ {
+ if (AreThereErrors())
+ return false;
+ if (ArcInfo.Base < 0)
+ return false;
+ if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base)
+ return false;
+
+ // 7-zip probably can update archives with embedded stubs.
+ // we just disable that feature for more safety.
+ if (ArcInfo.GetEmbeddedStubSize() != 0)
+ return false;
+
+ if (ArcInfo.ThereIsTail())
+ return false;
+ return true;
+ }
};
}}