diff options
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 72 |
1 files changed, 47 insertions, 25 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp index be20940c033..359835d3c2c 100644 --- a/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp +++ b/3rdparty/lzma/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -2,9 +2,10 @@ #include "StdAfx.h" -#include "Common/ComTry.h" +#include "../../../Common/ComTry.h" -#include "Windows/PropVariant.h" +#include "../../../Windows/FileName.h" +#include "../../../Windows/PropVariant.h" #include "../../Common/FileStreams.h" @@ -39,12 +40,12 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) COM_TRY_BEGIN NCOM::CPropVariant prop; if (_subArchiveMode) - switch(propID) + switch (propID) { case kpidName: prop = _subArchiveName; break; } else - switch(propID) + switch (propID) { case kpidName: prop = _fileInfo.Name; break; case kpidIsDir: prop = _fileInfo.IsDir(); break; @@ -59,41 +60,54 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) COM_TRY_END } -int COpenCallbackImp::FindName(const UString &name) -{ - for (int i = 0; i < FileNames.Size(); i++) - if (name.CompareNoCase(FileNames[i]) == 0) - return i; - return -1; -} - struct CInFileStreamVol: public CInFileStream { - UString Name; + int FileNameIndex; COpenCallbackImp *OpenCallbackImp; CMyComPtr<IArchiveOpenCallback> OpenCallbackRef; + ~CInFileStreamVol() { if (OpenCallbackRef) - { - int index = OpenCallbackImp->FindName(Name); - if (index >= 0) - OpenCallbackImp->FileNames.Delete(index); - } + OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false; } }; + +// from ArchiveExtractCallback.cpp +bool IsSafePath(const UString &path); + STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) { COM_TRY_BEGIN + *inStream = NULL; + if (_subArchiveMode) return S_FALSE; if (Callback) { RINOK(Callback->Open_CheckBreak()); } - *inStream = NULL; - FString fullPath = _folderPrefix + us2fs(name); + + UString name2 = name; + + + #ifndef _SFX + + #ifdef _WIN32 + name2.Replace(L'/', WCHAR_PATH_SEPARATOR); + #endif + + // if (!allowAbsVolPaths) + if (!IsSafePath(name2)) + return S_FALSE; + + #endif + + + FString fullPath; + if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name2), fullPath)) + return S_FALSE; if (!_fileInfo.Find(fullPath)) return S_FALSE; if (_fileInfo.IsDir()) @@ -101,13 +115,20 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre CInFileStreamVol *inFile = new CInFileStreamVol; CMyComPtr<IInStream> inStreamTemp = inFile; if (!inFile->Open(fullPath)) - return ::GetLastError(); - *inStream = inStreamTemp.Detach(); - inFile->Name = name; + { + DWORD lastError = ::GetLastError(); + if (lastError == 0) + return E_FAIL; + return HRESULT_FROM_WIN32(lastError); + } + + FileSizes.Add(_fileInfo.Size); + FileNames.Add(name2); + inFile->FileNameIndex = FileNames_WasUsed.Add(true); inFile->OpenCallbackImp = this; inFile->OpenCallbackRef = this; - FileNames.Add(name); - TotalSize += _fileInfo.Size; + // TotalSize += _fileInfo.Size; + *inStream = inStreamTemp.Detach(); return S_OK; COM_TRY_END } @@ -125,6 +146,7 @@ STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) } if (!Callback) return E_NOTIMPL; + PasswordWasAsked = true; return Callback->Open_CryptoGetTextPassword(password); COM_TRY_END } |