#include "third_party/lzma_sdk/google/seven_zip_reader.h"
#include <stdint.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/containers/buffer_iterator.h"
#include "base/containers/heap_array.h"
#include "base/containers/span_writer.h"
#include "base/files/memory_mapped_file.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/process/memory.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
extern "C" {
#include "third_party/lzma_sdk/C/7z.h"
#include "third_party/lzma_sdk/C/7zAlloc.h"
#include "third_party/lzma_sdk/C/7zCrc.h"
}
#if BUILDFLAG(IS_WIN)
#include <ntstatus.h>
#include <windows.h>
#endif
namespace seven_zip {
namespace internal {
namespace {
bool CopyFile(base::File& source, base::File& destination, size_t length) { … }
}
enum : uint32_t { … };
class FileSeekInStream : public ISeekInStream { … };
class SevenZipReaderImpl { … };
FileSeekInStream::FileSeekInStream() { … }
void FileSeekInStream::Initialize(base::File file) { … }
void FileSeekInStream::Close() { … }
SRes FileSeekInStream::DoRead(const ISeekInStream* p, void* buf, size_t* size) { … }
SRes FileSeekInStream::DoSeek(const ISeekInStream* p,
Int64* pos,
ESzSeek origin) { … }
SevenZipReaderImpl::SevenZipReaderImpl(
base::OnceCallback<base::File()> temp_file_request_callback)
: … { … }
SevenZipReaderImpl::~SevenZipReaderImpl() { … }
Result SevenZipReaderImpl::Initialize(base::File archive_file) { … }
EntryInfo SevenZipReaderImpl::GetEntryInfo(size_t entry_index) const { … }
bool SevenZipReaderImpl::IsDirectory(size_t entry_index) const { … }
Result SevenZipReaderImpl::ExtractFile(size_t entry_index,
base::span<uint8_t> output) { … }
Result SevenZipReaderImpl::SResToResult(SRes res) { … }
void* SevenZipReaderImpl::AllocTemp(ISzAllocPtr p, size_t size) { … }
void SevenZipReaderImpl::FreeTemp(ISzAllocPtr p, void* address) { … }
bool SevenZipReaderImpl::AreHeadersEncrypted(base::File archive_file,
base::File temp_file) { … }
Result SevenZipReaderImpl::ExtractIntoTempFile(size_t folder_index) { … }
bool SevenZipReaderImpl::IsFolderEncrypted(size_t folder_index) const { … }
#if BUILDFLAG(IS_WIN)
using NTSTATUS = LONG;
DWORD FilterPageError(const base::span<uint8_t>& mapped_file,
const base::span<uint8_t>& output,
DWORD exception_code,
const EXCEPTION_POINTERS* info,
int32_t* status) {
if (exception_code != EXCEPTION_IN_PAGE_ERROR)
return EXCEPTION_CONTINUE_SEARCH;
const EXCEPTION_RECORD* exception_record = info->ExceptionRecord;
const uint8_t* address = reinterpret_cast<const uint8_t*>(
exception_record->ExceptionInformation[1]);
if ((mapped_file.data() <= address &&
address < mapped_file.data() + mapped_file.size()) ||
(output.data() <= address && address < output.data() + output.size())) {
*status = exception_record->ExceptionInformation[2];
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
}
std::unique_ptr<SevenZipReader> SevenZipReader::Create(
base::File seven_zip_file,
Delegate& delegate) { … }
SevenZipReader::~SevenZipReader() = default;
void SevenZipReader::Extract() { … }
SevenZipReader::SevenZipReader(
std::unique_ptr<internal::SevenZipReaderImpl> impl,
Delegate& delegate)
: … { … }
bool SevenZipReader::ExtractEntry() { … }
void EnsureLzmaSdkInitialized() { … }
}