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:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2008-05-05 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:55 +0300
commit3901bf0ab88106a5b031cba7bc18d60cdebf7eef (patch)
tree808a2489abed822223b118b64e0553db80af6087 /CPP/7zip/Archive/Nsis
parentbd1fa36322ac27f5715433b388742893d6524516 (diff)
4.58 beta
Diffstat (limited to 'CPP/7zip/Archive/Nsis')
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisDecode.cpp4
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisDecode.h2
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisHandler.cpp32
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisIn.cpp232
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisIn.h53
5 files changed, 236 insertions, 87 deletions
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
index b50ec5e0..7e126bd4 100755
--- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
@@ -133,9 +133,9 @@ HRESULT CDecoder::Init(
return S_OK;
}
-HRESULT CDecoder::Read(void *data, UInt32 size, UInt32 *processedSize)
+HRESULT CDecoder::Read(void *data, size_t *processedSize)
{
- return ReadStream(_decoderInStream, data, size, processedSize);;
+ return ReadStream(_decoderInStream, data, processedSize);;
}
}}
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h
index 1a2fa41f..36aeb2b1 100755
--- a/CPP/7zip/Archive/Nsis/NsisDecode.h
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.h
@@ -39,7 +39,7 @@ public:
HRESULT Init(
DECL_EXTERNAL_CODECS_LOC_VARS
IInStream *inStream, NMethodType::EEnum method, bool thereIsFilterFlag, bool &useFilter);
- HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
+ HRESULT Read(void *data, size_t *processedSize);
};
}}
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
index 62c7ab38..b24d966d 100755
--- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
@@ -12,6 +12,7 @@
#include "Windows/PropVariant.h"
#include "../Common/ItemNameUtils.h"
+#include "../../Common/StreamUtils.h"
using namespace NWindows;
@@ -233,8 +234,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- const UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetReducedName(), CP_ACP));
- prop = (const wchar_t *)s;
+ UString s;
+ if (_archive.IsUnicode)
+ s = item.GetReducedNameU();
+ else
+ s = MultiByteToUnicodeString(item.GetReducedNameA(), CP_ACP);
+ s = NItemName::WinNameToOSName(s);
+ if (!s.IsEmpty())
+ prop = (const wchar_t *)s;
break;
}
case kpidIsFolder:
@@ -348,7 +355,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
continue;
RINOK(extractCallback->PrepareOperation(askMode));
if (!testMode)
- RINOK(realOutStream->Write((const char *)_archive.Script, (UInt32)_archive.Script.Length(), NULL));
+ RINOK(WriteStream(realOutStream, (const char *)_archive.Script, (UInt32)_archive.Script.Length()));
}
else
#endif
@@ -379,9 +386,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt64 pos = _archive.GetPosOfSolidItem(index);
while(streamPos < pos)
{
- UInt32 curSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength);
- UInt32 processedSize;
- HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
+ size_t processedSize = (UInt32)MyMin(pos - streamPos, (UInt64)kBufferLength);
+ HRESULT res = _archive.Decoder.Read(buffer, &processedSize);
if (res != S_OK)
{
if (res != S_FALSE)
@@ -398,8 +404,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
}
if (streamPos == pos)
{
- UInt32 processedSize;
- RINOK(_archive.Decoder.Read(buffer, 4, &processedSize));
+ size_t processedSize = 4;
+ RINOK(_archive.Decoder.Read(buffer, &processedSize));
if (processedSize != 4)
return E_FAIL;
streamPos += processedSize;
@@ -433,8 +439,8 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
UInt32 curSize = kBufferLength;
if (sizeIsKnown && curSize > fullSize)
curSize = fullSize;
- UInt32 processedSize;
- HRESULT res = _archive.Decoder.Read(buffer, curSize, &processedSize);
+ size_t processedSize = curSize;
+ HRESULT res = _archive.Decoder.Read(buffer, &processedSize);
if (res != S_OK)
{
if (res != S_FALSE)
@@ -449,7 +455,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
break;
}
- fullSize -= processedSize;
+ fullSize -= (UInt32)processedSize;
streamPos += processedSize;
offset += processedSize;
@@ -460,7 +466,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
completed = currentTotalSize + offset;
RINOK(extractCallback->SetCompleted(&completed));
if (!testMode)
- RINOK(realOutStream->Write(buffer, processedSize, NULL));
+ RINOK(WriteStream(realOutStream, buffer, processedSize));
}
}
else
@@ -478,7 +484,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
fullSize -= processedSize;
streamPos += processedSize;
if (!testMode)
- RINOK(realOutStream->Write(buffer, processedSize, 0));
+ RINOK(WriteStream(realOutStream, buffer, processedSize));
}
}
}
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
index 83080448..5c5c872f 100755
--- a/CPP/7zip/Archive/Nsis/NsisIn.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+// #include <stdio.h>
+
#include "NsisIn.h"
#include "NsisDecode.h"
@@ -9,6 +11,7 @@
#include "../../Common/StreamUtils.h"
+#include "Common/StringConvert.h"
#include "Common/IntToString.h"
namespace NArchive {
@@ -27,6 +30,14 @@ public:
static const char *kCrLf = "\x0D\x0A";
#endif
+#define NS_UN_SKIP_CODE 0xE000
+#define NS_UN_VAR_CODE 0xE001
+#define NS_UN_SHELL_CODE 0xE002
+#define NS_UN_LANG_CODE 0xE003
+#define NS_UN_CODES_START NS_UN_SKIP_CODE
+#define NS_UN_CODES_END NS_UN_LANG_CODE
+
+
UInt32 GetUInt32FromMemLE(const Byte *p)
{
return p[0] | (((UInt32)p[1]) << 8) | (((UInt32)p[2]) << 16) | (((UInt32)p[3]) << 24);
@@ -60,12 +71,20 @@ static int CompareItems(void *const *p1, void *const *p2, void * /* param */)
const CItem &i1 = **(CItem **)p1;
const CItem &i2 = **(CItem **)p2;
RINOZ(MyCompare(i1.Pos, i2.Pos));
- RINOZ(i1.Prefix.Compare(i2.Prefix));
- RINOZ(i1.Name.Compare(i2.Name));
+ if (i1.IsUnicode)
+ {
+ RINOZ(i1.PrefixU.Compare(i2.PrefixU));
+ RINOZ(i1.NameU.Compare(i2.NameU));
+ }
+ else
+ {
+ RINOZ(i1.PrefixA.Compare(i2.PrefixA));
+ RINOZ(i1.NameA.Compare(i2.NameA));
+ }
return 0;
}
-AString CInArchive::ReadString(UInt32 pos)
+AString CInArchive::ReadStringA(UInt32 pos)
{
AString s;
UInt32 offset = GetOffset() + _stringsPos + pos;
@@ -81,6 +100,24 @@ AString CInArchive::ReadString(UInt32 pos)
return s;
}
+UString CInArchive::ReadStringU(UInt32 pos)
+{
+ UString s;
+ UInt32 offset = GetOffset() + _stringsPos + (pos * 2);
+ for (;;)
+ {
+ if (offset >= _size || offset + 1 >= _size)
+ throw 1;
+ char c0 = _data[offset++];
+ char c1 = _data[offset++];
+ wchar_t c = (c0 | ((wchar_t)c1 << 8));
+ if (c == 0)
+ break;
+ s += c;
+ }
+ return s;
+}
+
/*
static AString ParsePrefix(const AString &prefix)
{
@@ -466,13 +503,27 @@ static AString GetVar(UInt32 index)
return res;
}
-// $0..$9, $INSTDIR, etc are encoded as ASCII bytes starting from this value.
#define NS_SKIP_CODE 252
#define NS_VAR_CODE 253
#define NS_SHELL_CODE 254
#define NS_LANG_CODE 255
#define NS_CODES_START NS_SKIP_CODE
+static AString GetShellString(int index)
+{
+ AString res = "$";
+ if (index < kNumShellStrings)
+ {
+ const char *sz = kShellStrings[index];
+ if (sz[0] != 0)
+ return res + sz;
+ }
+ res += "SHELL[";
+ res += UIntToString(index);
+ res += "]";
+ return res;
+}
+
// Based on Dave Laundon's simplified process_string
AString GetNsisString(const AString &s)
{
@@ -487,26 +538,7 @@ AString GetNsisString(const AString &s)
nData |= (((int)(c1 & 0x7F)) << 7);
if (nVarIdx == NS_SHELL_CODE)
- {
- UInt32 index = c1;
- bool needPrint = true;
- res += "$";
- if (index < kNumShellStrings)
- {
- const char *sz = kShellStrings[index];
- if (sz[0] != 0)
- {
- res += sz;
- needPrint = false;
- }
- }
- if (needPrint)
- {
- res += "SHELL[";
- res += UIntToString(index);
- res += "]";
- }
- }
+ res += GetShellString(c1);
else if (nVarIdx == NS_VAR_CODE)
res += GetVar(nData);
else if (nVarIdx == NS_LANG_CODE)
@@ -523,9 +555,53 @@ AString GetNsisString(const AString &s)
return res;
}
+UString GetNsisString(const UString &s)
+{
+ UString res;
+ for (int i = 0; i < s.Length();)
+ {
+ wchar_t nVarIdx = s[i++];
+ if (nVarIdx > NS_UN_CODES_START && nVarIdx <= NS_UN_CODES_END)
+ {
+ if (i == s.Length())
+ break;
+ int nData = s[i++] & 0x7FFF;
+
+ if (nVarIdx == NS_UN_SHELL_CODE)
+ res += GetUnicodeString(GetShellString(nData >> 8));
+ else if (nVarIdx == NS_UN_VAR_CODE)
+ res += GetUnicodeString(GetVar(nData));
+ else if (nVarIdx == NS_UN_LANG_CODE)
+ res += L"NS_LANG_CODE";
+ }
+ else if (nVarIdx == NS_UN_SKIP_CODE)
+ {
+ if (i == s.Length())
+ break;
+ res += s[i++];
+ }
+ else // Normal char
+ res += (char)nVarIdx;
+ }
+ return res;
+}
+
+AString CInArchive::ReadString2A(UInt32 pos)
+{
+ return GetNsisString(ReadStringA(pos));
+}
+
+UString CInArchive::ReadString2U(UInt32 pos)
+{
+ return GetNsisString(ReadStringU(pos));
+}
+
AString CInArchive::ReadString2(UInt32 pos)
{
- return GetNsisString(ReadString(pos));
+ if (IsUnicode)
+ return UnicodeStringToMultiByte(ReadString2U(pos));
+ else
+ return ReadString2A(pos);
}
#define DEL_DIR 1
@@ -566,7 +642,8 @@ AString CEntry::GetParamsString(int numParams)
HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
_posInData = bh.Offset + GetOffset();
- AString prefix;
+ AString prefixA;
+ UString prefixU;
for (UInt32 i = 0; i < bh.Num; i++)
{
CEntry e;
@@ -585,11 +662,22 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
case EW_CREATEDIR:
{
- prefix.Empty();
- prefix = ReadString2(e.Params[0]);
+ if (IsUnicode)
+ {
+ prefixU.Empty();
+ prefixU = ReadString2U(e.Params[0]);
+ }
+ else
+ {
+ prefixA.Empty();
+ prefixA = ReadString2A(e.Params[0]);
+ }
#ifdef NSIS_SCRIPT
Script += " ";
- Script += prefix;
+ if (IsUnicode)
+ Script += UnicodeStringToMultiByte(prefixU);
+ else
+ Script += prefixA;
#endif
break;
}
@@ -597,9 +685,18 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
case EW_EXTRACTFILE:
{
CItem item;
- item.Prefix = prefix;
+ item.IsUnicode = IsUnicode;
+ if (IsUnicode)
+ {
+ item.PrefixU = prefixU;
+ item.NameU = ReadString2U(e.Params[1]);
+ }
+ else
+ {
+ item.PrefixA = prefixA;
+ item.NameA = ReadString2A(e.Params[1]);
+ }
/* UInt32 overwriteFlag = e.Params[0]; */
- item.Name = ReadString2(e.Params[1]);
item.Pos = e.Params[2];
item.DateTime.dwLowDateTime = e.Params[3];
item.DateTime.dwHighDateTime = e.Params[4];
@@ -614,7 +711,11 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
Items.Add(item);
#ifdef NSIS_SCRIPT
Script += " ";
- Script += item.Name;
+
+ if (IsUnicode)
+ Script += UnicodeStringToMultiByte(item.NameU);
+ else
+ Script += item.NameA;
#endif
break;
}
@@ -908,7 +1009,10 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
// if (IsSolid)
for (i = 0; i + 1 < Items.Size();)
{
- if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || Items[i].Name == Items[i + 1].Name))
+ bool sameName = IsUnicode ?
+ (Items[i].NameU == Items[i + 1].NameU) :
+ (Items[i].NameA == Items[i + 1].NameA);
+ if (Items[i].Pos == Items[i + 1].Pos && (IsSolid || sameName))
Items.Delete(i + 1);
else
i++;
@@ -927,8 +1031,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
RINOK(_stream->Seek(GetPosOfNonSolidItem(i), STREAM_SEEK_SET, NULL));
const UInt32 kSigSize = 4 + 1 + 5;
BYTE sig[kSigSize];
- UInt32 processedSize;
- RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
+ size_t processedSize = kSigSize;
+ RINOK(ReadStream(_stream, sig, &processedSize));
if (processedSize < 4)
return S_FALSE;
UInt32 size = GetUInt32FromMemLE(sig);
@@ -977,7 +1081,37 @@ HRESULT CInArchive::Parse()
ReadBlockHeader(bhData);
_stringsPos = bhStrings.Offset;
+ UInt32 pos = GetOffset() + _stringsPos;
+ int numZeros0 = 0;
+ int numZeros1 = 0;
+ int i;
+ const kBlockSize = 256;
+ for (i = 0; i < kBlockSize; i++)
+ {
+ if (pos >= _size || pos + 1 >= _size)
+ break;
+ char c0 = _data[pos++];
+ char c1 = _data[pos++];
+ wchar_t c = (c0 | ((wchar_t)c1 << 8));
+ if (c >= NS_UN_CODES_START && c < NS_UN_CODES_END)
+ {
+ if (pos >= _size || pos + 1 >= _size)
+ break;
+ pos += 2;
+ numZeros1++;
+ }
+ else
+ {
+ if (c0 == 0 && c1 != 0)
+ numZeros0++;
+ if (c1 == 0)
+ numZeros1++;
+ }
+ // printf("\nnumZeros0 = %2x %2x", _data[pos + 0], _data[pos + 1]);
+ }
+ IsUnicode = (numZeros1 > numZeros0 * 3 + kBlockSize / 16);
+ // printf("\nnumZeros0 = %3d numZeros1 = %3d", numZeros0, numZeros1);
return ReadEntries(bhEntries);
}
@@ -1010,10 +1144,7 @@ HRESULT CInArchive::Open2(
const UInt32 kSigSize = 4 + 1 + 5 + 1; // size, flag, lzma props, lzma first byte
BYTE sig[kSigSize];
- UInt32 processedSize;
- RINOK(ReadStream(_stream, sig, kSigSize, &processedSize));
- if (processedSize != kSigSize)
- return S_FALSE;
+ RINOK(ReadStream_FALSE(_stream, sig, kSigSize));
UInt64 position;
RINOK(_stream->Seek(StreamOffset, STREAM_SEEK_SET, &position));
@@ -1065,11 +1196,11 @@ HRESULT CInArchive::Open2(
RINOK(Decoder.Init(
EXTERNAL_CODECS_LOC_VARS
_stream, Method, FilterFlag, UseFilter));
- UInt32 processedSize;
- RINOK(Decoder.Read(_data, unpackSize, &processedSize));
+ size_t processedSize = unpackSize;
+ RINOK(Decoder.Read(_data, &processedSize));
if (processedSize != unpackSize)
return S_FALSE;
- _size = (size_t)processedSize;
+ _size = processedSize;
if (IsSolid)
{
UInt32 size2 = ReadUInt32();
@@ -1081,9 +1212,7 @@ HRESULT CInArchive::Open2(
{
_data.SetCapacity(unpackSize);
_size = (size_t)unpackSize;
- RINOK(ReadStream(_stream, (Byte *)_data, unpackSize, &processedSize));
- if (processedSize != unpackSize)
- return S_FALSE;
+ RINOK(ReadStream_FALSE(_stream, (Byte *)_data, unpackSize));
}
return Parse();
}
@@ -1138,22 +1267,17 @@ HRESULT CInArchive::Open(
UInt64 headerPosition = 0;
while (position <= maxSize)
{
- UInt32 processedSize;
- RINOK(ReadStream(inStream, buffer, kStartHeaderSize, &processedSize));
- if (processedSize != kStartHeaderSize)
- return S_FALSE;
+ RINOK(ReadStream_FALSE(inStream, buffer, kStartHeaderSize));
headerPosition = position;
- position += processedSize;
+ position += kStartHeaderSize;
if(memcmp(buffer + 4, kSignature, kSignatureSize) == 0)
{
found = true;
break;
}
const UInt32 kRem = kStep - kStartHeaderSize;
- RINOK(ReadStream(inStream, buffer + kStartHeaderSize, kRem, &processedSize));
- if (processedSize != kRem)
- return S_FALSE;
- position += processedSize;
+ RINOK(ReadStream_FALSE(inStream, buffer + kStartHeaderSize, kRem));
+ position += kRem;
}
if (!found)
return S_FALSE;
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
index 22c050f1..e7908862 100755
--- a/CPP/7zip/Archive/Nsis/NsisIn.h
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
@@ -56,41 +56,56 @@ struct CBlockHeader
struct CItem
{
- AString Prefix;
- AString Name;
- UInt32 Pos;
+ AString PrefixA;
+ UString PrefixU;
+ AString NameA;
+ UString NameU;
+ FILETIME DateTime;
+ bool IsUnicode;
+ bool UseFilter;
+ bool IsCompressed;
bool SizeIsDefined;
bool CompressedSizeIsDefined;
bool EstimatedSizeIsDefined;
+ UInt32 Pos;
UInt32 Size;
UInt32 CompressedSize;
UInt32 EstimatedSize;
- FILETIME DateTime;
UInt32 DictionarySize;
- bool IsCompressed;
- bool UseFilter;
- CItem(): UseFilter(false), SizeIsDefined(false), EstimatedSizeIsDefined(false),
- IsCompressed(true), CompressedSizeIsDefined(false), Size(0) {}
+
+ CItem(): IsUnicode(false), UseFilter(false), IsCompressed(true), SizeIsDefined(false),
+ CompressedSizeIsDefined(false), EstimatedSizeIsDefined(false), Size(0) {}
bool IsINSTDIR() const
{
- if (Prefix.Length() < 3)
- return false;
- return true;
+ return (PrefixA.Length() >= 3 || PrefixU.Length() >= 3);
}
- AString GetReducedName() const
+ AString GetReducedNameA() const
{
- AString prefix = Prefix;
+ AString prefix = PrefixA;
if (prefix.Length() > 0)
if (prefix[prefix.Length() - 1] != '\\')
prefix += '\\';
- AString s2 = prefix + Name;
+ AString s2 = prefix + NameA;
const int len = 9;
if (s2.Left(len).CompareNoCase("$INSTDIR\\") == 0)
s2 = s2.Mid(len);
return s2;
}
+
+ UString GetReducedNameU() const
+ {
+ UString prefix = PrefixU;
+ if (prefix.Length() > 0)
+ if (prefix[prefix.Length() - 1] != L'\\')
+ prefix += L'\\';
+ UString s2 = prefix + NameU;
+ const int len = 9;
+ if (s2.Left(len).CompareNoCase(L"$INSTDIR\\") == 0)
+ s2 = s2.Mid(len);
+ return s2;
+ }
};
@@ -105,7 +120,10 @@ class CInArchive
DECL_EXTERNAL_CODECS_LOC_VARS2
);
void ReadBlockHeader(CBlockHeader &bh);
- AString ReadString(UInt32 pos);
+ AString ReadStringA(UInt32 pos);
+ UString ReadStringU(UInt32 pos);
+ AString ReadString2A(UInt32 pos);
+ UString ReadString2U(UInt32 pos);
AString ReadString2(UInt32 pos);
HRESULT ReadEntries(const CBlockHeader &bh);
HRESULT Parse();
@@ -129,12 +147,13 @@ public:
UInt64 StreamOffset;
CDecoder Decoder;
CObjectVector<CItem> Items;
- bool IsSolid;
CFirstHeader FirstHeader;
NMethodType::EEnum Method;
- bool UseFilter;
UInt32 DictionarySize;
+ bool IsSolid;
+ bool UseFilter;
bool FilterFlag;
+ bool IsUnicode;
#ifdef NSIS_SCRIPT
AString Script;