#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/download/public/common/base_file.h"
#include <memory>
#include <utility>
#include "base/containers/heap_array.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/download/public/common/download_interrupt_reasons_utils.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_stats.h"
#include "components/services/quarantine/quarantine.h"
#include "crypto/secure_hash.h"
#if BUILDFLAG(IS_ANDROID)
#include "base/android/content_uri_utils.h"
#include "components/download/internal/common/android/download_collection_bridge.h"
#endif
#define CONDITIONAL_TRACE(trace) …
namespace download {
namespace {
class FileErrorData : public base::trace_event::ConvertableToTraceFormat { … };
void InitializeFile(base::File* file, const base::FilePath& file_path) { … }
void DeleteFileWrapper(const base::FilePath& file_path) { … }
}
BaseFile::BaseFile(uint32_t download_id) : … { … }
BaseFile::~BaseFile() { … }
DownloadInterruptReason BaseFile::Initialize(
const base::FilePath& full_path,
const base::FilePath& default_directory,
base::File file,
int64_t bytes_so_far,
const std::string& hash_so_far,
std::unique_ptr<crypto::SecureHash> hash_state,
bool is_sparse_file,
int64_t* const bytes_wasted) { … }
DownloadInterruptReason BaseFile::AppendDataToFile(const char* data,
size_t data_len) { … }
DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset,
const char* data,
size_t data_len) { … }
bool BaseFile::ValidateDataInFile(int64_t offset,
const char* data,
size_t data_len) { … }
DownloadInterruptReason BaseFile::Rename(const base::FilePath& new_path) { … }
void BaseFile::Detach() { … }
void BaseFile::Cancel() { … }
std::unique_ptr<crypto::SecureHash> BaseFile::Finish() { … }
std::string BaseFile::DebugString() const { … }
DownloadInterruptReason BaseFile::CalculatePartialHash(
const std::string& hash_to_expect) { … }
DownloadInterruptReason BaseFile::Open(const std::string& hash_so_far,
int64_t* const bytes_wasted) { … }
void BaseFile::Close() { … }
void BaseFile::ClearFile() { … }
DownloadInterruptReason BaseFile::LogNetError(const char* operation,
net::Error error) { … }
DownloadInterruptReason BaseFile::LogSystemError(
const char* operation,
logging::SystemErrorCode os_error) { … }
DownloadInterruptReason BaseFile::LogInterruptReason(
const char* operation,
int os_error,
DownloadInterruptReason reason) { … }
#if BUILDFLAG(IS_ANDROID)
DownloadInterruptReason BaseFile::PublishDownload() {
Close();
base::FilePath new_path =
DownloadCollectionBridge::PublishDownload(full_path_);
if (!new_path.empty()) {
full_path_ = new_path;
return DOWNLOAD_INTERRUPT_REASON_NONE;
}
return DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
}
#endif
namespace {
DownloadInterruptReason QuarantineFileResultToReason(
quarantine::mojom::QuarantineFileResult result) { … }
}
GURL BaseFile::GetEffectiveAuthorityURL(const GURL& source_url,
const GURL& referrer_url) { … }
void BaseFile::OnFileQuarantined(
quarantine::mojom::QuarantineFileResult result) { … }
void BaseFile::OnQuarantineServiceError(const GURL& source_url,
const GURL& referrer_url) { … }
void BaseFile::AnnotateWithSourceInformation(
const std::string& client_guid,
const GURL& source_url,
const GURL& referrer_url,
mojo::PendingRemote<quarantine::mojom::Quarantine> remote_quarantine,
OnAnnotationDoneCallback on_annotation_done_callback) { … }
}