std::string_view 的使用
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <system_error>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <string_view>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
@@ -20,19 +21,19 @@ namespace {
|
||||
|
||||
constexpr std::size_t kArchiveBlockSize = 64 * 1024;
|
||||
|
||||
[[noreturn]] void throw_invalid_archive(const std::string &reason) {
|
||||
throw Invalid_Archive_Error("invalid upgrade archive: " + reason);
|
||||
[[noreturn]] void throw_invalid_archive(std::string_view reason) {
|
||||
throw Invalid_Archive_Error("invalid upgrade archive: " + std::string(reason));
|
||||
}
|
||||
|
||||
std::string archive_error_text(archive *a, const std::string &stage) {
|
||||
std::string archive_error_text(archive *a, std::string_view stage) {
|
||||
const char *err = archive_error_string(a);
|
||||
if (err == nullptr || *err == '\0') {
|
||||
return stage;
|
||||
return std::string(stage);
|
||||
}
|
||||
return stage + ": " + err;
|
||||
return std::string(stage) + ": " + err;
|
||||
}
|
||||
|
||||
void require_archive_ok(archive *a, int code, const std::string &stage) {
|
||||
void require_archive_ok(archive *a, int code, std::string_view stage) {
|
||||
if (code != ARCHIVE_OK) {
|
||||
throw std::runtime_error(archive_error_text(a, stage));
|
||||
}
|
||||
@@ -57,7 +58,7 @@ bool path_is_within(const fs::path &base, const fs::path &target) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string normalize_archive_path(const std::string &raw,
|
||||
std::string normalize_archive_path(std::string_view raw,
|
||||
bool allow_empty = false) {
|
||||
if (raw.empty()) {
|
||||
if (allow_empty)
|
||||
@@ -66,7 +67,7 @@ std::string normalize_archive_path(const std::string &raw,
|
||||
}
|
||||
if (raw.front() == '/' || raw.find('\\') != std::string::npos ||
|
||||
raw.find(':') != std::string::npos) {
|
||||
throw_invalid_archive("unsafe entry path: " + raw);
|
||||
throw_invalid_archive("unsafe entry path: " + std::string(raw));
|
||||
}
|
||||
|
||||
std::string normalized;
|
||||
@@ -74,9 +75,9 @@ std::string normalize_archive_path(const std::string &raw,
|
||||
while (start < raw.size()) {
|
||||
const std::size_t slash = raw.find('/', start);
|
||||
const std::size_t end = slash == std::string::npos ? raw.size() : slash;
|
||||
const std::string component = raw.substr(start, end - start);
|
||||
const std::string component(raw.substr(start, end - start));
|
||||
if (component.empty() || component == "." || component == "..") {
|
||||
throw_invalid_archive("unsafe entry path: " + raw);
|
||||
throw_invalid_archive("unsafe entry path: " + std::string(raw));
|
||||
}
|
||||
if (!normalized.empty())
|
||||
normalized.push_back('/');
|
||||
@@ -111,13 +112,13 @@ bool is_regular_entry(archive_entry *entry) {
|
||||
}
|
||||
|
||||
void reject_unsupported_entry_type(archive_entry *entry,
|
||||
const std::string &path) {
|
||||
std::string_view path) {
|
||||
const auto type = archive_entry_filetype(entry);
|
||||
if (type == AE_IFLNK) {
|
||||
throw_invalid_archive("symbolic link is not allowed: " + path);
|
||||
throw_invalid_archive("symbolic link is not allowed: " + std::string(path));
|
||||
}
|
||||
if (type != AE_IFDIR && type != AE_IFREG && type != 0) {
|
||||
throw_invalid_archive("special file is not allowed: " + path);
|
||||
throw_invalid_archive("special file is not allowed: " + std::string(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +129,7 @@ void setup_archive_reader(archive *a) {
|
||||
"archive_read_support_format_all failed");
|
||||
}
|
||||
|
||||
void consume_entry_data_for_validation(archive *a, const std::string &path,
|
||||
void consume_entry_data_for_validation(archive *a, std::string_view path,
|
||||
const Archive_Layout_Rules &rules,
|
||||
std::uint64_t &total_uncompressed_size) {
|
||||
std::uint64_t entry_size = 0;
|
||||
@@ -143,12 +144,12 @@ void consume_entry_data_for_validation(archive *a, const std::string &path,
|
||||
}
|
||||
if (result != ARCHIVE_OK) {
|
||||
throw_invalid_archive(
|
||||
archive_error_text(a, "cannot read entry: " + path));
|
||||
archive_error_text(a, "cannot read entry: " + std::string(path)));
|
||||
}
|
||||
|
||||
if (block_size > rules.max_entry_uncompressed_size ||
|
||||
entry_size > rules.max_entry_uncompressed_size - block_size) {
|
||||
throw_invalid_archive("entry size exceeds limit: " + path);
|
||||
throw_invalid_archive("entry size exceeds limit: " + std::string(path));
|
||||
}
|
||||
if (block_size > rules.max_total_uncompressed_size ||
|
||||
total_uncompressed_size >
|
||||
@@ -162,18 +163,18 @@ void consume_entry_data_for_validation(archive *a, const std::string &path,
|
||||
}
|
||||
|
||||
void consume_entry_data_for_validation(archive *a, archive_entry *entry,
|
||||
const std::string &path,
|
||||
std::string_view path,
|
||||
const Archive_Layout_Rules &rules,
|
||||
std::uint64_t &total_uncompressed_size) {
|
||||
if (archive_entry_size_is_set(entry)) {
|
||||
const auto expected_size = archive_entry_size(entry);
|
||||
if (expected_size < 0) {
|
||||
throw_invalid_archive("negative entry size: " + path);
|
||||
throw_invalid_archive("negative entry size: " + std::string(path));
|
||||
}
|
||||
const auto size = static_cast<std::uint64_t>(expected_size);
|
||||
if (size > rules.max_entry_uncompressed_size ||
|
||||
size > rules.max_total_uncompressed_size) {
|
||||
throw_invalid_archive("entry size exceeds limit: " + path);
|
||||
throw_invalid_archive("entry size exceeds limit: " + std::string(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +232,7 @@ Read_Archive_Ptr make_archive_reader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
bool is_safe_archive_name_token(const std::string &value) {
|
||||
bool is_safe_archive_name_token(std::string_view value) {
|
||||
if (value.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user