| diff --git a/third_party/unrar/src/crc.cpp b/third_party/unrar/src/crc.cpp |
| index 1097f4cd00d1..8488e102c28e 100644 |
| --- a/third_party/unrar/src/crc.cpp |
| +++ b/third_party/unrar/src/crc.cpp |
| @@ -15,6 +15,7 @@ |
| #include "rar.hpp" |
| |
| static uint crc_tables[8][256]; // Tables for Slicing-by-8. |
| +static bool is_initialized = false; |
| |
| |
| // Build the classic CRC32 lookup table. |
| @@ -49,10 +50,13 @@ static void InitTables() |
| } |
| |
| |
| -struct CallInitCRC {CallInitCRC() {InitTables();}} static CallInit32; |
| - |
| uint CRC32(uint StartCRC,const void *Addr,size_t Size) |
| { |
| + if (!is_initialized) { |
| + is_initialized = true; |
| + InitTables(); |
| + } |
| + |
| byte *Data=(byte *)Addr; |
| |
| // Align Data to 8 for better performance. |
| diff --git a/third_party/unrar/src/errhnd.cpp b/third_party/unrar/src/errhnd.cpp |
| index e862bb3a7566..3dd92a9cb88a 100644 |
| --- a/third_party/unrar/src/errhnd.cpp |
| +++ b/third_party/unrar/src/errhnd.cpp |
| @@ -1,10 +1,11 @@ |
| -#include "rar.hpp" |
| - |
| -ErrorHandler::ErrorHandler() |
| -{ |
| - Clean(); |
| -} |
| +// NOTE(vakh): The process.h file needs to be included first because "rar.hpp" |
| +// defines certain macros that cause symbol redefinition errors |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| +#include "base/logging.h" |
| +#include "base/process/process.h" |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| |
| +#include "rar.hpp" |
| |
| void ErrorHandler::Clean() |
| { |
| @@ -320,7 +321,11 @@ void ErrorHandler::Throw(RAR_EXIT Code) |
| mprintf(L"\n%s\n",St(MProgAborted)); |
| #endif |
| SetErrorCode(Code); |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + CHECK(false) << "Failed with RAR_EXIT code: " << Code; |
| +#else |
| throw Code; |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| } |
| |
| |
| diff --git a/third_party/unrar/src/errhnd.hpp b/third_party/unrar/src/errhnd.hpp |
| index 26df96d5b436..1bcae41e7007 100644 |
| --- a/third_party/unrar/src/errhnd.hpp |
| +++ b/third_party/unrar/src/errhnd.hpp |
| @@ -21,13 +21,12 @@ enum RAR_EXIT // RAR exit code. |
| class ErrorHandler |
| { |
| private: |
| - RAR_EXIT ExitCode; |
| - uint ErrCount; |
| - bool EnableBreak; |
| - bool Silent; |
| - bool DisableShutdown; // Shutdown is not suitable after last error. |
| + RAR_EXIT ExitCode = RARX_SUCCESS; |
| + uint ErrCount = 0; |
| + bool EnableBreak = true; |
| + bool Silent = false; |
| + bool DisableShutdown = false; // Shutdown is not suitable after last error. |
| public: |
| - ErrorHandler(); |
| void Clean(); |
| void MemoryError(); |
| void OpenError(const wchar *FileName); |
| @@ -62,8 +61,8 @@ class ErrorHandler |
| void SetSystemErrorCode(int Code); |
| bool IsShutdownEnabled() {return !DisableShutdown;} |
| |
| - bool UserBreak; // Ctrl+Break is pressed. |
| - bool MainExit; // main() is completed. |
| + bool UserBreak = false; // Ctrl+Break is pressed. |
| + bool MainExit = false; // main() is completed. |
| }; |
| |
| |
| diff --git a/third_party/unrar/src/file.cpp b/third_party/unrar/src/file.cpp |
| index 4ca83ad1ee6f..5188dbff715c 100644 |
| --- a/third_party/unrar/src/file.cpp |
| +++ b/third_party/unrar/src/file.cpp |
| @@ -51,6 +51,11 @@ bool File::Open(const wchar *Name,uint Mode) |
| bool UpdateMode=(Mode & FMF_UPDATE)!=0; |
| bool WriteMode=(Mode & FMF_WRITE)!=0; |
| #ifdef _WIN_ALL |
| +#if defined(CHROMIUM_UNRAR) |
| + // Do not open a file handle since the sandbox doesn't allow it. Use the |
| + // handle provided by the caller. |
| + hNewFile = hOpenFile; |
| +#else |
| uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ; |
| if (UpdateMode) |
| Access|=GENERIC_WRITE; |
| @@ -89,6 +94,14 @@ bool File::Open(const wchar *Name,uint Mode) |
| if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND) |
| ErrorType=FILE_NOTFOUND; |
| |
| +#endif // defined(CHROMIUM_UNRAR) |
| + |
| +#else |
| + |
| +#if defined(CHROMIUM_UNRAR) |
| + // Do not open a file handle since the sandbox doesn't allow it. Use the |
| + // handle provided by the caller. |
| + int handle = hOpenFile; |
| #else |
| int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY); |
| #ifdef O_BINARY |
| @@ -99,8 +112,9 @@ bool File::Open(const wchar *Name,uint Mode) |
| #endif |
| char NameA[NM]; |
| WideToChar(Name,NameA,ASIZE(NameA)); |
| - |
| int handle=open(NameA,flags); |
| +#endif // defined(CHROMIUM_UNRAR) |
| + |
| #ifdef LOCK_EX |
| |
| #ifdef _OSF_SOURCE |
| @@ -230,6 +244,8 @@ bool File::Close() |
| { |
| if (!SkipClose) |
| { |
| +#if !defined(CHROMIUM_UNRAR) |
| +// unrar should not close the file handle since it wasn't opened by unrar. |
| #ifdef _WIN_ALL |
| // We use the standard system handle for stdout in Windows |
| // and it must not be closed here. |
| @@ -242,6 +258,7 @@ bool File::Close() |
| Success=fclose(hFile)!=EOF; |
| #endif |
| #endif |
| +#endif // defined(CHROMIUM_UNRAR) |
| } |
| hFile=FILE_BAD_HANDLE; |
| } |
| @@ -735,3 +752,9 @@ int64 File::Copy(File &Dest,int64 Length) |
| return CopySize; |
| } |
| #endif |
| + |
| +#if defined(CHROMIUM_UNRAR) |
| +void File::SetFileHandle(FileHandle hF) { |
| + hOpenFile = hF; |
| +} |
| +#endif // defined(CHROMIUM_UNRAR) |
| diff --git a/third_party/unrar/src/file.hpp b/third_party/unrar/src/file.hpp |
| index 20734e28f62d..dd5cfecfbee9 100644 |
| --- a/third_party/unrar/src/file.hpp |
| +++ b/third_party/unrar/src/file.hpp |
| @@ -68,6 +68,10 @@ class File |
| wchar FileName[NM]; |
| |
| FILE_ERRORTYPE ErrorType; |
| + |
| +#if defined(CHROMIUM_UNRAR) |
| + FileHandle hOpenFile; |
| +#endif // defined(CHROMIUM_UNRAR) |
| public: |
| File(); |
| virtual ~File(); |
| @@ -111,6 +115,14 @@ class File |
| #ifdef _WIN_ALL |
| void RemoveSequentialFlag() {NoSequentialRead=true;} |
| #endif |
| + |
| +#if defined(CHROMIUM_UNRAR) |
| + // Since unrar runs in a sandbox, it doesn't have the permission to open |
| + // files on the filesystem. Instead, the caller opens the file and passes |
| + // the file handle to unrar. This handle is then used to read the file. |
| + void SetFileHandle(FileHandle file); |
| +#endif // defined(CHROMIUM_UNRAR) |
| + |
| #ifdef _UNIX |
| int GetFD() |
| { |
| diff --git a/third_party/unrar/src/isnt.cpp b/third_party/unrar/src/isnt.cpp |
| index 6fadec049fe4..d30adf550925 100644 |
| --- a/third_party/unrar/src/isnt.cpp |
| +++ b/third_party/unrar/src/isnt.cpp |
| @@ -1,24 +1,18 @@ |
| #include "rar.hpp" |
| |
| #ifdef _WIN_ALL |
| +#include "versionhelpers.h" |
| + |
| DWORD WinNT() |
| { |
| - static int dwPlatformId=-1; |
| - static DWORD dwMajorVersion,dwMinorVersion; |
| - if (dwPlatformId==-1) |
| - { |
| - OSVERSIONINFO WinVer; |
| - WinVer.dwOSVersionInfoSize=sizeof(WinVer); |
| - GetVersionEx(&WinVer); |
| - dwPlatformId=WinVer.dwPlatformId; |
| - dwMajorVersion=WinVer.dwMajorVersion; |
| - dwMinorVersion=WinVer.dwMinorVersion; |
| - } |
| - DWORD Result=0; |
| - if (dwPlatformId==VER_PLATFORM_WIN32_NT) |
| - Result=dwMajorVersion*0x100+dwMinorVersion; |
| - |
| - |
| - return Result; |
| + if (!IsWindowsXPOrGreater()) |
| + return WNT_NONE; |
| + if (!IsWindowsVistaOrGreater()) |
| + return WNT_WXP; |
| + if (!IsWindows7OrGreater()) return WNT_VISTA; |
| + if (!IsWindows8OrGreater()) return WNT_W7; |
| + if (!IsWindows8Point1OrGreater()) return WNT_W8; |
| + if (!IsWindows10OrGreater()) return WNT_W81; |
| + return WNT_W10; |
| } |
| #endif |
| diff --git a/third_party/unrar/src/isnt.hpp b/third_party/unrar/src/isnt.hpp |
| index 877d8801257a..a02174447e29 100644 |
| --- a/third_party/unrar/src/isnt.hpp |
| +++ b/third_party/unrar/src/isnt.hpp |
| @@ -1,6 +1,8 @@ |
| #ifndef _RAR_ISNT_ |
| #define _RAR_ISNT_ |
| |
| +#include "windows.h" |
| + |
| enum WINNT_VERSION { |
| WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500, |
| WNT_WXP=0x0501,WNT_W2003=0x0502,WNT_VISTA=0x0600,WNT_W7=0x0601, |
| diff --git a/third_party/unrar/src/model.cpp b/third_party/unrar/src/model.cpp |
| index e91b44070e35..6c5c44384ccf 100644 |
| --- a/third_party/unrar/src/model.cpp |
| +++ b/third_party/unrar/src/model.cpp |
| @@ -43,13 +43,27 @@ void ModelPPM::RestartModelRare() |
| InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1; |
| MinContext = MaxContext = (RARPPM_CONTEXT*) SubAlloc.AllocContext(); |
| if (MinContext == NULL) |
| + { |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(0); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + } |
| + |
| MinContext->Suffix=NULL; |
| OrderFall=MaxOrder; |
| MinContext->U.SummFreq=(MinContext->NumStats=256)+1; |
| FoundState=MinContext->U.Stats=(RARPPM_STATE*)SubAlloc.AllocUnits(256/2); |
| if (FoundState == NULL) |
| + { |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(0); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + } |
| + |
| for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++) |
| { |
| MinContext->U.Stats[i].Symbol=i; |
| diff --git a/third_party/unrar/src/os.hpp b/third_party/unrar/src/os.hpp |
| index f235f625aef8..19bd6703d8d2 100644 |
| --- a/third_party/unrar/src/os.hpp |
| +++ b/third_party/unrar/src/os.hpp |
| @@ -22,18 +22,25 @@ |
| |
| #ifdef _WIN_ALL |
| |
| -#define STRICT |
| +#ifndef STRICT |
| +#define STRICT 1 |
| +#endif |
| + |
| +#if !defined(CHROMIUM_UNRAR) |
| #define UNICODE |
| #undef WINVER |
| #undef _WIN32_WINNT |
| #define WINVER 0x0501 |
| #define _WIN32_WINNT 0x0501 |
| +#endif // CHROMIUM_UNRAR |
| |
| -#if !defined(ZIPSFX) |
| +#if !defined(ZIPSFX) && !defined(CHROMIUM_UNRAR) |
| #define RAR_SMP |
| #endif |
| |
| +#if !defined(CHROMIUM_UNRAR) |
| #define WIN32_LEAN_AND_MEAN |
| +#endif // CHROMIUM_UNRAR |
| |
| #include <windows.h> |
| #include <prsht.h> |
| @@ -65,8 +72,11 @@ |
| #include <direct.h> |
| #include <intrin.h> |
| |
| +#if !defined(CHROMIUM_UNRAR) |
| #define USE_SSE |
| #define SSE_ALIGNMENT 16 |
| +#endif // CHROMIUM_UNRAR |
| + |
| #else |
| #include <dirent.h> |
| #endif // _MSC_VER |
| diff --git a/third_party/unrar/src/threadmisc.cpp b/third_party/unrar/src/threadmisc.cpp |
| index 4ad5af2e5681..9dfd2b9bc301 100644 |
| --- a/third_party/unrar/src/threadmisc.cpp |
| +++ b/third_party/unrar/src/threadmisc.cpp |
| @@ -43,17 +43,22 @@ static inline void CriticalSectionEnd(CRITSECT_HANDLE *CritSection) |
| } |
| |
| |
| -static struct GlobalPoolCreateSync |
| +struct GlobalPoolCreateSync |
| { |
| CRITSECT_HANDLE CritSection; |
| GlobalPoolCreateSync() { CriticalSectionCreate(&CritSection); } |
| ~GlobalPoolCreateSync() { CriticalSectionDelete(&CritSection); } |
| -} PoolCreateSync; |
| +}; |
| + |
| +static GlobalPoolCreateSync& GetPoolCreateSync() { |
| + static GlobalPoolCreateSync PoolCreateSync; |
| + return PoolCreateSync; |
| +} |
| |
| |
| ThreadPool* CreateThreadPool() |
| { |
| - CriticalSectionStart(&PoolCreateSync.CritSection); |
| + CriticalSectionStart(&(GetPoolCreateSync().CritSection)); |
| |
| if (GlobalPoolUseCount++ == 0) |
| GlobalPool=new ThreadPool(MaxPoolThreads); |
| @@ -66,11 +71,11 @@ ThreadPool* CreateThreadPool() |
| if (GlobalPoolUseCount > 1) |
| { |
| ThreadPool *Pool = new ThreadPool(MaxPoolThreads); |
| - CriticalSectionEnd(&PoolCreateSync.CritSection); |
| + CriticalSectionEnd(&(GetPoolCreateSync().CritSection)); |
| return Pool; |
| } |
| |
| - CriticalSectionEnd(&PoolCreateSync.CritSection); |
| + CriticalSectionEnd(&(GetPoolCreateSync().CritSection)); |
| return GlobalPool; |
| } |
| |
| @@ -79,7 +84,7 @@ void DestroyThreadPool(ThreadPool *Pool) |
| { |
| if (Pool!=NULL) |
| { |
| - CriticalSectionStart(&PoolCreateSync.CritSection); |
| + CriticalSectionStart(&(GetPoolCreateSync().CritSection)); |
| |
| if (Pool==GlobalPool && GlobalPoolUseCount > 0 && --GlobalPoolUseCount == 0) |
| delete GlobalPool; |
| @@ -89,7 +94,7 @@ void DestroyThreadPool(ThreadPool *Pool) |
| if (Pool!=GlobalPool) |
| delete Pool; |
| |
| - CriticalSectionEnd(&PoolCreateSync.CritSection); |
| + CriticalSectionEnd(&(GetPoolCreateSync().CritSection)); |
| } |
| } |
| |
| diff --git a/third_party/unrar/src/unicode.cpp b/third_party/unrar/src/unicode.cpp |
| index 8d01e73eb1a0..858f68e4a09b 100644 |
| --- a/third_party/unrar/src/unicode.cpp |
| +++ b/third_party/unrar/src/unicode.cpp |
| @@ -1,7 +1,7 @@ |
| #include "rar.hpp" |
| #define MBFUNCTIONS |
| |
| -#if defined(_UNIX) && defined(MBFUNCTIONS) |
| +#if !defined(_WIN_ALL) && !defined(_APPLE) && defined(_UNIX) && defined(MBFUNCTIONS) |
| |
| static bool WideToCharMap(const wchar *Src,char *Dest,size_t DestSize,bool &Success); |
| static void CharToWideMap(const char *Src,wchar *Dest,size_t DestSize,bool &Success); |
| @@ -30,7 +30,7 @@ bool WideToChar(const wchar *Src,char *Dest,size_t DestSize) |
| #elif defined(_APPLE) |
| WideToUtf(Src,Dest,DestSize); |
| |
| -#elif defined(MBFUNCTIONS) |
| +#elif defined(_UNIX) && defined(MBFUNCTIONS) |
| if (!WideToCharMap(Src,Dest,DestSize,RetCode)) |
| { |
| mbstate_t ps; // Use thread safe external state based functions. |
| @@ -95,7 +95,7 @@ bool CharToWide(const char *Src,wchar *Dest,size_t DestSize) |
| #elif defined(_APPLE) |
| UtfToWide(Src,Dest,DestSize); |
| |
| -#elif defined(MBFUNCTIONS) |
| +#elif defined(_UNIX) && defined(MBFUNCTIONS) |
| mbstate_t ps; |
| memset (&ps, 0, sizeof(ps)); |
| const char *SrcParam=Src; // mbsrtowcs can change the pointer. |
| @@ -128,7 +128,7 @@ bool CharToWide(const char *Src,wchar *Dest,size_t DestSize) |
| } |
| |
| |
| -#if defined(_UNIX) && defined(MBFUNCTIONS) |
| +#if !defined(_WIN_ALL) && !defined(_APPLE) && defined(_UNIX) && defined(MBFUNCTIONS) |
| // Convert and restore mapped inconvertible Unicode characters. |
| // We use it for extended ASCII names in Unix. |
| bool WideToCharMap(const wchar *Src,char *Dest,size_t DestSize,bool &Success) |
| @@ -172,7 +172,7 @@ bool WideToCharMap(const wchar *Src,char *Dest,size_t DestSize,bool &Success) |
| #endif |
| |
| |
| -#if defined(_UNIX) && defined(MBFUNCTIONS) |
| +#if !defined(_WIN_ALL) && !defined(_APPLE) && defined(_UNIX) && defined(MBFUNCTIONS) |
| // Convert and map inconvertible Unicode characters. |
| // We use it for extended ASCII names in Unix. |
| void CharToWideMap(const char *Src,wchar *Dest,size_t DestSize,bool &Success) |
| diff --git a/third_party/unrar/src/unpack.cpp b/third_party/unrar/src/unpack.cpp |
| index 1cda19c44501..ca3c52ea792b 100644 |
| --- a/third_party/unrar/src/unpack.cpp |
| +++ b/third_party/unrar/src/unpack.cpp |
| @@ -1,3 +1,9 @@ |
| +// NOTE(vakh): The process.h file needs to be included first because "rar.hpp" |
| +// defines certain macros that cause symbol redefinition errors |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| +#include "base/process/memory.h" |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + |
| #include "rar.hpp" |
| |
| #include "coder.cpp" |
| @@ -89,7 +95,13 @@ void Unpack::Init(size_t WinSize,bool Solid) |
| |
| // We do not handle growth for existing fragmented window. |
| if (Grow && Fragmented) |
| + { |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(0); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + } |
| |
| byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize); |
| |
| @@ -99,7 +111,11 @@ void Unpack::Init(size_t WinSize,bool Solid) |
| { |
| // We do not support growth for new fragmented window. |
| // Also exclude RAR4 and small dictionaries. |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(WinSize); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| } |
| else |
| { |
| diff --git a/third_party/unrar/src/unpack50frag.cpp b/third_party/unrar/src/unpack50frag.cpp |
| index 3c008ff24539..16d5b1c3d5ef 100644 |
| --- a/third_party/unrar/src/unpack50frag.cpp |
| +++ b/third_party/unrar/src/unpack50frag.cpp |
| @@ -46,8 +46,14 @@ void FragmentedWindow::Init(size_t WinSize) |
| break; |
| Size-=Size/32; |
| } |
| - if (NewMem==NULL) |
| + if (NewMem == NULL) |
| + { |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(Size); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + } |
| |
| // Clean the window to generate the same output when unpacking corrupt |
| // RAR files, which may access to unused areas of sliding dictionary. |
| @@ -58,8 +64,14 @@ void FragmentedWindow::Init(size_t WinSize) |
| MemSize[BlockNum]=TotalSize; |
| BlockNum++; |
| } |
| - if (TotalSize<WinSize) // Not found enough free blocks. |
| + if (TotalSize < WinSize) // Not found enough free blocks. |
| + { |
| +#if defined(UNRAR_NO_EXCEPTIONS) |
| + base::TerminateBecauseOutOfMemory(WinSize); |
| +#else |
| throw std::bad_alloc(); |
| +#endif // defined(UNRAR_NO_EXCEPTIONS) |
| + } |
| } |
| |
| |
| diff --git a/third_party/unrar/src/unrar_wrapper.h b/third_party/unrar/src/unrar_wrapper.h |
| new file mode 100644 |
| index 000000000000..b19759da6f6e |
| --- /dev/null |
| +++ b/third_party/unrar/src/unrar_wrapper.h |
| @@ -0,0 +1,15 @@ |
| +// Copyright 2018 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef THIRD_PARTY_UNRAR_SRC_UNRAR_WRAPPER_H_ |
| +#define THIRD_PARTY_UNRAR_SRC_UNRAR_WRAPPER_H_ |
| + |
| +#include "rar.hpp" |
| + |
| +namespace third_party_unrar { |
| +using ::Archive; |
| +static const int kUnrarEndarcHead = ::HEAD_ENDARC; |
| +} // namespace third_party_unrar |
| + |
| +#endif // THIRD_PARTY_UNRAR_SRC_UNRAR_WRAPPER_H_ |