diff options
Diffstat (limited to 'CPP/7zip/Archive/Nsis')
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisDecode.cpp | 49 | ||||
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisDecode.h | 16 | ||||
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisHandler.cpp | 18 | ||||
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisIn.cpp | 51 | ||||
-rw-r--r-- | CPP/7zip/Archive/Nsis/NsisIn.h | 19 |
5 files changed, 97 insertions, 56 deletions
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp index daf3df6e..e2822184 100644 --- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp +++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp @@ -11,13 +11,24 @@ #include "../../Common/MethodId.h" #include "../../Compress/BcjCoder.h" -#include "../../Compress/BZip2Decoder.h" #define Get32(p) GetUi32(p) namespace NArchive { namespace NNsis { +UInt64 CDecoder::GetInputProcessedSize() const +{ + if (_lzmaDecoder) + return _lzmaDecoder->GetInputProcessedSize(); + if (_deflateDecoder) + return _deflateDecoder->GetInputProcessedSize(); + if (_bzDecoder) + return _bzDecoder->GetInputProcessedSize(); + return 0; +} + + HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) { useFilter = false; @@ -36,7 +47,10 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) _deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder(); _codecInStream = _deflateDecoder; break; - case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break; + case NMethodType::kBZip2: + _bzDecoder = new NCompress::NBZip2::CNsisDecoder(); + _codecInStream = _bzDecoder; + break; case NMethodType::kLZMA: _lzmaDecoder = new NCompress::NLzma::CDecoder(); _codecInStream = _lzmaDecoder; @@ -103,15 +117,15 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter) return S_OK; } + static const UInt32 kMask_IsCompressed = (UInt32)1 << 31; + HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress) { if (StreamPos > pos) return E_FAIL; - UInt64 inSizeStart = 0; - if (_lzmaDecoder) - inSizeStart = _lzmaDecoder->GetInputProcessedSize(); + const UInt64 inSizeStart = GetInputProcessedSize(); UInt64 offset = 0; while (StreamPos < pos) { @@ -122,14 +136,13 @@ HRESULT CDecoder::SetToPos(UInt64 pos, ICompressProgressInfo *progress) StreamPos += size; offset += size; - UInt64 inSize = 0; - if (_lzmaDecoder) - inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart; + const UInt64 inSize = GetInputProcessedSize() - inSizeStart; RINOK(progress->SetRatioInfo(&inSize, &offset)); } return S_OK; } + HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unpackSize, ISequentialOutStream *realOutStream, ICompressProgressInfo *progress, UInt32 &packSizeRes, UInt32 &unpackSizeRes) @@ -144,9 +157,9 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp Byte temp[4]; size_t processedSize = 4; RINOK(Read(temp, &processedSize)); + StreamPos += processedSize; if (processedSize != 4) return S_FALSE; - StreamPos += processedSize; UInt32 size = Get32(temp); if (unpackSizeDefined && size != unpackSize) return S_FALSE; @@ -156,8 +169,13 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp else { Byte temp[4]; - RINOK(ReadStream_FALSE(InputStream, temp, 4)); - StreamPos += 4; + { + size_t processedSize = 4; + RINOK(ReadStream(InputStream, temp, &processedSize)); + StreamPos += processedSize; + if (processedSize != 4) + return S_FALSE; + } UInt32 size = Get32(temp); if ((size & kMask_IsCompressed) == 0) @@ -209,9 +227,7 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp outBuf->Alloc(unpackSize); } - UInt64 inSizeStart = 0; - if (_lzmaDecoder) - inSizeStart = _lzmaDecoder->GetInputProcessedSize(); + const UInt64 inSizeStart = GetInputProcessedSize(); // we don't allow files larger than 4 GB; if (!unpackSizeDefined) @@ -254,9 +270,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp StreamPos += size; offset += (UInt32)size; - UInt64 inSize = 0; // it can be improved: we need inSize for Deflate and BZip2 too. - if (_lzmaDecoder) - inSize = _lzmaDecoder->GetInputProcessedSize() - inSizeStart; + const UInt64 inSize = GetInputProcessedSize() - inSizeStart; + if (Solid) packSizeRes = (UInt32)inSize; unpackSizeRes += (UInt32)size; diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h index ec713d05..2153d785 100644 --- a/CPP/7zip/Archive/Nsis/NsisDecode.h +++ b/CPP/7zip/Archive/Nsis/NsisDecode.h @@ -8,6 +8,7 @@ #include "../../Common/FilterCoder.h" #include "../../Common/StreamUtils.h" +#include "../../Compress/BZip2Decoder.h" #include "../../Compress/DeflateDecoder.h" #include "../../Compress/LzmaDecoder.h" @@ -38,6 +39,7 @@ class CDecoder CMyComPtr<ISequentialInStream> _codecInStream; CMyComPtr<ISequentialInStream> _decoderInStream; + NCompress::NBZip2::CNsisDecoder *_bzDecoder; NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoder; NCompress::NLzma::CDecoder *_lzmaDecoder; @@ -50,13 +52,17 @@ public: bool Solid; bool IsNsisDeflate; - CByteBuffer Buffer; // temp buf. + CByteBuffer Buffer; // temp buf CDecoder(): FilterFlag(false), Solid(true), IsNsisDeflate(true) - {} + { + _bzDecoder = NULL; + _deflateDecoder = NULL; + _lzmaDecoder = NULL; + } void Release() { @@ -64,10 +70,16 @@ public: _codecInStream.Release(); _decoderInStream.Release(); InputStream.Release(); + + _bzDecoder = NULL; + _deflateDecoder = NULL; _lzmaDecoder = NULL; } + + UInt64 GetInputProcessedSize() const; HRESULT Init(ISequentialInStream *inStream, bool &useFilter); + HRESULT Read(void *data, size_t *processedSize) { return ReadStream(_decoderInStream, data, processedSize);; diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp index 971c8464..095105fe 100644 --- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp +++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp @@ -23,8 +23,8 @@ using namespace NWindows; namespace NArchive { namespace NNsis { -static const char *kBcjMethod = "BCJ"; -static const char *kUnknownMethod = "Unknown"; +#define kBcjMethod "BCJ" +#define kUnknownMethod "Unknown" static const char * const kMethods[] = { @@ -64,7 +64,7 @@ static AString UInt32ToString(UInt32 val) { char s[16]; ConvertUInt32ToString(val, s); - return s; + return (AString)s; } static AString GetStringForSizeValue(UInt32 val) @@ -123,7 +123,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) // case kpidCodePage: if (_archive.IsUnicode) prop = "UTF-16"; break; case kpidSubType: { - AString s = _archive.GetFormatDescription(); + AString s (_archive.GetFormatDescription()); if (!_archive.IsInstaller) { s.Add_Space_if_NotEmpty(); @@ -308,7 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidOffset: prop = item.Pos; break; case kpidPath: { - UString s = NItemName::WinNameToOSName(_archive.GetReducedName(index)); + UString s = NItemName::WinPathToOsPath(_archive.GetReducedName(index)); if (!s.IsEmpty()) prop = (const wchar_t *)s; break; @@ -481,7 +481,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, Int32 askMode = testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; + const UInt32 index = allFilesMode ? i : indices[i]; RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -647,6 +647,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { UInt32 curPacked2 = 0; UInt32 curUnpacked2 = 0; + + if (!_archive.IsSolid) + { + RINOK(_archive.SeekTo(_archive.GetPosOfNonSolidItem(index) + 4 + curPacked )); + } + HRESULT res = _archive.Decoder.Decode( writeToTemp ? &tempBuf2 : NULL, false, 0, diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index a3bfcaec..f739b0ff 100644 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -398,11 +398,9 @@ static const char * const kShellStrings[] = }; -static void UIntToString(AString &s, UInt32 v) +static inline void UIntToString(AString &s, UInt32 v) { - char sz[16]; - ConvertUInt32ToString(v, sz); - s += sz; + s.Add_UInt32(v); } #ifdef NSIS_SCRIPT @@ -461,7 +459,7 @@ void CInArchive::AddLicense(UInt32 param, Int32 langID) } } } - AString fileName = "[LICENSE]"; + AString fileName ("[LICENSE]"); if (langID >= 0) { fileName += "\\license-"; @@ -940,7 +938,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p) break; if (c < 0x80) { - Raw_UString += (wchar_t)c; + Raw_UString += (char)c; continue; } @@ -963,7 +961,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p) else // if (c == PARK_CODE_LANG) Add_LangStr(Raw_AString, n); } - Raw_UString.AddAscii(Raw_AString); + Raw_UString += Raw_AString.Ptr(); // check it ! continue; } c = n; @@ -1009,7 +1007,7 @@ void CInArchive::GetNsisString_Unicode_Raw(const Byte *p) else // if (c == NS_3_CODE_LANG) Add_LangStr(Raw_AString, n); } - Raw_UString.AddAscii(Raw_AString); + Raw_UString += Raw_AString.Ptr(); } } @@ -1145,7 +1143,7 @@ void CInArchive::ReadString2_Raw(UInt32 pos) GetNsisString_Raw(_data + _stringsPos + pos); return; } - Raw_UString.SetFromAscii(Raw_AString); + Raw_UString = Raw_AString.Ptr(); } bool CInArchive::IsGoodString(UInt32 param) const @@ -2309,7 +2307,7 @@ static void AddString(AString &dest, const char *src) AString CInArchive::GetFormatDescription() const { - AString s = "NSIS-"; + AString s ("NSIS-"); char c; if (IsPark()) { @@ -3185,8 +3183,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) UString spec_outdir_U; AString spec_outdir_A; - UPrefixes.Add(L"$INSTDIR"); - APrefixes.Add("$INSTDIR"); + UPrefixes.Add(UString("$INSTDIR")); + APrefixes.Add(AString("$INSTDIR")); p = _data + bh.Offset; @@ -4021,7 +4019,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh) case EW_INTOP: { AddParam_Var(params[0]); - const char *kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+ + const char * const kOps = "+-*/|&^!|&%<>"; // NSIS 2.01+ // "+-*/|&^!|&%"; // NSIS 2.0b4+ // "+-*/|&^~!|&%"; // NSIS old UInt32 opIndex = params[3]; @@ -4857,11 +4855,11 @@ static int CompareItems(void *const *p1, void *const *p2, void *param) { if (i1.Prefix < 0) return -1; if (i2.Prefix < 0) return 1; - RINOZ(wcscmp( - inArchive->UPrefixes[i1.Prefix], + RINOZ( + inArchive->UPrefixes[i1.Prefix].Compare( inArchive->UPrefixes[i2.Prefix])); } - RINOZ(wcscmp(i1.NameU, i2.NameU)); + RINOZ(i1.NameU.Compare(i2.NameU)); } else { @@ -4934,7 +4932,7 @@ HRESULT CInArchive::SortItems() for (i = 0; i < Items.Size(); i++) { CItem &item = Items[i]; - RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL)); + RINOK(SeekToNonSolidItem(i)); const UInt32 kSigSize = 4 + 1 + 1 + 4; // size,[flag],prop,dict BYTE sig[kSigSize]; size_t processedSize = kSigSize; @@ -4997,6 +4995,9 @@ HRESULT CInArchive::Parse() // ???? offset == FirstHeader.HeaderSize const Byte *p = _data; + if (_size < 4 + 8 * 8) + return S_FALSE; + CBlockHeader bhEntries, bhStrings, bhLangTables; bhEntries.Parse(p + 4 + 8 * 2); bhStrings.Parse(p + 4 + 8 * 3); @@ -5014,12 +5015,14 @@ HRESULT CInArchive::Parse() #endif _stringsPos = bhStrings.Offset; - if (_stringsPos > _size) + if (_stringsPos > _size + || bhLangTables.Offset > _size + || bhEntries.Offset > _size) return S_FALSE; { if (bhLangTables.Offset < bhStrings.Offset) return S_FALSE; - UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset; + const UInt32 stringTableSize = bhLangTables.Offset - bhStrings.Offset; if (stringTableSize < 2) return S_FALSE; const Byte *strData = _data + _stringsPos; @@ -5035,13 +5038,10 @@ HRESULT CInArchive::Parse() if (strData[stringTableSize - 2] != 0) return S_FALSE; } - } if (bhEntries.Num > (1 << 25)) return S_FALSE; - if (bhEntries.Offset > _size) - return S_FALSE; if (bhEntries.Num * kCmdSize > _size - bhEntries.Offset) return S_FALSE; @@ -5595,16 +5595,19 @@ HRESULT CInArchive::Open2(const Byte *sig, size_t size) if (IsSolid) { - RINOK(_stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL)); + RINOK(SeekTo_DataStreamOffset()); } else { _headerIsCompressed = ((compressedHeaderSize & kMask_IsCompressed) != 0); compressedHeaderSize &= ~kMask_IsCompressed; _nonSolidStartOffset = compressedHeaderSize; - RINOK(_stream->Seek(DataStreamOffset + 4, STREAM_SEEK_SET, NULL)); + RINOK(SeekTo(DataStreamOffset + 4)); } + if (FirstHeader.HeaderSize == 0) + return S_FALSE; + _data.Alloc(FirstHeader.HeaderSize); _size = (size_t)FirstHeader.HeaderSize; diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h index d8e6808b..028e4a5d 100644 --- a/CPP/7zip/Archive/Nsis/NsisIn.h +++ b/CPP/7zip/Archive/Nsis/NsisIn.h @@ -350,14 +350,19 @@ public: return Decoder.Init(_stream, useFilter); } + HRESULT SeekTo(UInt64 pos) + { + return _stream->Seek(pos, STREAM_SEEK_SET, NULL); + } + HRESULT SeekTo_DataStreamOffset() { - return _stream->Seek(DataStreamOffset, STREAM_SEEK_SET, NULL); + return SeekTo(DataStreamOffset); } HRESULT SeekToNonSolidItem(unsigned index) { - return _stream->Seek(GetPosOfNonSolidItem(index), STREAM_SEEK_SET, NULL); + return SeekTo(GetPosOfNonSolidItem(index)); } void Clear(); @@ -403,23 +408,23 @@ public: s = MultiByteToUnicodeString(APrefixes[item.Prefix]); if (s.Len() > 0) if (s.Back() != L'\\') - s += L'\\'; + s += '\\'; } if (IsUnicode) { s += item.NameU; if (item.NameU.IsEmpty()) - s += L"file"; + s += "file"; } else { s += MultiByteToUnicodeString(item.NameA); if (item.NameA.IsEmpty()) - s += L"file"; + s += "file"; } - const char *kRemoveStr = "$INSTDIR\\"; + const char * const kRemoveStr = "$INSTDIR\\"; if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr)) { s.Delete(0, MyStringLen(kRemoveStr)); @@ -427,7 +432,7 @@ public: s.DeleteFrontal(1); } if (item.IsUninstaller && ExeStub.Size() == 0) - s += L".nsis"; + s += ".nsis"; return s; } |