diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2018-12-30 17:01:47 +0300 |
---|---|---|
committer | Kornel <kornel@geekhood.net> | 2018-12-30 17:01:47 +0300 |
commit | 5b2a99c548a6c9c90d4cc63cddca29af009c2479 (patch) | |
tree | fb4af843548b762bdb6cc8dc2ec65457a9fdf7da /CPP | |
parent | 18dc2b41613055f0daf7f6a1d4311368798ea12a (diff) |
18.0618.06
Diffstat (limited to 'CPP')
70 files changed, 870 insertions, 314 deletions
diff --git a/CPP/7zip/Aes.mak b/CPP/7zip/Aes.mak index fbd70aae..20f1a72f 100644 --- a/CPP/7zip/Aes.mak +++ b/CPP/7zip/Aes.mak @@ -1,7 +1,7 @@ C_OBJS = $(C_OBJS) \ $O\Aes.obj -!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64" +!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" ASM_OBJS = $(ASM_OBJS) \ $O\AesOpt.obj !ENDIF diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index 988b35f7..bbb892e7 100644 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -236,6 +236,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) prop = v; break; } + + case kpidReadOnly: + { + if (!_db.CanUpdate()) + prop = true; + break; + } } prop.Detach(value); return S_OK; diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp index 79f83bac..b6be06a8 100644 --- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp +++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp @@ -267,6 +267,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt db = &_db; #endif + if (db && !db->CanUpdate()) + return E_NOTIMPL; + /* CMyComPtr<IArchiveGetRawProps> getRawProps; updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps); diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp index b7b71d13..ab5b5de4 100644 --- a/CPP/7zip/Archive/7z/7zIn.cpp +++ b/CPP/7zip/Archive/7z/7zIn.cpp @@ -1465,21 +1465,24 @@ void CDbEx::FillLinks() } if (indexInFolder != 0) + { folderIndex++; - /* - if (indexInFolder != 0) - ThrowIncorrect(); - */ + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } for (;;) { if (folderIndex >= NumFolders) return; FolderStartFileIndex[folderIndex] = i; - /* if (NumUnpackStreamsVector[folderIndex] != 0) - ThrowIncorrect();; - */ + { + // 18.06 + ThereIsHeaderError = true; + // ThrowIncorrect(); + } folderIndex++; } } diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h index 2d5fbb79..6a61d314 100644 --- a/CPP/7zip/Archive/7z/7zIn.h +++ b/CPP/7zip/Archive/7z/7zIn.h @@ -257,6 +257,16 @@ struct CDbEx: public CDatabase PhySize = 0; } + bool CanUpdate() const + { + if (ThereIsHeaderError + || UnexpectedEnd + || StartHeaderWasRecovered + || UnsupportedFeatureError) + return false; + return true; + } + void FillLinks(); UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 5450c8ba..6705fc00 100644 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -124,13 +124,13 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode) #define ELF_DATA_2LSB 1 #define ELF_DATA_2MSB 2 -static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } -static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); } -// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); } +static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); } +static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); } +// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); } static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode) { - Bool /* is32, */ be; + BoolInt /* is32, */ be; UInt32 filterId; if (size < 512 || buf[6] != 1) /* ver */ @@ -200,7 +200,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode if (size < 512) return 0; - Bool /* mode64, */ be; + BoolInt /* mode64, */ be; switch (GetUi32(buf)) { case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break; @@ -239,7 +239,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode #define RIFF_SIG 0x46464952 -static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) +static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) { UInt32 subChunkSize, pos; if (size < 0x2C) @@ -285,7 +285,7 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode) return False; } -static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) +static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode) { filterMode->Id = 0; filterMode->Delta = 0; @@ -894,7 +894,7 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo // RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK)); if (result == S_OK) { - Bool parseRes = ParseFile(Buffer, size, &filterModeTemp); + BoolInt parseRes = ParseFile(Buffer, size, &filterModeTemp); if (parseRes && filterModeTemp.Delta == 0) { filterModeTemp.SetDelta(); @@ -1648,6 +1648,9 @@ HRESULT Update( for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++) { + if (fi >= db->Files.Size()) + return E_FAIL; + const CFileItem &file = db->Files[fi]; if (file.HasStream) { diff --git a/CPP/7zip/Archive/ArHandler.cpp b/CPP/7zip/Archive/ArHandler.cpp index 816a84e4..09a62201 100644 --- a/CPP/7zip/Archive/ArHandler.cpp +++ b/CPP/7zip/Archive/ArHandler.cpp @@ -170,8 +170,8 @@ static bool OctalToNumber32(const char *s, unsigned size, UInt32 &res) res = 0; char sz[32]; size = RemoveTailSpaces(sz, s, size); - if (size == 0) - return true; // some items doesn't contaion any numbers + if (size == 0 || strcmp(sz, "-1") == 0) + return true; // some items don't contain any numbers const char *end; UInt64 res64 = ConvertOctStringToUInt64(sz, &end); if ((unsigned)(end - sz) != size) @@ -185,8 +185,8 @@ static bool DecimalToNumber(const char *s, unsigned size, UInt64 &res) res = 0; char sz[32]; size = RemoveTailSpaces(sz, s, size); - if (size == 0) - return true; // some items doesn't contaion any numbers + if (size == 0 || strcmp(sz, "-1") == 0) + return true; // some items don't contain any numbers const char *end; res = ConvertStringToUInt64(sz, &end); return ((unsigned)(end - sz) == size); diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp index 98428430..b0c2f750 100644 --- a/CPP/7zip/Archive/Bz2Handler.cpp +++ b/CPP/7zip/Archive/Bz2Handler.cpp @@ -366,7 +366,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt return E_INVALIDARG; size = prop.uhVal.QuadPart; } - return UpdateArchive(size, outStream, _props, updateCallback); + + CMethodProps props2 = _props; + #ifndef _7ZIP_ST + props2.AddProp_NumThreads(_props._numThreads); + #endif + + return UpdateArchive(size, outStream, props2, updateCallback); } if (indexInArchive != 0) diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp index 7834c605..c7002121 100644 --- a/CPP/7zip/Archive/Common/CoderMixer2.cpp +++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp @@ -91,6 +91,7 @@ HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPa { CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2; Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2); + if (getInStreamProcessedSize2) FOR_VECTOR (i, PackSizePointers) { if (!PackSizePointers[i]) diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp index 5fe372dd..d9fe6016 100644 --- a/CPP/7zip/Archive/DmgHandler.cpp +++ b/CPP/7zip/Archive/DmgHandler.cpp @@ -788,9 +788,21 @@ HRESULT CHandler::Open2(IInStream *stream) if (headSize != RSRC_HEAD_SIZE || footerOffset >= rsrcPair.Len || mainDataSize >= rsrcPair.Len - || footerOffset + footerSize != rsrcPair.Len + || footerOffset < mainDataSize || footerOffset != headSize + mainDataSize) return S_FALSE; + + const UInt32 footerEnd = footerOffset + footerSize; + if (footerEnd != rsrcPair.Len) + { + // there is rare case dmg example, where there are 4 additional bytes + UInt64 rem = rsrcPair.Len - footerOffset; + if (rem < footerSize + || rem - footerSize != 4 + || Get32(p + footerEnd) != 0) + return S_FALSE; + } + if (footerSize < 16) return S_FALSE; if (memcmp(p, p + footerOffset, 16) != 0) diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp index d8417fe5..db65fbea 100644 --- a/CPP/7zip/Archive/ExtHandler.cpp +++ b/CPP/7zip/Archive/ExtHandler.cpp @@ -1596,6 +1596,17 @@ STDMETHODIMP CHandler::Close() } +static void ChangeSeparatorsInName(char *s, unsigned num) +{ + for (unsigned i = 0; i < num; i++) + { + char c = s[i]; + if (c == CHAR_PATH_SEPARATOR || c == '/') + s[i] = '_'; + } +} + + void CHandler::GetPath(unsigned index, AString &s) const { s.Empty(); @@ -1612,6 +1623,8 @@ void CHandler::GetPath(unsigned index, AString &s) const if (!s.IsEmpty()) s.InsertAtFront(CHAR_PATH_SEPARATOR); s.Insert(0, item.Name); + // 18.06 + ChangeSeparatorsInName(s.GetBuf(), item.Name.Len()); if (item.ParentNode == k_INODE_ROOT) return; diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp index 9c37c062..d6623cd6 100644 --- a/CPP/7zip/Archive/FatHandler.cpp +++ b/CPP/7zip/Archive/FatHandler.cpp @@ -161,7 +161,8 @@ bool CHeader::Parse(const Byte *p) return false; // we also support images that contain 0 in offset field. - bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0)); + bool isOkOffset = (codeOffset == 0) + || (codeOffset == (p[0] == 0xEB ? 2 : 3)); UInt16 numRootDirEntries = Get16(p + 17); if (numRootDirEntries == 0) diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp index 3ff2e86e..ca1d7bda 100644 --- a/CPP/7zip/Archive/HfsHandler.cpp +++ b/CPP/7zip/Archive/HfsHandler.cpp @@ -419,7 +419,13 @@ void CDatabase::GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path) const wchar_t *src = (const wchar_t *)*s; wchar_t *dest = p + len; for (unsigned j = 0; j < curLen; j++) - dest[j] = src[j]; + { + wchar_t c = src[j]; + // 18.06 + if (c == CHAR_PATH_SEPARATOR || c == '/') + c = '_'; + dest[j] = c; + } if (len == 0) break; diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp index afdc2bfa..9eac3ca1 100644 --- a/CPP/7zip/Archive/LzmaHandler.cpp +++ b/CPP/7zip/Archive/LzmaHandler.cpp @@ -131,13 +131,7 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream, if (header.FilterID > 1) return E_NOTIMPL; - { - CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; - _lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); - if (!setDecoderProperties) - return E_NOTIMPL; - RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5)); - } + RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5)); bool filteredMode = (header.FilterID == 1); @@ -357,24 +351,54 @@ API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size) } } + + STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *) { Close(); - const UInt32 kBufSize = 1 + 5 + 8 + 2; + const unsigned headerSize = GetHeaderSize(); + const UInt32 kBufSize = 1 << 7; Byte buf[kBufSize]; - - RINOK(ReadStream_FALSE(inStream, buf, kBufSize)); - + size_t processedSize = kBufSize; + RINOK(ReadStream(inStream, buf, &processedSize)); + if (processedSize < headerSize + 2) + return S_FALSE; if (!_header.Parse(buf, _lzma86)) return S_FALSE; - const Byte *start = buf + GetHeaderSize(); + const Byte *start = buf + headerSize; if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80 return S_FALSE; - + RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize)); - if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0) + + SizeT srcLen = processedSize - headerSize; + + if (srcLen > 10 + && _header.Size == 0 + // && _header.FilterID == 0 + && _header.LzmaProps[0] == 0 + ) return S_FALSE; + + CDecoder state; + const UInt32 outLimit = 1 << 11; + Byte outBuf[outLimit]; + + SizeT outSize = outLimit; + if (outSize > _header.Size) + outSize = (SizeT)_header.Size; + SizeT destLen = outSize; + ELzmaStatus status; + + SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen, + _header.LzmaProps, 5, LZMA_FINISH_ANY, + &status, &g_Alloc); + + if (res != SZ_OK) + if (res != SZ_ERROR_INPUT_EOF) + return S_FALSE; + _isArc = true; _stream = inStream; _seqStream = inStream; diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp index bbdab45a..f4f9ab04 100644 --- a/CPP/7zip/Archive/Nsis/NsisIn.cpp +++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp @@ -2445,23 +2445,24 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p) bool strongPark = false; bool strongNsis = false; + if (NumStringChars > 2) { const Byte *strData = _data + _stringsPos; if (IsUnicode) { - UInt32 num = NumStringChars; + UInt32 num = NumStringChars - 2; for (UInt32 i = 0; i < num; i++) { if (Get16(strData + i * 2) == 0) { unsigned c2 = Get16(strData + 2 + i * 2); + // it can be TXT/RTF with marker char (1 or 2). so we must check next char // if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL) if (c2 == NS_3_CODE_VAR) { - // it can be TXT/RTF string with marker char (1 or 2). so we must next char - // const wchar_t *p2 = (const wchar_t *)(strData + i * 2 + 2); - // p2 = p2; - if ((Get16(strData + 3 + i * 2) & 0x8000) != 0) + // 18.06: fixed: is it correct ? + // if ((Get16(strData + 3 + i * 2) & 0x8000) != 0) + if ((Get16(strData + 4 + i * 2) & 0x8080) == 0x8080) { NsisType = k_NsisType_Nsis3; strongNsis = true; @@ -2478,7 +2479,7 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p) } else { - UInt32 num = NumStringChars; + UInt32 num = NumStringChars - 2; for (UInt32 i = 0; i < num; i++) { if (strData[i] == 0) diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp index 0eebf005..21372033 100644 --- a/CPP/7zip/Archive/NtfsHandler.cpp +++ b/CPP/7zip/Archive/NtfsHandler.cpp @@ -1475,6 +1475,21 @@ void CDatabase::ClearAndClose() InStream.Release(); } + +static void CopyName(wchar_t *dest, const wchar_t *src) +{ + for (;;) + { + wchar_t c = *src++; + // 18.06 + if (c == '\\' || c == '/') + c = '_'; + *dest++ = c; + if (c == 0) + return; + } +} + void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const { const CItem *item = &Items[index]; @@ -1492,7 +1507,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const wchar_t *s = path.AllocBstr(data.Name.Len() + 1); s[0] = L':'; if (!data.Name.IsEmpty()) - MyStringCopy(s + 1, data.Name.GetRawPtr()); + CopyName(s + 1, data.Name.GetRawPtr()); return; } @@ -1541,7 +1556,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const if (!name.IsEmpty()) { size -= name.Len(); - MyStringCopy(s + size, name.GetRawPtr()); + CopyName(s + size, name.GetRawPtr()); } s[--size] = ':'; needColon = true; @@ -1551,7 +1566,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const const UString2 &name = rec.FileNames[item->NameIndex].Name; unsigned len = name.Len(); if (len != 0) - MyStringCopy(s + size - len, name.GetRawPtr()); + CopyName(s + size - len, name.GetRawPtr()); if (needColon) s[size] = ':'; size -= len; @@ -1575,7 +1590,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const if (len != 0) { size -= len; - MyStringCopy(s + size, name.GetRawPtr()); + CopyName(s + size, name.GetRawPtr()); } s[size + len] = WCHAR_PATH_SEPARATOR; continue; diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp index 17fcccc3..8b99201f 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp +++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp @@ -1000,7 +1000,7 @@ bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item) struct CLinkFile { unsigned Index; - unsigned NumLinks; + unsigned NumLinks; // the number of links to Data CByteBuffer Data; HRESULT Res; bool crcOK; @@ -1015,7 +1015,7 @@ struct CUnpacker CMyComPtr<ICompressCoder> copyCoder; CMyComPtr<ICompressCoder> LzCoders[2]; - bool NeedClearSolid[2]; + bool SolidAllowed; CFilterCoder *filterStreamSpec; CMyComPtr<ISequentialInStream> filterStream; @@ -1032,7 +1032,7 @@ struct CUnpacker CLinkFile *linkFile; - CUnpacker(): linkFile(NULL) { NeedClearSolid[0] = NeedClearSolid[1] = true; } + CUnpacker(): linkFile(NULL) { SolidAllowed = false; } HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword); @@ -1142,7 +1142,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz if (method > kLzMethodMax) return E_NOTIMPL; - if (linkFile && !lastItem.Is_UnknownSize()) + bool needBuf = (linkFile && linkFile->NumLinks != 0); + + if (needBuf && !lastItem.Is_UnknownSize()) { size_t dataSize = (size_t)lastItem.Size; if (dataSize != lastItem.Size) @@ -1167,15 +1169,15 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz ICompressCoder *commonCoder = (method == 0) ? copyCoder : LzCoders[item.IsService() ? 1 : 0]; outStreamSpec->SetStream(realOutStream); - outStreamSpec->Init(lastItem, (linkFile ? (Byte *)linkFile->Data : NULL)); - - NeedClearSolid[item.IsService() ? 1 : 0] = false; + outStreamSpec->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL)); HRESULT res = S_OK; if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0) { res = commonCoder->Code(inStream, outStream, &packSize, lastItem.Is_UnknownSize() ? NULL : &lastItem.Size, progress); + if (!item.IsService()) + SolidAllowed = true; } else { @@ -1210,7 +1212,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz { linkFile->Res = res; linkFile->crcOK = isCrcOK; - if (!lastItem.Is_UnknownSize() && processedSize != lastItem.Size) + if (needBuf + && !lastItem.Is_UnknownSize() + && processedSize != lastItem.Size) linkFile->Data.ChangeSize_KeepData((size_t)processedSize, (size_t)processedSize); } @@ -2578,6 +2582,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, const Byte kStatus_Skip = 1 << 1; const Byte kStatus_Link = 1 << 2; + /* + In original RAR: + 1) service streams are not allowed to be solid, + and solid flag must be ignored for service streams. + 2) If RAR creates new solid block and first file in solid block is Link file, + then it can clear solid flag for Link file and + clear solid flag for first non-Link file after Link file. + */ + CObjectVector<CLinkFile> linkFiles; { @@ -2603,13 +2616,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (ref.Link >= 0) { - if (!testMode) + // 18.06 fixed: we use links for Test mode too + // if (!testMode) { if ((unsigned)ref.Link < index) { const CRefItem &linkRef = _refs[(unsigned)ref.Link]; const CItem &linkItem = _items[linkRef.Item]; - if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) + if (linkItem.IsSolid()) + if (testMode || linkItem.Size <= k_CopyLinkFile_MaxSize) { if (extractStatuses[(unsigned)ref.Link] == 0) { @@ -2664,19 +2679,25 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { unsigned solidLimit = 0; - FOR_VECTOR(i, _refs) + FOR_VECTOR (i, _refs) { if ((extractStatuses[i] & kStatus_Link) == 0) continue; + + // We use CLinkFile for testMode too. + // So we can show errors for copy files. + // if (!testMode) + { + CLinkFile &linkFile = linkFiles.AddNew(); + linkFile.Index = i; + } + const CItem &item = _items[_refs[i].Item]; /* if (item.IsService()) continue; */ - CLinkFile &linkFile = linkFiles.AddNew(); - linkFile.Index = i; - if (item.IsSolid()) { unsigned j = i; @@ -2707,6 +2728,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, solidLimit = i + 1; } + if (!testMode) for (UInt32 t = 0; t < numItems; t++) { unsigned index = allFilesMode ? t : indices[t]; @@ -2748,7 +2770,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, // bool needClearSolid = true; - FOR_VECTOR(i, _refs) + FOR_VECTOR (i, _refs) { if (extractStatuses[i] == 0) continue; @@ -2761,15 +2783,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CMyComPtr<ISequentialOutStream> realOutStream; + // isExtract means that we don't skip that item. So we need read data. + + bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0); Int32 askMode = - ((extractStatuses[i] & kStatus_Extract) != 0) ? (testMode ? + isExtract ? (testMode ? NExtract::NAskMode::kTest : NExtract::NAskMode::kExtract) : NExtract::NAskMode::kSkip; unpacker.linkFile = NULL; - if (((extractStatuses[i] & kStatus_Link) != 0)) + // if (!testMode) + if ((extractStatuses[i] & kStatus_Link) != 0) { int bufIndex = FindLinkBuf(linkFiles, i); if (bufIndex < 0) @@ -2791,13 +2817,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); - bool isSolid; + bool isSolid = false; + if (!item->IsService()) { - bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0]; - isSolid = (item->IsSolid() && !needClearSolid); - if (item->IsService()) - isSolid = false; - needClearSolid = !item->IsSolid(); + if (item->IsSolid()) + isSolid = unpacker.SolidAllowed; + unpacker.SolidAllowed = isSolid; } if (item->IsDir()) @@ -2826,18 +2851,30 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, curUnpackSize = 0; curPackSize = GetPackSize(index2); } - else if ((unsigned)index2 < index) - bufIndex = FindLinkBuf(linkFiles, index2); + else + { + if ((unsigned)index2 < index) + bufIndex = FindLinkBuf(linkFiles, index2); + } } + bool needCallback = true; + if (!realOutStream) { if (testMode) { if (item->NeedUse_as_CopyLink_or_HardLink()) { + Int32 opRes = NExtract::NOperationResult::kOK; + if (bufIndex >= 0) + { + const CLinkFile &linkFile = linkFiles[bufIndex]; + opRes = DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK); + } + RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); + RINOK(extractCallback->SetOperationResult(opRes)); continue; } } @@ -2846,10 +2883,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, if (item->IsService()) continue; - if (item->NeedUse_as_HardLink()) - continue; + needCallback = false; - bool needDecode = false; + if (!item->NeedUse_as_HardLink()) + if (index2 < 0) for (unsigned n = i + 1; n < _refs.Size(); n++) { @@ -2860,41 +2897,56 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, break; if (extractStatuses[i] != 0) { - needDecode = true; + needCallback = true; break; } } - if (!needDecode) - continue; - askMode = NExtract::NAskMode::kSkip; } } - RINOK(extractCallback->PrepareOperation(askMode)); + if (needCallback) + { + RINOK(extractCallback->PrepareOperation(askMode)); + } if (bufIndex >= 0) { CLinkFile &linkFile = linkFiles[bufIndex]; - if (linkFile.NumLinks == 0) - return E_FAIL; - if (realOutStream) + + if (isExtract) { - RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress)); + if (linkFile.NumLinks == 0) + return E_FAIL; + + if (needCallback) + if (realOutStream) + { + RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress)); + } + + if (--linkFile.NumLinks == 0) + linkFile.Data.Free(); + } + + if (needCallback) + { + RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))); } - if (--linkFile.NumLinks == 0) - linkFile.Data.Free(); - RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK))); continue; } + if (!needCallback) + continue; + if (item->NeedUse_as_CopyLink()) { - RINOK(extractCallback->SetOperationResult( - realOutStream ? - NExtract::NOperationResult::kUnsupportedMethod: - NExtract::NOperationResult::kOK)); + int opRes = realOutStream ? + NExtract::NOperationResult::kUnsupportedMethod: + NExtract::NOperationResult::kOK; + realOutStream.Release(); + RINOK(extractCallback->SetOperationResult(opRes)); continue; } @@ -2941,7 +2993,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } { - FOR_VECTOR(i, linkFiles) + FOR_VECTOR (i, linkFiles) if (linkFiles[i].NumLinks != 0) return E_FAIL; } diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 4b54e071..ce1df22e 100644 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -415,6 +415,8 @@ bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item) if (size < 8) return false; item.PackSize |= ((UInt64)Get32(p) << 32); + if (item.PackSize >= ((UInt64)1 << 63)) + return false; item.Size |= ((UInt64)Get32(p + 4) << 32); p += 8; size -= 8; @@ -667,7 +669,8 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass { if (processed < offset + 2) error = k_ErrorType_Corrupted; - ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset); + else + ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset); } ArcInfo.EndOfArchive_was_Read = true; diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp index 5c024328..89de660f 100644 --- a/CPP/7zip/Archive/SquashfsHandler.cpp +++ b/CPP/7zip/Archive/SquashfsHandler.cpp @@ -4,6 +4,7 @@ #include "../../../C/Alloc.h" #include "../../../C/CpuArch.h" +#include "../../../C/LzmaDec.h" #include "../../../C/Xz.h" #include "../../Common/ComTry.h" @@ -24,7 +25,7 @@ #include "../Compress/CopyCoder.h" #include "../Compress/ZlibDecoder.h" -#include "../Compress/LzmaDecoder.h" +// #include "../Compress/LzmaDecoder.h" namespace NArchive { namespace NSquashfs { @@ -866,8 +867,8 @@ class CHandler: CBufPtrSeqOutStream *_outStreamSpec; CMyComPtr<ISequentialOutStream> _outStream; - NCompress::NLzma::CDecoder *_lzmaDecoderSpec; - CMyComPtr<ICompressCoder> _lzmaDecoder; + // NCompress::NLzma::CDecoder *_lzmaDecoderSpec; + // CMyComPtr<ICompressCoder> _lzmaDecoder; NCompress::NZlib::CDecoder *_zlibDecoderSpec; CMyComPtr<ICompressCoder> _zlibDecoder; @@ -1155,12 +1156,13 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool if (inSize != _zlibDecoderSpec->GetInputProcessedSize()) return S_FALSE; } + /* else if (method == kMethod_LZMA) { if (!_lzmaDecoder) { _lzmaDecoderSpec = new NCompress::NLzma::CDecoder(); - _lzmaDecoderSpec->FinishStream = true; + // _lzmaDecoderSpec->FinishStream = true; _lzmaDecoder = _lzmaDecoderSpec; } const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; @@ -1187,6 +1189,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool if (inSize != propsSize + _lzmaDecoderSpec->GetInputProcessedSize()) return S_FALSE; } + */ else { if (_inputBuffer.Size() < inSize) @@ -1200,11 +1203,49 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool if (!dest) return E_OUTOFMEMORY; } + SizeT destLen = outSizeMax, srcLen = inSize; + if (method == kMethod_LZO) { RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen)); } + else if (method == kMethod_LZMA) + { + Byte props[5]; + const Byte *src = _inputBuffer; + + if (_noPropsLZMA) + { + props[0] = 0x5D; + SetUi32(&props[1], _h.BlockSize); + } + else + { + const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8; + if (inSize < kPropsSize) + return S_FALSE; + memcpy(props, src, LZMA_PROPS_SIZE); + UInt64 outSize = GetUi64(src + LZMA_PROPS_SIZE); + if (outSize > outSizeMax) + return S_FALSE; + destLen = (SizeT)outSize; + src += kPropsSize; + inSize -= kPropsSize; + srcLen = inSize; + } + + ELzmaStatus status; + SRes res = LzmaDecode(dest, &destLen, + src, &srcLen, + props, LZMA_PROPS_SIZE, + LZMA_FINISH_END, + &status, &g_Alloc); + if (res != 0) + return SResToHRESULT(res); + if (status != LZMA_STATUS_FINISHED_WITH_MARK) + return S_FALSE; + } else { ECoderStatus status; @@ -1217,6 +1258,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz)) return S_FALSE; } + if (inSize != srcLen) return S_FALSE; if (outBuf) diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp index 16a6e6f9..ebb6acfd 100644 --- a/CPP/7zip/Archive/SwfHandler.cpp +++ b/CPP/7zip/Archive/SwfHandler.cpp @@ -46,7 +46,7 @@ static const Byte SWF_COMPRESSED_LZMA = 'Z'; static const Byte SWF_MIN_COMPRESSED_ZLIB_VER = 6; static const Byte SWF_MIN_COMPRESSED_LZMA_VER = 13; -static const Byte kVerLim = 20; +static const Byte kVerLim = 64; API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size) { diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp index d432c318..32761658 100644 --- a/CPP/7zip/Archive/Tar/TarIn.cpp +++ b/CPP/7zip/Archive/Tar/TarIn.cpp @@ -443,14 +443,14 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro case 'X': { // pax Extended Header - if (item.Name.IsPrefixedBy("PaxHeader/")) + if (item.Name.IsPrefixedBy("PaxHeader/") + || item.Name.Find("PaxHeaders.4467/") >= 0) { RINOK(ReadDataToString(stream, item, pax, error)); if (error != k_ErrorType_OK) return S_OK; continue; } - break; } case NFileHeader::NLinkFlag::kDumpDir: @@ -488,7 +488,11 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro if (ParsePaxLongName(pax, name)) item.Name = name; else - error = k_ErrorType_Warning; + { + // no "path" property is allowed in pax4467 + // error = k_ErrorType_Warning; + } + pax.Empty(); } return S_OK; diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp index b934478e..3c712084 100644 --- a/CPP/7zip/Archive/Wim/WimIn.cpp +++ b/CPP/7zip/Archive/Wim/WimIn.cpp @@ -111,7 +111,9 @@ HRESULT CUnpacker::UnpackChunk( } else if (method == NMethod::kLZX) { - lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits); + res = lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits); + if (res != S_OK) + return E_NOTIMPL; lzxDecoderSpec->KeepHistoryForNext = false; lzxDecoderSpec->SetKeepHistory(false); res = lzxDecoderSpec->Code(packBuf.Data, inSize, (UInt32)outSize); @@ -563,7 +565,13 @@ void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCO wchar_t *dest = s + size; meta += 2; for (unsigned i = 0; i < len; i++) - dest[i] = Get16(meta + i * 2); + { + wchar_t c = Get16(meta + i * 2); + // 18.06 + if (c == CHAR_PATH_SEPARATOR || c == '/') + c = '_'; + dest[i] = c; + } } if (index < 0) return; @@ -866,7 +874,11 @@ HRESULT CDatabase::ParseImageDirs(CByteBuffer &buf, int parent) if (DirProcessed == DirSize - 8 && Get64(p + DirSize - 8) != 0) return S_OK; - return S_FALSE; + // 18.06: we support cases, when some old dism can capture images + // where DirProcessed much smaller than DirSize + HeadersError = true; + return S_OK; + // return S_FALSE; } diff --git a/CPP/7zip/Archive/Wim/WimIn.h b/CPP/7zip/Archive/Wim/WimIn.h index 6a387212..9e835b01 100644 --- a/CPP/7zip/Archive/Wim/WimIn.h +++ b/CPP/7zip/Archive/Wim/WimIn.h @@ -468,7 +468,7 @@ public: int ExludedItem; // -1 : if there are no exclude items CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives - bool ThereIsError() const { return RefCountError; } + bool ThereIsError() const { return RefCountError || HeadersError; } unsigned GetNumUserItemsInImage(unsigned imageIndex) const { @@ -544,7 +544,10 @@ public: HeadersError = false; } - CDatabase(): RefCountError(false) {} + CDatabase(): + RefCountError(false), + HeadersError(false) + {} void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const; void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const; diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp index ddaddcd5..801619fb 100644 --- a/CPP/7zip/Archive/XzHandler.cpp +++ b/CPP/7zip/Archive/XzHandler.cpp @@ -488,7 +488,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal { CXzBlock block; - Bool isIndex; + BoolInt isIndex; UInt32 headerSizeRes; SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes); if (res2 == SZ_OK && !isIndex) @@ -820,7 +820,7 @@ static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu, packRem -= inLen; - Bool blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); + BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p); if ((inLen == 0 && outLen == 0) || blockFinished) { diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp index 494b9d70..a4794f51 100644 --- a/CPP/7zip/Archive/Zip/ZipHandler.cpp +++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp @@ -599,8 +599,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidHostOS: { - const Byte hostOS = item.GetHostOS(); - TYPE_TO_PROP(kHostOS, hostOS, prop); + if (item.FromCentral) + { + // 18.06: now we use HostOS only from Central::MadeByVersion + const Byte hostOS = item.MadeByVersion.HostOS; + TYPE_TO_PROP(kHostOS, hostOS, prop); + } break; } diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp index aa7184af..509753c2 100644 --- a/CPP/7zip/Archive/Zip/ZipIn.cpp +++ b/CPP/7zip/Archive/Zip/ZipIn.cpp @@ -155,6 +155,7 @@ void CInArchive::Close() HeadersError = false; HeadersWarning = false; ExtraMinorError = false; + UnexpectedEnd = false; LocalsWereRead = false; LocalsCenterMerged = false; @@ -1729,6 +1730,9 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode) HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize) { items.Clear(); + + // _startLocalFromCd_Disk = (UInt32)(Int32)-1; + // _startLocalFromCd_Offset = (UInt64)(Int64)-1; RINOK(SeekToVol(IsMultiVol ? cdInfo.CdDisk : -1, cdOffset)); @@ -1752,6 +1756,17 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn { CItemEx cdItem; RINOK(ReadCdItem(cdItem)); + + /* + if (cdItem.Disk < _startLocalFromCd_Disk || + cdItem.Disk == _startLocalFromCd_Disk && + cdItem.LocalHeaderPos < _startLocalFromCd_Offset) + { + _startLocalFromCd_Disk = cdItem.Disk; + _startLocalFromCd_Offset = cdItem.LocalHeaderPos; + } + */ + items.Add(cdItem); } if (Callback && (items.Size() & 0xFFF) == 0) @@ -2509,6 +2524,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items) { ArcInfo.CdWasRead = true; ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos; + + // ArcInfo.FirstItemRelatOffset = _startLocalFromCd_Offset; } } } @@ -2535,6 +2552,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items) items.Clear(); localsWereRead = true; + HeadersError = false; + HeadersWarning = false; + ExtraMinorError = false; + // we can use any mode: with buffer and without buffer // without buffer : skips packed data : fast for big files : slow for small files // with buffer : reads packed data : slow for big files : fast for small files diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h index 88f29569..f46f1f07 100644 --- a/CPP/7zip/Archive/Zip/ZipIn.h +++ b/CPP/7zip/Archive/Zip/ZipIn.h @@ -250,6 +250,9 @@ class CInArchive UInt64 _streamPos; UInt64 _cnt; + // UInt32 _startLocalFromCd_Disk; + // UInt64 _startLocalFromCd_Offset; + size_t GetAvail() const { return _bufCached - _bufPos; } void InitBuf() { _bufPos = 0; _bufCached = 0; } @@ -383,6 +386,9 @@ public: UInt64 GetEmbeddedStubSize() const { + // it's possible that first item in CD doesn refers to first local item + // so FirstItemRelatOffset is not first local item + if (ArcInfo.CdWasRead) return ArcInfo.FirstItemRelatOffset; if (IsMultiVol) diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h index 78e3e01c..e5769711 100644 --- a/CPP/7zip/Archive/Zip/ZipItem.h +++ b/CPP/7zip/Archive/Zip/ZipItem.h @@ -214,6 +214,12 @@ class CLocalItem public: UInt16 Flags; UInt16 Method; + + /* + Zip specification doesn't mention that ExtractVersion field uses HostOS subfield. + 18.06: 7-Zip now doesn't use ExtractVersion::HostOS to detect codePage + */ + CVersion ExtractVersion; UInt64 Size; @@ -309,7 +315,8 @@ public: UInt32 GetWinAttrib() const; bool GetPosixAttrib(UInt32 &attrib) const; - Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; } + // 18.06: 0 instead of ExtractVersion.HostOS for local item + Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : (Byte)0; } void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const; @@ -326,7 +333,10 @@ public: UINT GetCodePage() const { - Byte hostOS = GetHostOS(); + // 18.06: now we use HostOS only from Central::MadeByVersion + if (!FromCentral) + return CP_OEMCP; + Byte hostOS = MadeByVersion.HostOS; return (UINT)(( hostOS == NFileHeader::NHostOS::kFAT || hostOS == NFileHeader::NHostOS::kNTFS diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp index 2289203b..e65c2b8b 100644 --- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp +++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp @@ -40,7 +40,10 @@ static const Byte kHostOS = #endif static const Byte kMadeByHostOS = kHostOS; -static const Byte kExtractHostOS = kHostOS; + +// 18.06: now we always write zero to high byte of ExtractVersion field. +// Previous versions of p7zip wrote (NFileHeader::NHostOS::kUnix) there, that is not correct +static const Byte kExtractHostOS = 0; static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore; diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile index 54919f73..74e5463a 100644 --- a/CPP/7zip/Bundles/LzmaCon/makefile +++ b/CPP/7zip/Bundles/LzmaCon/makefile @@ -55,5 +55,6 @@ C_OBJS = \ $O\Threads.obj \ !include "../../Crc.mak" +!include "../../LzmaDec.mak" !include "../../7zip.mak" diff --git a/CPP/7zip/Compress/DeflateDecoder.cpp b/CPP/7zip/Compress/DeflateDecoder.cpp index 88ab1f91..fceef857 100644 --- a/CPP/7zip/Compress/DeflateDecoder.cpp +++ b/CPP/7zip/Compress/DeflateDecoder.cpp @@ -446,6 +446,14 @@ void CCoder::SetOutStreamSizeResume(const UInt64 *outSize) STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize) { + /* + 18.06: + We want to support GetInputProcessedSize() before CCoder::Read() + So we call m_InBitStream.Init() even before buffer allocations + m_InBitStream.Init() just sets variables to default values + But later we will call m_InBitStream.Init() again with real buffer pointers + */ + m_InBitStream.Init(); _needInitInStream = true; SetOutStreamSizeResume(outSize); return S_OK; diff --git a/CPP/7zip/Compress/LzmsDecoder.cpp b/CPP/7zip/Compress/LzmsDecoder.cpp index 02a7f5dc..5189ce16 100644 --- a/CPP/7zip/Compress/LzmsDecoder.cpp +++ b/CPP/7zip/Compress/LzmsDecoder.cpp @@ -517,9 +517,9 @@ HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t out if (len > outSize - _pos) return S_FALSE; - if (dist > _pos) - return S_FALSE; size_t span = (size_t)1 << power; + if ((UInt64)dist + span > _pos) + return S_FALSE; Byte *dest = _win + _pos - span; const Byte *src = dest - dist; _pos += len; diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp index 10e8bff6..4456ba63 100644 --- a/CPP/7zip/Compress/Rar3Decoder.cpp +++ b/CPP/7zip/Compress/Rar3Decoder.cpp @@ -148,7 +148,8 @@ void CDecoder::ExecuteFilter(unsigned tempFilterIndex, NVm::CBlockRef &outBlockR if (!_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData)) _unsupportedFilter = true; delete tempFilter; - _tempFilters[tempFilterIndex] = 0; + _tempFilters[tempFilterIndex] = NULL; + _numEmptyTempFilters++; } HRESULT CDecoder::WriteBuf() @@ -225,6 +226,7 @@ HRESULT CDecoder::WriteBuf() void CDecoder::InitFilters() { _lastFilter = 0; + _numEmptyTempFilters = 0; unsigned i; for (i = 0; i < _tempFilters.Size(); i++) delete _tempFilters[i]; @@ -274,24 +276,27 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize) filter->ExecCount++; } - unsigned numEmptyItems = 0; + if (_numEmptyTempFilters != 0) { - FOR_VECTOR (i, _tempFilters) + unsigned num = _tempFilters.Size(); + CTempFilter **tempFilters = &_tempFilters.Front(); + + unsigned w = 0; + for (unsigned i = 0; i < num; i++) { - _tempFilters[i - numEmptyItems] = _tempFilters[i]; - if (!_tempFilters[i]) - numEmptyItems++; - if (numEmptyItems != 0) - _tempFilters[i] = NULL; + CTempFilter *tf = tempFilters[i]; + if (tf) + tempFilters[w++] = tf; } + + _tempFilters.DeleteFrom(w); + _numEmptyTempFilters = 0; } - if (numEmptyItems == 0) - { - _tempFilters.Add(NULL); - numEmptyItems = 1; - } + + if (_tempFilters.Size() > MAX_UNPACK_FILTERS) + return false; CTempFilter *tempFilter = new CTempFilter; - _tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter; + _tempFilters.Add(tempFilter); tempFilter->FilterIndex = filterIndex; UInt32 blockStart = inp.ReadEncodedUInt32(); diff --git a/CPP/7zip/Compress/Rar3Decoder.h b/CPP/7zip/Compress/Rar3Decoder.h index fbc5ac2e..3d319ded 100644 --- a/CPP/7zip/Compress/Rar3Decoder.h +++ b/CPP/7zip/Compress/Rar3Decoder.h @@ -189,6 +189,7 @@ class CDecoder: NVm::CVm _vm; CRecordVector<CFilter *> _filters; CRecordVector<CTempFilter *> _tempFilters; + unsigned _numEmptyTempFilters; UInt32 _lastFilter; bool _isSolid; diff --git a/CPP/7zip/Compress/XpressDecoder.cpp b/CPP/7zip/Compress/XpressDecoder.cpp index a38d9418..864c6f8f 100644 --- a/CPP/7zip/Compress/XpressDecoder.cpp +++ b/CPP/7zip/Compress/XpressDecoder.cpp @@ -33,10 +33,11 @@ struct CBitStream bs.Value = (bs.Value << 16) | GetUi16(in); \ in += 2; bs.BitPos += 16; } -const unsigned kNumHuffBits = 15; -const unsigned kNumLenSlots = 16; -const unsigned kNumPosSlots = 16; -const unsigned kNumSyms = 256 + kNumPosSlots * kNumLenSlots; +static const unsigned kNumHuffBits = 15; +static const unsigned kNumLenBits = 4; +static const unsigned kLenMask = (1 << kNumLenBits) - 1; +static const unsigned kNumPosSlots = 16; +static const unsigned kNumSyms = 256 + (kNumPosSlots << kNumLenBits); HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) { @@ -83,10 +84,10 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) else { sym -= 256; - UInt32 dist = sym / kNumLenSlots; - UInt32 len = sym & (kNumLenSlots - 1); + UInt32 dist = sym >> kNumLenBits; + UInt32 len = sym & kLenMask; - if (len == kNumLenSlots - 1) + if (len == kLenMask) { if (in > lim) return S_FALSE; @@ -99,7 +100,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) in += 2; } else - len += kNumLenSlots - 1; + len += kLenMask; } bs.BitPos -= dist; @@ -108,7 +109,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize) BIT_STREAM_NORMALIZE - if (len > outSize - pos) + if (len + 3 > outSize - pos) return S_FALSE; if (dist > pos) return S_FALSE; diff --git a/CPP/7zip/Crc.mak b/CPP/7zip/Crc.mak index 2e0b92ef..815142db 100644 --- a/CPP/7zip/Crc.mak +++ b/CPP/7zip/Crc.mak @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\7zCrc.obj -!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64" +!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff --git a/CPP/7zip/Crc64.mak b/CPP/7zip/Crc64.mak index 1228a014..d58a4832 100644 --- a/CPP/7zip/Crc64.mak +++ b/CPP/7zip/Crc64.mak @@ -1,6 +1,6 @@ C_OBJS = $(C_OBJS) \ $O\XzCrc64.obj -!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64" +!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64" C_OBJS = $(C_OBJS) \ !ELSE ASM_OBJS = $(ASM_OBJS) \ diff --git a/CPP/7zip/LzmaDec.mak b/CPP/7zip/LzmaDec.mak index 02e449d4..8d7f6f98 100644 --- a/CPP/7zip/LzmaDec.mak +++ b/CPP/7zip/LzmaDec.mak @@ -1,4 +1,4 @@ -!IF "$(CPU)" == "AMD64" +!IF "$(PLATFORM)" == "x64" CFLAGS_C_SPEC = -D_LZMA_DEC_OPT ASM_OBJS = $(ASM_OBJS) \ $O\LzmaDecOpt.obj diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp index c0a7bcd0..0e2a4700 100644 --- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -23,6 +23,7 @@ #include "../../../Common/StringConvert.h" #include "../../../Common/StringToInt.h" +#include "../../../Windows/ErrorMsg.h" #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" #ifdef _WIN32 @@ -39,7 +40,9 @@ extern bool g_CaseSensitive; extern bool g_PathTrailReplaceMode; +#ifdef _7ZIP_LARGE_PAGES bool g_LargePagesMode = false; +#endif #ifdef UNDER_CE @@ -410,8 +413,19 @@ static void AddToCensorFromListFile( UStringVector names; if (!NFind::DoesFileExist(us2fs(fileName))) throw CArcCmdLineException(kCannotFindListFile, fileName); - if (!ReadNamesFromListFile(us2fs(fileName), names, codePage)) + DWORD lastError = 0; + if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError)) + { + if (lastError != 0) + { + UString m; + m = "The file operation error for listfile"; + m.Add_LF(); + m += NError::MyFormatMessage(lastError); + throw CArcCmdLineException(m, fileName); + } throw CArcCmdLineException(kIncorrectListFile, fileName); + } if (renamePairs) { if ((names.Size() & 1) != 0) diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp index 083e7c84..de2f2e00 100644 --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -1182,7 +1182,9 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) bool needDelete = true; if (needDelete) { + if (NFind::DoesFileExist(fullProcessedPath)) if (!DeleteFileAlways(fullProcessedPath)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) { RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath)); return S_OK; @@ -1368,13 +1370,35 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode) // UInt64 ticks = GetCpuTicks(); bool res = _outFileStreamSpec->File.SetLength(_curSize); _fileLengthWasSet = res; - _outFileStreamSpec->File.SeekToBegin(); + // ticks = GetCpuTicks() - ticks; // printf("\nticks = %10d\n", (unsigned)ticks); if (!res) { RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath)); } + + /* + _outFileStreamSpec->File.Close(); + ticks = GetCpuTicks() - ticks; + printf("\nticks = %10d\n", (unsigned)ticks); + return S_FALSE; + */ + + /* + File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow, + if we don't write any data. + File.SetLength() for remote share file (exFAT) can be slow in some cases, + and the Windows can return "network error" after 1 minute, + while remote file still can grow. + We need some way to detect such bad cases and disable PreAllocateOutFile mode. + */ + + res = _outFileStreamSpec->File.SeekToBegin(); + if (!res) + { + RINOK(SendMessageError_with_LastError("Can not seek to begin of file", fullProcessedPath)); + } } #ifdef SUPPORT_ALT_STREAMS diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp index a3a44ce2..78dcaea3 100644 --- a/CPP/7zip/UI/Common/ArchiveName.cpp +++ b/CPP/7zip/UI/Common/ArchiveName.cpp @@ -2,6 +2,8 @@ #include "StdAfx.h" +#include "../../../Common/Wildcard.h" + #include "../../../Windows/FileDir.h" #include "../../../Windows/FileName.h" @@ -11,7 +13,7 @@ using namespace NWindows; using namespace NFile; -UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName) +static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName) { FString resultName = fi.Name; if (!fi.IsDir() && !keepName) @@ -72,7 +74,75 @@ static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepN return resultName; } -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName) + +UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi) { - return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName))); + bool keepName = false; + /* + if (paths.Size() == 1) + { + const UString &name = paths[0]; + if (name.Len() > 4) + if (CompareFileNames(name.RightPtr(4), L".tar") == 0) + keepName = true; + } + */ + + UString name; + if (fi) + name = CreateArchiveName(*fi, keepName); + else + { + if (paths.IsEmpty()) + return L"archive"; + bool fromPrev = (paths.Size() > 1); + name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName))); + } + + UString postfix; + UInt32 index = 1; + + for (;;) + { + // we don't want cases when we include archive to itself. + // so we find first available name for archive + const UString name2 = name + postfix; + const UString name2_zip = name2 + L".zip"; + const UString name2_7z = name2 + L".7z"; + const UString name2_tar = name2 + L".tar"; + const UString name2_wim = name2 + L".wim"; + + unsigned i = 0; + + for (i = 0; i < paths.Size(); i++) + { + const UString &fn = paths[i]; + NFind::CFileInfo fi2; + + const NFind::CFileInfo *fp; + if (fi && paths.Size() == 1) + fp = fi; + else + { + if (!fi2.Find(us2fs(fn))) + continue; + fp = &fi2; + } + const UString fname = fs2us(fp->Name); + if ( 0 == CompareFileNames(fname, name2_zip) + || 0 == CompareFileNames(fname, name2_7z) + || 0 == CompareFileNames(fname, name2_tar) + || 0 == CompareFileNames(fname, name2_wim)) + break; + } + + if (i == paths.Size()) + break; + index++; + postfix = "_"; + postfix.Add_UInt32(index); + } + + name += postfix; + return name; } diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h index ec2f1e8d..0d32645f 100644 --- a/CPP/7zip/UI/Common/ArchiveName.h +++ b/CPP/7zip/UI/Common/ArchiveName.h @@ -3,11 +3,8 @@ #ifndef __ARCHIVE_NAME_H #define __ARCHIVE_NAME_H -#include "../../../Common/MyString.h" - #include "../../../Windows/FileFind.h" -UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName); -UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName); +UString CreateArchiveName(const UStringVector &paths, const NWindows::NFile::NFind::CFileInfo *fi = NULL); #endif diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp index e86db15d..c5854d39 100644 --- a/CPP/7zip/UI/Common/Bench.cpp +++ b/CPP/7zip/UI/Common/Bench.cpp @@ -522,10 +522,9 @@ class CBenchProgressInfo: { public: CBenchProgressStatus *Status; - HRESULT Res; IBenchCallback *Callback; - CBenchProgressInfo(): Callback(0) {} + CBenchProgressInfo(): Callback(NULL) {} MY_UNKNOWN_IMP STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); }; @@ -758,7 +757,7 @@ struct CEncoderInfo fileData(NULL), CheckCrc_Enc(true), CheckCrc_Dec(true), - outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {} + outStreamSpec(NULL), callback(NULL), printCallback(NULL), propStreamSpec(NULL) {} #ifndef _7ZIP_ST @@ -1144,7 +1143,7 @@ static const UInt32 kNumThreadsMax = (1 << 12); struct CBenchEncoders { CEncoderInfo *encoders; - CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; } + CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; } ~CBenchEncoders() { delete []encoders; } }; @@ -1545,7 +1544,7 @@ struct CFreqThreads CFreqInfo *Items; UInt32 NumThreads; - CFreqThreads(): Items(0), NumThreads(0) {} + CFreqThreads(): Items(NULL), NumThreads(0) {} void WaitAll() { for (UInt32 i = 0; i < NumThreads; i++) @@ -1603,7 +1602,7 @@ struct CCrcThreads CCrcInfo *Items; UInt32 NumThreads; - CCrcThreads(): Items(0), NumThreads(0) {} + CCrcThreads(): Items(NULL), NumThreads(0) {} void WaitAll() { for (UInt32 i = 0; i < NumThreads; i++) @@ -1885,8 +1884,51 @@ AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti) } +static void PrintSize(AString &s, UInt64 v) +{ + char c = 0; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'K'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'M'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'G'; + if ((v & 0x3FF) == 0) { v >>= 10; c = 'T'; + }}}} + else + { + PrintHex(s, v); + return; + } + char temp[32]; + ConvertUInt64ToString(v, temp); + s += temp; + if (c) + s += c; +} + + +#ifdef _7ZIP_LARGE_PAGES + extern bool g_LargePagesMode; +extern "C" +{ + extern SIZE_T g_LargePageSize; +} + +void Add_LargePages_String(AString &s) +{ + if (g_LargePagesMode || g_LargePageSize != 0) + { + s += " (LP-"; + PrintSize(s, g_LargePageSize); + if (!g_LargePagesMode) + s += "-NA"; + s += ")"; + } +} + +#endif + + static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads) @@ -1898,8 +1940,15 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, else f.Print(" ?"); f.Print(" MB"); - if (g_LargePagesMode) - f.Print(" LP"); + + #ifdef _7ZIP_LARGE_PAGES + { + AString s; + Add_LargePages_String(s); + f.Print(s); + } + #endif + f.Print(", # "); f.Print(threadsString); PrintNumber(f, numThreads, 3); @@ -2539,26 +2588,7 @@ static const char * const k_PF[] = #endif -static void PrintSize(AString &s, UInt64 v) -{ - char c = 0; - if ((v & 0x3FF) == 0) { v >>= 10; c = 'K'; - if ((v & 0x3FF) == 0) { v >>= 10; c = 'M'; - if ((v & 0x3FF) == 0) { v >>= 10; c = 'G'; - if ((v & 0x3FF) == 0) { v >>= 10; c = 'T'; - }}}} - else - { - PrintHex(s, v); - return; - } - char temp[32]; - ConvertUInt64ToString(v, temp); - s += temp; - if (c) - s += c; -} - + static void PrintPage(AString &s, UInt32 v) { @@ -2707,8 +2737,9 @@ void GetCpuName(AString &s) #endif - if (g_LargePagesMode) - s += " (LP)"; + #ifdef _7ZIP_LARGE_PAGES + Add_LargePages_String(s); + #endif } @@ -2968,6 +2999,9 @@ HRESULT Bench( UInt64 start = ::GetTimeCount(); UInt32 sum = (UInt32)start; sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp); + if (sum == 0xF1541213) + if (printCallback) + printCallback->Print(""); const UInt64 realDelta = ::GetTimeCount() - start; start = realDelta; if (start == 0) @@ -2984,7 +3018,7 @@ HRESULT Bench( else { // PrintNumber(*printCallback, start, 0); - PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0)); + PrintNumber(*printCallback, mipsVal, 5); } } /* diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h index ec51faee..18a40a84 100644 --- a/CPP/7zip/UI/Common/Bench.h +++ b/CPP/7zip/UI/Common/Bench.h @@ -68,5 +68,10 @@ void GetSysInfo(AString &s1, AString &s2); void GetCpuName(AString &s); void GetCpuFeatures(AString &s); +#ifdef _7ZIP_LARGE_PAGES +void Add_LargePages_String(AString &s); +#else +// #define Add_LargePages_String +#endif #endif diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp index 0828dfbc..088f0777 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.cpp +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -1084,3 +1084,13 @@ CMessagePathException::CMessagePathException(const char *a, const wchar_t *u) (*this) += u; } } + +CMessagePathException::CMessagePathException(const wchar_t *a, const wchar_t *u) +{ + (*this) += a; + if (u) + { + Add_LF(); + (*this) += u; + } +} diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h index 37ebed4c..6490bd50 100644 --- a/CPP/7zip/UI/Common/EnumDirItems.h +++ b/CPP/7zip/UI/Common/EnumDirItems.h @@ -22,6 +22,7 @@ HRESULT EnumerateItems( struct CMessagePathException: public UString { CMessagePathException(const char *a, const wchar_t *u = NULL); + CMessagePathException(const wchar_t *a, const wchar_t *u = NULL); }; diff --git a/CPP/7zip/UI/Common/HashCalc.cpp b/CPP/7zip/UI/Common/HashCalc.cpp index 46a69de1..c340ac7f 100644 --- a/CPP/7zip/UI/Common/HashCalc.cpp +++ b/CPP/7zip/UI/Common/HashCalc.cpp @@ -230,7 +230,7 @@ HRESULT HashCalc( unsigned i; CHashBundle hb; RINOK(hb.SetMethods(EXTERNAL_CODECS_LOC_VARS options.Methods)); - hb.Init(); + // hb.Init(); hb.NumErrors = dirItems.Stat.NumErrors; diff --git a/CPP/7zip/UI/Common/HashCalc.h b/CPP/7zip/UI/Common/HashCalc.h index 3b4ec30d..db5b39aa 100644 --- a/CPP/7zip/UI/Common/HashCalc.h +++ b/CPP/7zip/UI/Common/HashCalc.h @@ -51,9 +51,13 @@ struct CHashBundle: public IHashCalc UInt64 CurSize; + UString MainName; + UString FirstFileName; + HRESULT SetMethods(DECL_EXTERNAL_CODECS_LOC_VARS const UStringVector &methods); - void Init() + // void Init() {} + CHashBundle() { NumDirs = NumFiles = NumAltStreams = FilesSize = AltStreamsSize = NumErrors = 0; } @@ -76,7 +80,7 @@ struct CHashBundle: public IHashCalc virtual HRESULT GetStream(const wchar_t *name, bool isFolder) x; \ virtual HRESULT OpenFileError(const FString &path, DWORD systemError) x; \ virtual HRESULT SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash) x; \ - virtual HRESULT AfterLastFile(const CHashBundle &hb) x; \ + virtual HRESULT AfterLastFile(CHashBundle &hb) x; \ struct IHashCallbackUI: public IDirItemsCallback { diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp index 11d512ae..419c29ee 100644 --- a/CPP/7zip/UI/Common/OpenArchive.cpp +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -563,6 +563,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa UInt32 parentType = 0; RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType)); + // 18.06: fixed : we don't want to split name to parts + /* if (parentType != NParentType::kAltStream) { for (;;) @@ -576,6 +578,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa s.DeleteFrom(pos); } } + */ parts.Insert(0, s); @@ -2013,7 +2016,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op) } else { - const CArcInfoEx &ai = op.codecs->Formats[formatIndex]; + const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex]; if (ai.FindExtension(extension) >= 0) { if (ai.Flags_FindSignature() && searchMarkerInHandler) diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp index 081d38eb..8c7ae45f 100644 --- a/CPP/7zip/UI/Common/Update.cpp +++ b/CPP/7zip/UI/Common/Update.cpp @@ -288,29 +288,27 @@ void CArchivePath::ParseFromPath(const UString &path, EArcNameMode mode) if (mode == k_ArcNameMode_Add) return; - if (mode == k_ArcNameMode_Exact) - { - BaseExtension.Empty(); - return; - } - int dotPos = Name.ReverseFind_Dot(); - if (dotPos < 0) - return; - if ((unsigned)dotPos == Name.Len() - 1) + if (mode != k_ArcNameMode_Exact) { - Name.DeleteBack(); - BaseExtension.Empty(); - return; - } - const UString ext = Name.Ptr(dotPos + 1); - if (BaseExtension.IsEqualTo_NoCase(ext)) - { - BaseExtension = ext; - Name.DeleteFrom(dotPos); + int dotPos = Name.ReverseFind_Dot(); + if (dotPos < 0) + return; + if ((unsigned)dotPos == Name.Len() - 1) + Name.DeleteBack(); + else + { + const UString ext = Name.Ptr(dotPos + 1); + if (BaseExtension.IsEqualTo_NoCase(ext)) + { + BaseExtension = ext; + Name.DeleteFrom(dotPos); + return; + } + } } - else - BaseExtension.Empty(); + + BaseExtension.Empty(); } UString CArchivePath::GetFinalPath() const @@ -327,6 +325,7 @@ UString CArchivePath::GetFinalPath() const UString CArchivePath::GetFinalVolPath() const { UString path = GetPathWithoutExt(); + // if BaseExtension is empty, we must ignore VolExtension also. if (!BaseExtension.IsEmpty()) { path += '.'; @@ -1166,7 +1165,7 @@ HRESULT UpdateArchive( { errorInfo.SystemError = ERROR_ACCESS_DENIED; errorInfo.Message = "The file is read-only"; - errorInfo.FileNames.Add(arcPath); + errorInfo.FileNames.Add(us2fs(arcPath)); return errorInfo.Get_HRESULT_Error(); } @@ -1377,6 +1376,31 @@ HRESULT UpdateArchive( unsigned ci; + + // self including protection + if (options.DeleteAfterCompressing) + { + for (ci = 0; ci < options.Commands.Size(); ci++) + { + CArchivePath &ap = options.Commands[ci].ArchivePath; + const FString path = us2fs(ap.GetFinalPath()); + // maybe we must compare absolute paths path here + FOR_VECTOR (i, dirItems.Items) + { + const FString phyPath = dirItems.GetPhyPath(i); + if (phyPath == path) + { + UString s; + s = "It is not allowed to include archive to itself"; + s.Add_LF(); + s += path; + throw s; + } + } + } + } + + for (ci = 0; ci < options.Commands.Size(); ci++) { CArchivePath &ap = options.Commands[ci].ArchivePath; @@ -1562,26 +1586,39 @@ HRESULT UpdateArchive( } CCurrentDirRestorer curDirRestorer; + + AStringVector paths; + AStringVector names; for (i = 0; i < fullPaths.Size(); i++) { const UString arcPath2 = fs2us(fullPaths[i]); const UString fileName = ExtractFileNameFromPath(arcPath2); - const AString path (GetAnsiString(arcPath2)); - const AString name (GetAnsiString(fileName)); + paths.Add(GetAnsiString(arcPath2)); + names.Add(GetAnsiString(fileName)); + // const AString path (GetAnsiString(arcPath2)); + // const AString name (GetAnsiString(fileName)); // Warning!!! MAPISendDocuments function changes Current directory // fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } - MapiFileDesc f; + CRecordVector<MapiFileDesc> files; + files.ClearAndSetSize(paths.Size()); + + for (i = 0; i < paths.Size(); i++) + { + MapiFileDesc &f = files[i]; memset(&f, 0, sizeof(f)); f.nPosition = 0xFFFFFFFF; - f.lpszPathName = (char *)(const char *)path; - f.lpszFileName = (char *)(const char *)name; - + f.lpszPathName = (char *)(const char *)paths[i]; + f.lpszFileName = (char *)(const char *)names[i]; + } + + { MapiMessage m; memset(&m, 0, sizeof(m)); - m.nFileCount = 1; - m.lpFiles = &f; + m.nFileCount = files.Size(); + m.lpFiles = &files.Front(); const AString addr (GetAnsiString(options.EMailAddress)); MapiRecipDesc rec; diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp index ab80ce37..762b21bb 100644 --- a/CPP/7zip/UI/Console/HashCon.cpp +++ b/CPP/7zip/UI/Console/HashCon.cpp @@ -332,7 +332,7 @@ void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value) *_so << name << s << endl; } -HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb) +HRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb) { ClosePercents2(); diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp index 38e23e21..416ef2c9 100644 --- a/CPP/7zip/UI/Console/List.cpp +++ b/CPP/7zip/UI/Console/List.cpp @@ -1072,18 +1072,24 @@ HRESULT ListArchives(CCodecs *codecs, errorCode = ERROR_FILE_NOT_FOUND; lastError = HRESULT_FROM_WIN32(lastError);; g_StdOut.Flush(); - *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; - g_ErrStream->NormalizePrint_UString(arcPath); - *g_ErrStream << endl << endl; + if (g_ErrStream) + { + *g_ErrStream << endl << kError << NError::MyFormatMessage(errorCode) << endl; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << endl << endl; + } numErrors++; continue; } if (fi.IsDir()) { g_StdOut.Flush(); - *g_ErrStream << endl << kError; - g_ErrStream->NormalizePrint_UString(arcPath); - *g_ErrStream << " is not a file" << endl << endl; + if (g_ErrStream) + { + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " is not a file" << endl << endl; + } numErrors++; continue; } @@ -1133,24 +1139,28 @@ HRESULT ListArchives(CCodecs *codecs, { if (result == E_ABORT) return result; + if (result != S_FALSE) + lastError = result; g_StdOut.Flush(); - *g_ErrStream << endl << kError; - g_ErrStream->NormalizePrint_UString(arcPath); - *g_ErrStream << " : "; - if (result == S_FALSE) + if (g_ErrStream) { - Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); - } - else - { - lastError = result; - *g_ErrStream << "opening : "; - if (result == E_OUTOFMEMORY) - *g_ErrStream << "Can't allocate required memory"; + *g_ErrStream << endl << kError; + g_ErrStream->NormalizePrint_UString(arcPath); + *g_ErrStream << " : "; + if (result == S_FALSE) + { + Print_OpenArchive_Error(*g_ErrStream, codecs, arcLink); + } else - *g_ErrStream << NError::MyFormatMessage(result); + { + *g_ErrStream << "opening : "; + if (result == E_OUTOFMEMORY) + *g_ErrStream << "Can't allocate required memory"; + else + *g_ErrStream << NError::MyFormatMessage(result); + } + *g_ErrStream << endl; } - *g_ErrStream << endl; numErrors++; continue; } diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp index a632c1b4..f300c3d4 100644 --- a/CPP/7zip/UI/Console/Main.cpp +++ b/CPP/7zip/UI/Console/Main.cpp @@ -24,6 +24,7 @@ #include "../../../Windows/TimeUtils.h" #include "../Common/ArchiveCommandLine.h" +#include "../Common/Bench.h" #include "../Common/ExitCode.h" #include "../Common/Extract.h" @@ -56,8 +57,6 @@ using namespace NCommandLineParser; HINSTANCE g_hInstance = 0; #endif -extern bool g_LargePagesMode; - extern CStdOutStream *g_StdStream; extern CStdOutStream *g_ErrStream; @@ -236,7 +235,7 @@ static void PrintWarningsPaths(const CErrorPathCodes &pc, CStdOutStream &so) { FOR_VECTOR(i, pc.Paths) { - so.NormalizePrint_UString(pc.Paths[i]); + so.NormalizePrint_UString(fs2us(pc.Paths[i])); so << " : "; so << NError::MyFormatMessage(pc.Codes[i]) << endl; } @@ -376,8 +375,13 @@ static void PrintMemUsage(const char *s, UInt64 val) *g_StdStream << " " << s << " Memory ="; PrintNum(SHIFT_SIZE_VALUE(val, 20), 7); *g_StdStream << " MB"; - if (g_LargePagesMode) - *g_StdStream << " (LP)"; + + #ifdef _7ZIP_LARGE_PAGES + AString lp; + Add_LargePages_String(lp); + if (!lp.IsEmpty()) + *g_StdStream << lp; + #endif } EXTERN_C_BEGIN @@ -911,7 +915,7 @@ int Main2( { hashCalc = &hb; ThrowException_if_Error(hb.SetMethods(EXTERNAL_CODECS_VARS_L options.HashMethods)); - hb.Init(); + // hb.Init(); } hresultMain = Extract( diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp index 21de12a5..fff6fa25 100644 --- a/CPP/7zip/UI/Explorer/ContextMenu.cpp +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -582,7 +582,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, } } - const UString &fileName = _fileNames.Front(); + // const UString &fileName = _fileNames.Front(); if (needExtract) { @@ -639,12 +639,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, } } - UString arcName; - if (_fileNames.Size() == 1) - arcName = CreateArchiveName(fi0, false); - else - arcName = CreateArchiveName(fileName, _fileNames.Size() > 1, false); - + const UString arcName = CreateArchiveName(_fileNames, _fileNames.Size() == 1 ? &fi0 : NULL); + UString arcName7z = arcName; arcName7z += ".7z"; UString arcNameZip = arcName; diff --git a/CPP/7zip/UI/Far/Far.cpp b/CPP/7zip/UI/Far/Far.cpp index cec4af52..5d92bc40 100644 --- a/CPP/7zip/UI/Far/Far.cpp +++ b/CPP/7zip/UI/Far/Far.cpp @@ -327,7 +327,7 @@ HRESULT OpenArchive(const CSysString &fileName, } */ -static HANDLE MyOpenFilePluginW(const wchar_t *name) +static HANDLE MyOpenFilePluginW(const wchar_t *name, bool isAbortCodeSupported) { FString normalizedName = us2fs(name); normalizedName.Trim(); @@ -373,7 +373,12 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name) archiverInfoResult, defaultName, openArchiveCallback); */ if (result == E_ABORT) - return (HANDLE)-2; + { + // fixed 18.06: + // OpenFilePlugin() is allowed to return (HANDLE)-2 as abort code + // OpenPlugin() is not allowed to return (HANDLE)-2. + return isAbortCodeSupported ? (HANDLE)-2 : INVALID_HANDLE_VALUE; + } UString errorMessage = agent->GetErrorMessage(); if (!errorMessage.IsEmpty()) @@ -403,7 +408,7 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name) return (HANDLE)(plugin); } -static HANDLE MyOpenFilePlugin(const char *name) +static HANDLE MyOpenFilePlugin(const char *name, bool isAbortCodeSupported) { UINT codePage = #ifdef UNDER_CE @@ -411,7 +416,7 @@ static HANDLE MyOpenFilePlugin(const char *name) #else ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; #endif - return MyOpenFilePluginW(GetUnicodeString(name, codePage)); + return MyOpenFilePluginW(GetUnicodeString(name, codePage), isAbortCodeSupported); } EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char * /* data */, int /* dataSize */) @@ -423,7 +428,7 @@ EXTERN_C HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char * /* data // if (!Opt.ProcessShiftF1) return(INVALID_HANDLE_VALUE); } - return MyOpenFilePlugin(name); + return MyOpenFilePlugin(name, true); // isAbortCodeSupported MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE); } @@ -458,7 +463,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) fileName.DeleteBack(); fileName.DeleteFrontal(1); } - return MyOpenFilePlugin(fileName); + return MyOpenFilePlugin(fileName, false); // isAbortCodeSupported } if (openFrom == OPEN_PLUGINSMENU) @@ -470,7 +475,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item) PluginPanelItem pluginPanelItem; if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) throw 142134; - return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName); + return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName, false); // isAbortCodeSupported } case 1: diff --git a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp index b7fbb235..7069e1aa 100644 --- a/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp +++ b/CPP/7zip/UI/FileManager/AltStreamsFolder.cpp @@ -468,7 +468,7 @@ static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR ou { if (NFind::DoesFileOrDirExist(outPath)) { - RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), outPath)); + RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), FString(outPath))); CFileInfo fi; if (fi.Find(inPath)) { diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp index a5317e26..1bc96ae3 100644 --- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp +++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp @@ -759,11 +759,15 @@ STDMETHODIMP CExtractCallbackImp::AskWrite( destPathResultTemp = fs2us(destPathSys); } else + { + if (NFind::DoesFileExist(destPathSys)) if (!NDir::DeleteFileAlways(destPathSys)) + if (GetLastError() != ERROR_FILE_NOT_FOUND) { RINOK(MessageError("can not delete output file", destPathSys)); return E_ABORT; } + } } *writeAnswer = BoolToInt(true); return StringToBstr(destPathResultTemp, destPathResult); diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp index 9ad7bcc5..a42e790b 100644 --- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp +++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp @@ -213,6 +213,12 @@ void CListViewDialog::ShowItemInfo() if (index < Values.Size()) dlg.Text = Values[index]; } + + #ifdef _WIN32 + if (dlg.Text.Find(L'\r') < 0) + dlg.Text.Replace(L"\n", L"\r\n"); + #endif + dlg.Create(*this); } diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp index 973e64dd..afb5649a 100644 --- a/CPP/7zip/UI/FileManager/Panel.cpp +++ b/CPP/7zip/UI/FileManager/Panel.cpp @@ -879,8 +879,9 @@ void CPanel::AddToArchive() FOR_VECTOR (i, indices) names.Add(curPrefix + GetItemRelPath2(indices[i])); - bool fromPrev = (names.Size() > 1); - const UString arcName = CreateArchiveName(names.Front(), fromPrev, false); + + const UString arcName = CreateArchiveName(names); + HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"", true, // addExtension names, false, true, false); diff --git a/CPP/7zip/UI/FileManager/PanelCopy.cpp b/CPP/7zip/UI/FileManager/PanelCopy.cpp index 5715d9de..c3416cc7 100644 --- a/CPP/7zip/UI/FileManager/PanelCopy.cpp +++ b/CPP/7zip/UI/FileManager/PanelCopy.cpp @@ -29,7 +29,7 @@ public: CMyComPtr<IFolderOperationsExtractCallback> ExtractCallback; CHashBundle Hash; - UString FirstFilePath; + // UString FirstFilePath; HRESULT Result; @@ -48,7 +48,7 @@ void CPanelCopyThread::ShowFinalResults(HWND hwnd) if (!ResultsWereShown) { ResultsWereShown = true; - ShowHashResults(Hash, fs2us(FirstFilePath), hwnd); + ShowHashResults(Hash, hwnd); } } @@ -100,7 +100,7 @@ HRESULT CPanelCopyThread::ProcessVirt() else if (options->testMode) { CProgressMessageBoxPair &pair = GetMessagePair(false); // GetMessagePair(ExtractCallbackSpec->Hash.NumErrors != 0); - AddHashBundleRes(pair.Message, Hash, FirstFilePath); + AddHashBundleRes(pair.Message, Hash); } } @@ -158,7 +158,10 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind if (indices.Size() == 1) - extracter.FirstFilePath = GetItemRelPath(indices[0]); + { + extracter.Hash.FirstFileName = GetItemRelPath(indices[0]); + extracter.Hash.MainName = extracter.Hash.FirstFileName; + } if (options.VirtFileSystem) { @@ -186,7 +189,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind extracter.ExtractCallbackSpec->SetHashCalc(&extracter.Hash); } - extracter.Hash.Init(); + // extracter.Hash.Init(); UString title; { diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp index 7b918a02..1cfbfe5d 100644 --- a/CPP/7zip/UI/FileManager/PanelCrc.cpp +++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp @@ -147,7 +147,7 @@ class CThreadCrc: public CProgressThreadVirt public: CDirEnumerator Enumerator; CHashBundle Hash; - FString FirstFilePath; + // FString FirstFilePath; void SetStatus(const UString &s); void AddErrorMessage(DWORD systemError, const FChar *name); @@ -165,7 +165,7 @@ void CThreadCrc::ShowFinalResults(HWND hwnd) if (!ResultsWereShown) { ResultsWereShown = true; - ShowHashResults(Hash, fs2us(FirstFilePath), hwnd); + ShowHashResults(Hash, hwnd); } } @@ -193,7 +193,7 @@ void CThreadCrc::SetStatus(const UString &s2) HRESULT CThreadCrc::ProcessVirt() { - Hash.Init(); + // Hash.Init(); CMyBuffer buf; if (!buf.Allocate(kBufSize)) @@ -289,7 +289,7 @@ HRESULT CThreadCrc::ProcessVirt() } if (isFirstFile) { - FirstFilePath = path; + Hash.FirstFileName = path; isFirstFile = false; } sync.Set_FilePath(fs2us(path)); @@ -370,9 +370,13 @@ HRESULT CApp::CalculateCrc2(const UString &methodName) methods.Add(methodName); RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods)); } + FOR_VECTOR (i, indices) t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i]))); + if (t.Enumerator.FilePaths.Size() == 1) + t.Hash.MainName = t.Enumerator.FilePaths[0]; + UString basePrefix = srcPanel.GetFsPath(); UString basePrefix2 = basePrefix; if (basePrefix2.Back() == ':') diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp index 9f64c2c8..6a781e22 100644 --- a/CPP/7zip/UI/FileManager/PanelDrag.cpp +++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp @@ -940,8 +940,10 @@ void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &fo if (IsFolderInTemp(folderPath2F)) folderPath2 = ROOT_FS_FOLDER; } - const UString archiveName = CreateArchiveName(fileNames.Front(), (fileNames.Size() > 1), false); - CompressFiles(folderPath2, archiveName, L"", + + const UString arcName = CreateArchiveName(fileNames); + + CompressFiles(folderPath2, arcName, L"", true, // addExtension fileNames, false, // email diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp index 59dc78b3..e6dc57ba 100644 --- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp +++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp @@ -324,7 +324,6 @@ static void PrintSize_MB(UString &s, UInt64 size) s += kMB; } -extern bool g_LargePagesMode; UInt32 CBenchmarkDialog::OnChangeDictionary() { @@ -338,8 +337,14 @@ UInt32 CBenchmarkDialog::OnChangeDictionary() s += " / "; PrintSize_MB(s, ramSize); } - if (g_LargePagesMode) - s += " LP"; + + #ifdef _7ZIP_LARGE_PAGES + { + AString s2; + Add_LargePages_String(s2); + s += s2; + } + #endif SetItemText(IDT_BENCH_MEMORY_VAL, s); diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp index 814415f6..1e37efb8 100644 --- a/CPP/7zip/UI/GUI/ExtractGUI.cpp +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -99,8 +99,10 @@ HRESULT CThreadExtracting::ProcessVirt() CDecompressStat Stat; #ifndef _SFX + /* if (HashBundle) HashBundle->Init(); + */ #endif HRESULT res = Extract(codecs, @@ -119,7 +121,7 @@ HRESULT CThreadExtracting::ProcessVirt() { AddValuePair(Pairs, IDS_ARCHIVES_COLON, Stat.NumArchives); AddSizeValuePair(Pairs, IDS_PROP_PACKED_SIZE, Stat.PackSize); - AddHashBundleRes(Pairs, *HashBundle, UString()); + AddHashBundleRes(Pairs, *HashBundle); } else if (Options->TestMode) { diff --git a/CPP/7zip/UI/GUI/HashGUI.cpp b/CPP/7zip/UI/GUI/HashGUI.cpp index 7cb00973..37cd65e9 100644 --- a/CPP/7zip/UI/GUI/HashGUI.cpp +++ b/CPP/7zip/UI/GUI/HashGUI.cpp @@ -27,6 +27,7 @@ class CHashCallbackGUI: public CProgressThreadVirt, public IHashCallbackUI UInt64 NumFiles; bool _curIsFolder; UString FirstFileName; + // UString MainPath; CPropNameValPairs PropNameValPairs; @@ -71,9 +72,9 @@ void AddSizeValue(UString &s, UInt64 value) if (value >= (1 << 10)) { char c; - if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; } - if (value >= (10 << 20)) { value >>= 20; c = 'M'; } - else { value >>= 10; c = 'K'; } + if (value >= ((UInt64)10 << 30)) { value >>= 30; c = 'G'; } + else if (value >= (10 << 20)) { value >>= 20; c = 'M'; } + else { value >>= 10; c = 'K'; } char sz[32]; ConvertUInt64ToString(value, sz); s += " ("; @@ -192,19 +193,25 @@ static void AddHashResString(CPropNameValPairs &s, const CHasherState &h, unsign } -void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName) +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb) { if (hb.NumErrors != 0) AddValuePair(s, IDS_PROP_NUM_ERRORS, hb.NumErrors); - - if (hb.NumFiles == 1 && hb.NumDirs == 0 && !firstFileName.IsEmpty()) + + if (hb.NumFiles == 1 && hb.NumDirs == 0 && !hb.FirstFileName.IsEmpty()) { CProperty &pair = s.AddNew(); LangString(IDS_PROP_NAME, pair.Name); - pair.Value = firstFileName; + pair.Value = hb.FirstFileName; } else { + if (!hb.MainName.IsEmpty()) + { + CProperty &pair = s.AddNew(); + LangString(IDS_PROP_NAME, pair.Name); + pair.Value = hb.MainName; + } if (hb.NumDirs != 0) AddValuePair(s, IDS_PROP_FOLDERS, hb.NumDirs); AddValuePair(s, IDS_PROP_FILES, hb.NumFiles); @@ -240,10 +247,10 @@ void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString } -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName) +void AddHashBundleRes(UString &s, const CHashBundle &hb) { CPropNameValPairs pairs; - AddHashBundleRes(pairs, hb, firstFileName); + AddHashBundleRes(pairs, hb); FOR_VECTOR (i, pairs) { @@ -263,9 +270,11 @@ void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFil } -HRESULT CHashCallbackGUI::AfterLastFile(const CHashBundle &hb) +HRESULT CHashCallbackGUI::AfterLastFile(CHashBundle &hb) { - AddHashBundleRes(PropNameValPairs, hb, FirstFileName); + hb.FirstFileName = FirstFileName; + // MainPath + AddHashBundleRes(PropNameValPairs, hb); CProgressSync &sync = Sync; sync.Set_NumFilesCur(hb.NumFiles); @@ -335,10 +344,10 @@ void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd) } -void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd) +void ShowHashResults(const CHashBundle &hb, HWND hwnd) { CPropNameValPairs propPairs; - AddHashBundleRes(propPairs, hb, firstFileName); + AddHashBundleRes(propPairs, hb); ShowHashResults(propPairs, hwnd); } diff --git a/CPP/7zip/UI/GUI/HashGUI.h b/CPP/7zip/UI/GUI/HashGUI.h index 4035abf1..82644535 100644 --- a/CPP/7zip/UI/GUI/HashGUI.h +++ b/CPP/7zip/UI/GUI/HashGUI.h @@ -18,10 +18,10 @@ void AddValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); void AddSizeValue(UString &s, UInt64 value); void AddSizeValuePair(CPropNameValPairs &pairs, UINT resourceID, UInt64 value); -void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb, const UString &firstFileName); -void AddHashBundleRes(UString &s, const CHashBundle &hb, const UString &firstFileName); +void AddHashBundleRes(CPropNameValPairs &s, const CHashBundle &hb); +void AddHashBundleRes(UString &s, const CHashBundle &hb); void ShowHashResults(const CPropNameValPairs &propPairs, HWND hwnd); -void ShowHashResults(const CHashBundle &hb, const UString &firstFileName, HWND hwnd); +void ShowHashResults(const CHashBundle &hb, HWND hwnd); #endif diff --git a/CPP/Build.mak b/CPP/Build.mak index 5a11d066..4186a60b 100644 --- a/CPP/Build.mak +++ b/CPP/Build.mak @@ -4,19 +4,20 @@ LIBS = $(LIBS) oleaut32.lib ole32.lib CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE !ENDIF -# CFLAGS = $(CFLAGS) -FAsc -Fa$O/Asm/ - !IFNDEF O -!IFDEF CPU -O=$(CPU) +!IFDEF PLATFORM +O=$(PLATFORM) !ELSE -O=O +O=o !ENDIF !ENDIF -!IF "$(CPU)" == "AMD64" +# CFLAGS = $(CFLAGS) -FAsc -Fa$O/asm/ + + +!IF "$(PLATFORM)" == "x64" MY_ML = ml64 -Dx64 -WX -!ELSEIF "$(CPU)" == "ARM" +!ELSEIF "$(PLATFORM)" == "arm" MY_ML = armasm -WX !ELSE MY_ML = ml -WX @@ -29,16 +30,16 @@ RFLAGS = $(RFLAGS) -dUNDER_CE LFLAGS = $(LFLAGS) /ENTRY:mainACRTStartup !ENDIF !ELSE -!IFNDEF NEW_COMPILER +!IFDEF OLD_COMPILER LFLAGS = $(LFLAGS) -OPT:NOWIN98 !ENDIF -!IF "$(CPU)" != "ARM" && "$(CPU)" != "ARM64" +!IF "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" CFLAGS = $(CFLAGS) -Gr !ENDIF LIBS = $(LIBS) user32.lib advapi32.lib shell32.lib !ENDIF -!IF "$(CPU)" == "ARM" +!IF "$(PLATFORM)" == "arm" COMPL_ASM = $(MY_ML) $** $O/$(*B).obj !ELSE COMPL_ASM = $(MY_ML) -c -Fo$O/ $** @@ -46,19 +47,19 @@ COMPL_ASM = $(MY_ML) -c -Fo$O/ $** CFLAGS = $(CFLAGS) -nologo -c -Fo$O/ -W4 -WX -EHsc -Gy -GR- -GF -!IFDEF MY_STATIC_LINK +!IFDEF MY_DYNAMIC_LINK +CFLAGS = $(CFLAGS) -MD +!ELSE !IFNDEF MY_SINGLE_THREAD CFLAGS = $(CFLAGS) -MT !ENDIF -!ELSE -CFLAGS = $(CFLAGS) -MD !ENDIF -!IFDEF NEW_COMPILER +!IFNDEF OLD_COMPILER CFLAGS = $(CFLAGS) -GS- -Zc:forScope -Zc:wchar_t !IFNDEF UNDER_CE CFLAGS = $(CFLAGS) -MP2 -!IFNDEF CPU +!IFNDEF PLATFORM # CFLAGS = $(CFLAGS) -arch:IA32 !ENDIF !ENDIF @@ -66,7 +67,13 @@ CFLAGS = $(CFLAGS) -MP2 CFLAGS = $(CFLAGS) !ENDIF -!IF "$(CPU)" == "AMD64" +!IFNDEF UNDER_CE +!IF "$(PLATFORM)" == "arm" +CFLAGS = $(CFLAGS) -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE +!ENDIF +!ENDIF + +!IF "$(PLATFORM)" == "x64" CFLAGS_O1 = $(CFLAGS) -O1 !ELSE CFLAGS_O1 = $(CFLAGS) -O1 @@ -82,7 +89,7 @@ LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE !IFDEF DEF_FILE LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE) !ELSE -!IF defined(MY_FIXED) && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64" +!IF defined(MY_FIXED) && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64" LFLAGS = $(LFLAGS) /FIXED !ELSE LFLAGS = $(LFLAGS) /FIXED:NO @@ -91,7 +98,7 @@ LFLAGS = $(LFLAGS) /FIXED:NO !ENDIF -# !IF "$(CPU)" == "AMD64" +# !IF "$(PLATFORM)" == "x64" !IFDEF SUB_SYS_VER @@ -131,10 +138,10 @@ clean: $O: if not exist "$O" mkdir "$O" -$O/Asm: - if not exist "$O/Asm" mkdir "$O/Asm" +$O/asm: + if not exist "$O/asm" mkdir "$O/asm" -$(PROGPATH): $O $O/Asm $(OBJS) $(DEF_FILE) +$(PROGPATH): $O $O/asm $(OBJS) $(DEF_FILE) link $(LFLAGS) -out:$(PROGPATH) $(OBJS) $(LIBS) !IFNDEF NO_DEFAULT_RES diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp index 9112003b..ca345e87 100644 --- a/CPP/Common/ListFileUtils.cpp +++ b/CPP/Common/ListFileUtils.cpp @@ -25,14 +25,21 @@ static void AddName(UStringVector &strings, UString &s) strings.Add(s); } -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage) +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, DWORD &lastError) { + lastError = 0; NWindows::NFile::NIO::CInFile file; if (!file.Open(fileName)) + { + lastError = ::GetLastError(); return false; + } UInt64 fileSize; if (!file.GetLength(fileSize)) + { + lastError = ::GetLastError(); return false; + } if (fileSize >= ((UInt32)1 << 31) - 32) return false; UString u; @@ -43,7 +50,10 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage CByteArr buf((size_t)fileSize); UInt32 processed; if (!file.Read(buf, (UInt32)fileSize, processed)) + { + lastError = ::GetLastError(); return false; + } if (processed != fileSize) return false; file.Close(); @@ -74,7 +84,10 @@ bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage char *p = s.GetBuf((unsigned)fileSize); UInt32 processed; if (!file.Read(p, (UInt32)fileSize, processed)) + { + lastError = ::GetLastError(); return false; + } if (processed != fileSize) return false; file.Close(); diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h index e8d833fd..a91e4b11 100644 --- a/CPP/Common/ListFileUtils.h +++ b/CPP/Common/ListFileUtils.h @@ -9,6 +9,10 @@ #define MY__CP_UTF16 1200 #define MY__CP_UTF16BE 1201 -bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); +// bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP); + + // = CP_OEMCP +bool ReadNamesFromListFile2(CFSTR fileName, UStringVector &strings, UINT codePage, + DWORD &lastError); #endif diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h index abdc8cf8..40de52cd 100644 --- a/CPP/Common/MyString.h +++ b/CPP/Common/MyString.h @@ -307,6 +307,7 @@ public: void ReplaceOneCharAtPos(unsigned pos, char c) { _chars[pos] = c; } + char *GetBuf() { return _chars; } /* GetBuf(minLen): provides the buffer that can store at least (minLen) characters and additional null terminator. 9.35: GetBuf doesn't preserve old characters and terminator */ |