Commit 34eedbc8 authored by Varun Khaneja's avatar Varun Khaneja Committed by Commit Bot

Use unrar to extract some metadata about files the .rar file.

- Uses the the Archive API to iterative over the files
  contained inside the downloaded .rar file.
- Identify if the .rar file contains any executables.
- Identify if the .rar file contains any archives.

This information isn't currently used to populate the CSBRR ping
sent to Safe Browsing. That's work for a follow-up CL.

All this is behind the flag: InspectDownloadedRarFiles

Note: This CL sends a fd/handle to the unrar library since code
running inside the sandbox can't open/create files.

Change-Id: Ie5d30040f51f59854d4a041652d171d704f4df78
Bug: 750327
Reviewed-on: https://chromium-review.googlesource.com/947664
Commit-Queue: Varun Khaneja <vakh@chromium.org>
Reviewed-by: default avatarNathan Parker <nparker@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@chromium.org>
Reviewed-by: default avatarLuke Z <lpz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563016}
parent 024402fa
...@@ -13,16 +13,74 @@ proto_library("proto") { ...@@ -13,16 +13,74 @@ proto_library("proto") {
] ]
} }
source_set("safe_browsing") { source_set("file_type_policies") {
sources = [ sources = [
"file_type_policies.cc", "file_type_policies.cc",
"file_type_policies.h", "file_type_policies.h",
] ]
if (safe_browsing_mode == 1) { deps = [
sources += [ ":proto",
"//base",
"//chrome/browser:resources",
"//ui/base",
]
}
if (safe_browsing_mode == 1) {
source_set("archive_analyzer_results") {
sources = [
"archive_analyzer_results.cc", "archive_analyzer_results.cc",
"archive_analyzer_results.h", "archive_analyzer_results.h",
]
deps = [
"//base",
]
public_deps = [
"//components/safe_browsing:csd_proto",
]
}
source_set("rar_analyzer") {
sources = [
"rar_analyzer.cc",
"rar_analyzer.h",
]
deps = [
":archive_analyzer_results",
":file_type_policies",
"//base",
"//third_party/unrar:unrar",
]
defines = [
"_FILE_OFFSET_BITS=64",
"LARGEFILE_SOURCE",
"RAR_SMP",
"SILENT",
# The following is set to disable certain macro definitions in the unrar
# source code.
"CHROMIUM_UNRAR",
# Disables exceptions in unrar, replaces them with process termination.
"UNRAR_NO_EXCEPTIONS",
]
public_deps = [
"//components/safe_browsing:csd_proto",
]
}
}
source_set("safe_browsing") {
deps = [
":file_type_policies",
]
if (safe_browsing_mode == 1) {
sources = [
"binary_feature_extractor.cc", "binary_feature_extractor.cc",
"binary_feature_extractor.h", "binary_feature_extractor.h",
"binary_feature_extractor_mac.cc", "binary_feature_extractor_mac.cc",
...@@ -44,17 +102,20 @@ source_set("safe_browsing") { ...@@ -44,17 +102,20 @@ source_set("safe_browsing") {
if (is_posix) { if (is_posix) {
sources += [ "binary_feature_extractor_posix.cc" ] sources += [ "binary_feature_extractor_posix.cc" ]
} }
}
public_deps = [ deps += [
"//base:i18n", ":archive_analyzer_results",
"//chrome/browser:resources", ":rar_analyzer",
"//chrome/common:mojo_bindings", ]
"//chrome/common/safe_browsing:proto",
"//components/safe_browsing:csd_proto", public_deps = [
"//crypto", ":proto",
"//ipc", "//base:i18n",
"//third_party/zlib/google:zip", "//chrome/common:mojo_bindings",
"//ui/base", "//components/safe_browsing:csd_proto",
] "//crypto",
"//ipc",
"//third_party/zlib/google:zip",
]
}
} }
include_rules = [ include_rules = [
"+third_party/protobuf", "+third_party/protobuf",
"+third_party/unrar",
"+third_party/zlib", "+third_party/zlib",
] ]
// 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.
#include "chrome/common/safe_browsing/rar_analyzer.h"
#include <memory>
#include <string>
#include "build/build_config.h"
#include "chrome/common/safe_browsing/archive_analyzer_results.h"
#include "chrome/common/safe_browsing/file_type_policies.h"
#include "third_party/unrar/src/unrar_wrapper.h"
namespace safe_browsing {
namespace rar_analyzer {
void AnalyzeRarFile(base::File rar_file,
const base::FilePath& rar_file_path,
ArchiveAnalyzerResults* results) {
auto archive = std::make_unique<third_party_unrar::Archive>();
archive->SetFileHandle(rar_file.GetPlatformFile());
std::wstring wide_rar_file_path(rar_file_path.value().begin(),
rar_file_path.value().end());
if (!archive->Open(wide_rar_file_path.c_str())) {
results->success = false;
// TODO(vakh): Log UMA here.
VLOG(1) << __FUNCTION__
<< ": Unable to open rar_file: " << rar_file.GetPlatformFile();
return;
}
if (!archive->IsArchive(/*EnableBroken=*/true)) {
// TODO(vakh): Log UMA here.
results->success = false;
VLOG(1) << __FUNCTION__
<< ": !IsArchive: rar_file: " << rar_file.GetPlatformFile();
return;
}
// TODO(vakh): Log UMA here.
results->success = true;
std::set<base::FilePath> archived_archive_filenames;
for (archive->ViewComment();
archive->ReadHeader() > 0 &&
archive->GetHeaderType() != third_party_unrar::kUnrarEndarcHead;
archive->SeekToNext()) {
VLOG(2) << __FUNCTION__ << ": FileName: " << archive->FileHead.FileName;
std::wstring wide_filename(archive->FileHead.FileName);
#if defined(OS_WIN)
base::FilePath file_path(wide_filename);
#else
std::string filename(wide_filename.begin(), wide_filename.end());
base::FilePath file_path(filename);
#endif // OS_WIN
VLOG(2) << __FUNCTION__ << ": file_path: " << file_path.value().c_str();
bool is_executable =
FileTypePolicies::GetInstance()->IsCheckedBinaryFile(file_path);
VLOG(2) << __FUNCTION__ << ": is_executable: " << is_executable;
results->has_executable |= is_executable;
bool is_archive = FileTypePolicies::GetInstance()->IsArchiveFile(file_path);
VLOG(2) << __FUNCTION__ << ": is_archive: " << is_archive;
results->has_archive |= is_archive;
if (is_archive) {
archived_archive_filenames.insert(file_path.BaseName());
}
results->archived_archive_filenames.assign(
archived_archive_filenames.begin(), archived_archive_filenames.end());
}
}
} // namespace rar_analyzer
} // namespace safe_browsing
// 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.
//
// This file contains the rar file analysis implementation for download
// protection, which runs in a sandbox. The reason for running in a sandbox is
// to isolate the browser and other renderer processes from any vulnerabilities
// that the attacker-controlled download file may try to exploit.
//
// Here's the call flow for inspecting .rar files upon download:
// 1. File is downloaded.
// 2. |CheckClientDownloadRequest::AnalyzeFile()| is called to analyze the Safe
// Browsing reputation of the downloaded file.
// 3. It calls |CheckClientDownloadRequest::StartExtractRarFeatures()|, which
// creates an instance of |SandboxedRarAnalyzer|, and calls |Start()|.
// 4. |SandboxedRarAnalyzer::Start()| leads to a mojo call to
// |SafeArchiveAnalyzer::AnalyzeRarFile()| in a sandbox.
// 5. Finally, |SafeArchiveAnalyzer::AnalyzeRarFile()| calls |AnalyzeRarFile()|
// defined in this file to actually inspect the file.
#ifndef CHROME_COMMON_SAFE_BROWSING_RAR_ANALYZER_H_
#define CHROME_COMMON_SAFE_BROWSING_RAR_ANALYZER_H_
#include "base/files/file.h"
#include "base/files/file_path.h"
namespace safe_browsing {
struct ArchiveAnalyzerResults;
namespace rar_analyzer {
// |rar_file| is a platform-agnostic handle to the file. Since |AnalyzeRarFile|
// runs inside a sandbox, it isn't allowed to open file handles. So the file is
// opened in |SandboxedRarAnalyzer|, which runs in the browser process, and the
// handle is passed here. |rar_file_path| is the path to the same file. It is
// required only because the unrar library expects it to be used with a
// filename. The function populates the various fields in |results| based on the
// results of parsing the rar file.
// If the parsing fails for any reason, including crashing the sandbox process,
// the browser process considers the file safe.
void AnalyzeRarFile(base::File rar_file,
const base::FilePath& rar_file_path,
ArchiveAnalyzerResults* results);
} // namespace rar_analyzer
} // namespace safe_browsing
#endif // CHROME_COMMON_SAFE_BROWSING_RAR_ANALYZER_H_
...@@ -26,11 +26,6 @@ source_set("cpp") { ...@@ -26,11 +26,6 @@ source_set("cpp") {
] ]
} }
#TODO(crbug/750327): This dependency is here temporarily.
deps = [
"//third_party/unrar:unrar",
]
public_deps += [ "//chrome/common/safe_browsing" ] public_deps += [ "//chrome/common/safe_browsing" ]
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/files/file_util.h" #include "base/files/file_util.h"
#include "base/process/process_handle.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/task_scheduler/post_task.h" #include "base/task_scheduler/post_task.h"
#include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h"
...@@ -17,10 +18,10 @@ ...@@ -17,10 +18,10 @@
#include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/connector.h"
SandboxedRarAnalyzer::SandboxedRarAnalyzer( SandboxedRarAnalyzer::SandboxedRarAnalyzer(
const base::FilePath& rar_file, const base::FilePath& rar_file_path,
const ResultCallback& callback, const ResultCallback& callback,
service_manager::Connector* connector) service_manager::Connector* connector)
: file_path_(rar_file), callback_(callback), connector_(connector) { : file_path_(rar_file_path), callback_(callback), connector_(connector) {
DCHECK(callback); DCHECK(callback);
DCHECK(!file_path_.value().empty()); DCHECK(!file_path_.value().empty());
} }
...@@ -37,7 +38,7 @@ void SandboxedRarAnalyzer::Start() { ...@@ -37,7 +38,7 @@ void SandboxedRarAnalyzer::Start() {
SandboxedRarAnalyzer::~SandboxedRarAnalyzer() = default; SandboxedRarAnalyzer::~SandboxedRarAnalyzer() = default;
void SandboxedRarAnalyzer::AnalyzeFile() { void SandboxedRarAnalyzer::AnalyzeFile(base::File file) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
DCHECK(!analyzer_ptr_); DCHECK(!analyzer_ptr_);
DCHECK(!file_path_.value().empty()); DCHECK(!file_path_.value().empty());
...@@ -48,34 +49,41 @@ void SandboxedRarAnalyzer::AnalyzeFile() { ...@@ -48,34 +49,41 @@ void SandboxedRarAnalyzer::AnalyzeFile() {
&SandboxedRarAnalyzer::AnalyzeFileDone, base::Unretained(this), &SandboxedRarAnalyzer::AnalyzeFileDone, base::Unretained(this),
safe_browsing::ArchiveAnalyzerResults())); safe_browsing::ArchiveAnalyzerResults()));
analyzer_ptr_->AnalyzeRarFile( analyzer_ptr_->AnalyzeRarFile(
file_path_, base::BindOnce(&SandboxedRarAnalyzer::AnalyzeFileDone, this)); std::move(file), file_path_,
base::BindOnce(&SandboxedRarAnalyzer::AnalyzeFileDone, this));
} }
void SandboxedRarAnalyzer::AnalyzeFileDone( void SandboxedRarAnalyzer::AnalyzeFileDone(
const safe_browsing::ArchiveAnalyzerResults& results) { const safe_browsing::ArchiveAnalyzerResults& results) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
analyzer_ptr_.reset(); analyzer_ptr_.reset();
callback_.Run(results); callback_.Run(results);
} }
void SandboxedRarAnalyzer::PrepareFileToAnalyze() { void SandboxedRarAnalyzer::PrepareFileToAnalyze() {
base::File file(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ); if (file_path_.value().empty()) {
// TODO(vakh): Add UMA metrics here to check how often this happens.
DLOG(ERROR) << "file_path_ empty!";
ReportFileFailure();
return;
}
base::File file(file_path_, base::File::FLAG_OPEN | base::File::FLAG_READ);
if (!file.IsValid()) { if (!file.IsValid()) {
// TODO(vakh): Add UMA metrics here to check how often this happens. // TODO(vakh): Add UMA metrics here to check how often this happens.
DLOG(ERROR) << "Could not open file: " << file_path_.value();
ReportFileFailure(); ReportFileFailure();
return; return;
} }
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, content::BrowserThread::UI, FROM_HERE,
base::BindOnce(&SandboxedRarAnalyzer::AnalyzeFile, this)); base::BindOnce(&SandboxedRarAnalyzer::AnalyzeFile, this,
std::move(file)));
} }
void SandboxedRarAnalyzer::ReportFileFailure() { void SandboxedRarAnalyzer::ReportFileFailure() {
DCHECK(!analyzer_ptr_); DCHECK(!analyzer_ptr_);
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE, content::BrowserThread::UI, FROM_HERE,
base::BindOnce(callback_, safe_browsing::ArchiveAnalyzerResults())); base::BindOnce(callback_, safe_browsing::ArchiveAnalyzerResults()));
......
...@@ -28,7 +28,7 @@ class SandboxedRarAnalyzer ...@@ -28,7 +28,7 @@ class SandboxedRarAnalyzer
using ResultCallback = base::RepeatingCallback<void( using ResultCallback = base::RepeatingCallback<void(
const safe_browsing::ArchiveAnalyzerResults&)>; const safe_browsing::ArchiveAnalyzerResults&)>;
SandboxedRarAnalyzer(const base::FilePath& rar_file, SandboxedRarAnalyzer(const base::FilePath& rar_file_path,
const ResultCallback& callback, const ResultCallback& callback,
service_manager::Connector* connector); service_manager::Connector* connector);
...@@ -50,7 +50,7 @@ class SandboxedRarAnalyzer ...@@ -50,7 +50,7 @@ class SandboxedRarAnalyzer
void ReportFileFailure(); void ReportFileFailure();
// Starts the utility process and sends it a file analyze request. // Starts the utility process and sends it a file analyze request.
void AnalyzeFile(); void AnalyzeFile(base::File file);
// The response containing the file analyze results. // The response containing the file analyze results.
void AnalyzeFileDone(const safe_browsing::ArchiveAnalyzerResults& results); void AnalyzeFileDone(const safe_browsing::ArchiveAnalyzerResults& results);
......
...@@ -26,7 +26,8 @@ interface SafeArchiveAnalyzer { ...@@ -26,7 +26,8 @@ interface SafeArchiveAnalyzer {
// Build flag FULL_SAFE_BROWSING: Analyze the |rar_file| for malicious // Build flag FULL_SAFE_BROWSING: Analyze the |rar_file| for malicious
// download protection. // download protection.
AnalyzeRarFile(mojo_base.mojom.FilePath rar_file) AnalyzeRarFile(mojo_base.mojom.File rar_file,
mojo_base.mojom.FilePath rar_file_path)
=> (SafeArchiveAnalyzerResults results); => (SafeArchiveAnalyzerResults results);
}; };
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/safe_browsing/archive_analyzer_results.h" #include "chrome/common/safe_browsing/archive_analyzer_results.h"
#include "chrome/common/safe_browsing/rar_analyzer.h"
#include "chrome/common/safe_browsing/zip_analyzer.h" #include "chrome/common/safe_browsing/zip_analyzer.h"
#include "mojo/public/cpp/bindings/strong_binding.h" #include "mojo/public/cpp/bindings/strong_binding.h"
...@@ -44,15 +45,14 @@ void SafeArchiveAnalyzer::AnalyzeDmgFile(base::File dmg_file, ...@@ -44,15 +45,14 @@ void SafeArchiveAnalyzer::AnalyzeDmgFile(base::File dmg_file,
#endif #endif
} }
void SafeArchiveAnalyzer::AnalyzeRarFile(const base::FilePath& rar_file_path, void SafeArchiveAnalyzer::AnalyzeRarFile(base::File rar_file,
const base::FilePath& rar_file_path,
AnalyzeRarFileCallback callback) { AnalyzeRarFileCallback callback) {
DCHECK(rar_file.IsValid());
DCHECK(!rar_file_path.value().empty()); DCHECK(!rar_file_path.value().empty());
safe_browsing::ArchiveAnalyzerResults results; safe_browsing::ArchiveAnalyzerResults results;
base::File file(rar_file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); safe_browsing::rar_analyzer::AnalyzeRarFile(std::move(rar_file),
if (!file.IsValid()) { rar_file_path, &results);
results.success = false;
}
// TODO(crbug/750327): Inspect |file|.
std::move(callback).Run(results); std::move(callback).Run(results);
} }
...@@ -26,7 +26,8 @@ class SafeArchiveAnalyzer : public chrome::mojom::SafeArchiveAnalyzer { ...@@ -26,7 +26,8 @@ class SafeArchiveAnalyzer : public chrome::mojom::SafeArchiveAnalyzer {
AnalyzeZipFileCallback callback) override; AnalyzeZipFileCallback callback) override;
void AnalyzeDmgFile(base::File dmg_file, void AnalyzeDmgFile(base::File dmg_file,
AnalyzeDmgFileCallback callback) override; AnalyzeDmgFileCallback callback) override;
void AnalyzeRarFile(const base::FilePath& rar_file_path, void AnalyzeRarFile(base::File rar_file,
const base::FilePath& rar_file_path,
AnalyzeRarFileCallback callback) override; AnalyzeRarFileCallback callback) override;
const std::unique_ptr<service_manager::ServiceContextRef> service_ref_; const std::unique_ptr<service_manager::ServiceContextRef> service_ref_;
......
...@@ -15,7 +15,8 @@ source_set("mac") { ...@@ -15,7 +15,8 @@ source_set("mac") {
deps = [ deps = [
":dmg_common", ":dmg_common",
"//base", "//base",
"//chrome/common", "//chrome/common/safe_browsing:archive_analyzer_results",
"//chrome/common/safe_browsing:safe_browsing",
"//components/safe_browsing:csd_proto", "//components/safe_browsing:csd_proto",
] ]
} }
......
...@@ -27,7 +27,6 @@ if (safe_browsing_mode == 1) { ...@@ -27,7 +27,6 @@ if (safe_browsing_mode == 1) {
"src/global.cpp", "src/global.cpp",
"src/hash.cpp", "src/hash.cpp",
"src/headers.cpp", "src/headers.cpp",
"src/isnt.cpp",
"src/list.cpp", "src/list.cpp",
"src/match.cpp", "src/match.cpp",
"src/options.cpp", "src/options.cpp",
...@@ -56,6 +55,9 @@ if (safe_browsing_mode == 1) { ...@@ -56,6 +55,9 @@ if (safe_browsing_mode == 1) {
"src/unpack.cpp", "src/unpack.cpp",
"src/volume.cpp", "src/volume.cpp",
] ]
if (is_win) {
sources += [ "src/isnt.cpp" ]
}
configs -= [ "//build/config/compiler:chromium_code" ] configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ]
...@@ -64,6 +66,7 @@ if (safe_browsing_mode == 1) { ...@@ -64,6 +66,7 @@ if (safe_browsing_mode == 1) {
"_FILE_OFFSET_BITS=64", "_FILE_OFFSET_BITS=64",
"LARGEFILE_SOURCE", "LARGEFILE_SOURCE",
"RAR_SMP", "RAR_SMP",
"SILENT",
# The following is set to disable certain macro definitions in the unrar # The following is set to disable certain macro definitions in the unrar
# source code. # source code.
......
...@@ -24,4 +24,6 @@ Notable changes from upstream: ...@@ -24,4 +24,6 @@ Notable changes from upstream:
- Explicit use of parentheses to fix linter errors. - Explicit use of parentheses to fix linter errors.
- Replace exceptions with terminating the current process. Guarded with the - Replace exceptions with terminating the current process. Guarded with the
macro UNRAR_NO_EXCEPTIONS. macro UNRAR_NO_EXCEPTIONS.
- Pass a file handle to the rar file, instead of trying to open the rar file
inside the unrar library code. This is done because the unrar library code
operates inside a sandbox, so it doesn't have the permissions to open files.
...@@ -51,6 +51,11 @@ bool File::Open(const wchar *Name,uint Mode) ...@@ -51,6 +51,11 @@ bool File::Open(const wchar *Name,uint Mode)
bool UpdateMode=(Mode & FMF_UPDATE)!=0; bool UpdateMode=(Mode & FMF_UPDATE)!=0;
bool WriteMode=(Mode & FMF_WRITE)!=0; bool WriteMode=(Mode & FMF_WRITE)!=0;
#ifdef _WIN_ALL #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; uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ;
if (UpdateMode) if (UpdateMode)
Access|=GENERIC_WRITE; Access|=GENERIC_WRITE;
...@@ -89,6 +94,14 @@ bool File::Open(const wchar *Name,uint Mode) ...@@ -89,6 +94,14 @@ bool File::Open(const wchar *Name,uint Mode)
if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND) if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND)
ErrorType=FILE_NOTFOUND; 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 #else
int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY); int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY);
#ifdef O_BINARY #ifdef O_BINARY
...@@ -99,8 +112,9 @@ bool File::Open(const wchar *Name,uint Mode) ...@@ -99,8 +112,9 @@ bool File::Open(const wchar *Name,uint Mode)
#endif #endif
char NameA[NM]; char NameA[NM];
WideToChar(Name,NameA,ASIZE(NameA)); WideToChar(Name,NameA,ASIZE(NameA));
int handle=open(NameA,flags); int handle=open(NameA,flags);
#endif // defined(CHROMIUM_UNRAR)
#ifdef LOCK_EX #ifdef LOCK_EX
#ifdef _OSF_SOURCE #ifdef _OSF_SOURCE
...@@ -230,6 +244,8 @@ bool File::Close() ...@@ -230,6 +244,8 @@ bool File::Close()
{ {
if (!SkipClose) if (!SkipClose)
{ {
#if !defined(CHROMIUM_UNRAR)
// unrar should not close the file handle since it wasn't opened by unrar.
#ifdef _WIN_ALL #ifdef _WIN_ALL
// We use the standard system handle for stdout in Windows // We use the standard system handle for stdout in Windows
// and it must not be closed here. // and it must not be closed here.
...@@ -242,6 +258,7 @@ bool File::Close() ...@@ -242,6 +258,7 @@ bool File::Close()
Success=fclose(hFile)!=EOF; Success=fclose(hFile)!=EOF;
#endif #endif
#endif #endif
#endif // defined(CHROMIUM_UNRAR)
} }
hFile=FILE_BAD_HANDLE; hFile=FILE_BAD_HANDLE;
} }
...@@ -735,3 +752,9 @@ int64 File::Copy(File &Dest,int64 Length) ...@@ -735,3 +752,9 @@ int64 File::Copy(File &Dest,int64 Length)
return CopySize; return CopySize;
} }
#endif #endif
#if defined(CHROMIUM_UNRAR)
void File::SetFileHandle(FileHandle hF) {
hOpenFile = hF;
}
#endif // defined(CHROMIUM_UNRAR)
...@@ -68,6 +68,10 @@ class File ...@@ -68,6 +68,10 @@ class File
wchar FileName[NM]; wchar FileName[NM];
FILE_ERRORTYPE ErrorType; FILE_ERRORTYPE ErrorType;
#if defined(CHROMIUM_UNRAR)
FileHandle hOpenFile;
#endif // defined(CHROMIUM_UNRAR)
public: public:
File(); File();
virtual ~File(); virtual ~File();
...@@ -111,6 +115,14 @@ class File ...@@ -111,6 +115,14 @@ class File
#ifdef _WIN_ALL #ifdef _WIN_ALL
void RemoveSequentialFlag() {NoSequentialRead=true;} void RemoveSequentialFlag() {NoSequentialRead=true;}
#endif #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 #ifdef _UNIX
int GetFD() int GetFD()
{ {
......
#include "isnt.hpp" #include "rar.hpp"
#ifdef _WIN_ALL #ifdef _WIN_ALL
#include "versionhelpers.h" #include "versionhelpers.h"
DWORD WinNT() DWORD WinNT()
{ {
if (!IsWinXpOrGreater()) return WNT_NONE; if (!IsWindowsXPOrGreater())
if (!IsWinVistaOrGreater()) return WNT_WXP; return WNT_NONE;
if (!IsWindowsVistaOrGreater())
return WNT_WXP;
if (!IsWindows7OrGreater()) return WNT_VISTA; if (!IsWindows7OrGreater()) return WNT_VISTA;
if (!IsWindows8OrGreater()) return WNT_W7; if (!IsWindows8OrGreater()) return WNT_W7;
if (!IsWindows8Point1OrGreater()) return WNT_W8; if (!IsWindows8Point1OrGreater()) return WNT_W8;
......
#ifndef _RAR_ISNT_ #ifndef _RAR_ISNT_
#define _RAR_ISNT_ #define _RAR_ISNT_
#ifdef _WIN_ALL #include "windows.h"
enum WINNT_VERSION { enum WINNT_VERSION {
WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500, WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500,
...@@ -12,5 +12,3 @@ enum WINNT_VERSION { ...@@ -12,5 +12,3 @@ enum WINNT_VERSION {
DWORD WinNT(); DWORD WinNT();
#endif #endif
#endif
// 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_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment