chore: modernize base::Value useage in asar/archive (#34796)

This commit is contained in:
Jeremy Rose 2022-07-05 09:35:38 -07:00 committed by GitHub
parent c418275228
commit 403bd39d05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 80 deletions

View file

@ -35,83 +35,75 @@ const char kSeparators[] = "\\/";
const char kSeparators[] = "/"; const char kSeparators[] = "/";
#endif #endif
bool GetNodeFromPath(std::string path, const base::Value::Dict* GetNodeFromPath(std::string path,
const base::DictionaryValue* root, const base::Value::Dict& root);
const base::DictionaryValue** out);
// Gets the "files" from "dir". // Gets the "files" from "dir".
bool GetFilesNode(const base::DictionaryValue* root, const base::Value::Dict* GetFilesNode(const base::Value::Dict& root,
const base::DictionaryValue* dir, const base::Value::Dict& dir) {
const base::DictionaryValue** out) {
// Test for symbol linked directory. // Test for symbol linked directory.
const std::string* link = dir->FindStringKey("link"); const std::string* link = dir.FindString("link");
if (link != nullptr) { if (link != nullptr) {
const base::DictionaryValue* linked_node = nullptr; const base::Value::Dict* linked_node = GetNodeFromPath(*link, root);
if (!GetNodeFromPath(*link, root, &linked_node)) if (!linked_node)
return false; return nullptr;
dir = linked_node; return linked_node->FindDict("files");
} }
return dir->GetDictionaryWithoutPathExpansion("files", out); return dir.FindDict("files");
} }
// Gets sub-file "name" from "dir". // Gets sub-file "name" from "dir".
bool GetChildNode(const base::DictionaryValue* root, const base::Value::Dict* GetChildNode(const base::Value::Dict& root,
const std::string& name, const std::string& name,
const base::DictionaryValue* dir, const base::Value::Dict& dir) {
const base::DictionaryValue** out) { if (name.empty())
if (name.empty()) { return &root;
*out = root;
return true;
}
const base::DictionaryValue* files = nullptr; const base::Value::Dict* files = GetFilesNode(root, dir);
return GetFilesNode(root, dir, &files) && return files ? files->FindDict(name) : nullptr;
files->GetDictionaryWithoutPathExpansion(name, out);
} }
// Gets the node of "path" from "root". // Gets the node of "path" from "root".
bool GetNodeFromPath(std::string path, const base::Value::Dict* GetNodeFromPath(std::string path,
const base::DictionaryValue* root, const base::Value::Dict& root) {
const base::DictionaryValue** out) { if (path.empty())
if (path.empty()) { return &root;
*out = root;
return true;
}
const base::DictionaryValue* dir = root; const base::Value::Dict* dir = &root;
for (size_t delimiter_position = path.find_first_of(kSeparators); for (size_t delimiter_position = path.find_first_of(kSeparators);
delimiter_position != std::string::npos; delimiter_position != std::string::npos;
delimiter_position = path.find_first_of(kSeparators)) { delimiter_position = path.find_first_of(kSeparators)) {
const base::DictionaryValue* child = nullptr; const base::Value::Dict* child =
if (!GetChildNode(root, path.substr(0, delimiter_position), dir, &child)) GetChildNode(root, path.substr(0, delimiter_position), *dir);
return false; if (!child)
return nullptr;
dir = child; dir = child;
path.erase(0, delimiter_position + 1); path.erase(0, delimiter_position + 1);
} }
return GetChildNode(root, path, dir, out); return GetChildNode(root, path, *dir);
} }
bool FillFileInfoWithNode(Archive::FileInfo* info, bool FillFileInfoWithNode(Archive::FileInfo* info,
uint32_t header_size, uint32_t header_size,
bool load_integrity, bool load_integrity,
const base::DictionaryValue* node) { const base::Value::Dict* node) {
if (auto size = node->FindIntKey("size")) { if (absl::optional<int> size = node->FindInt("size")) {
info->size = static_cast<uint32_t>(size.value()); info->size = static_cast<uint32_t>(*size);
} else { } else {
return false; return false;
} }
if (auto unpacked = node->FindBoolKey("unpacked")) { if (absl::optional<bool> unpacked = node->FindBool("unpacked")) {
info->unpacked = unpacked.value(); info->unpacked = *unpacked;
if (info->unpacked) { if (info->unpacked) {
return true; return true;
} }
} }
auto* offset = node->FindStringKey("offset"); const std::string* offset = node->FindString("offset");
if (offset && if (offset &&
base::StringToUint64(base::StringPiece(*offset), &info->offset)) { base::StringToUint64(base::StringPiece(*offset), &info->offset)) {
info->offset += header_size; info->offset += header_size;
@ -119,26 +111,26 @@ bool FillFileInfoWithNode(Archive::FileInfo* info,
return false; return false;
} }
if (auto executable = node->FindBoolKey("executable")) { if (absl::optional<bool> executable = node->FindBool("executable")) {
info->executable = executable.value(); info->executable = *executable;
} }
#if BUILDFLAG(IS_MAC) #if BUILDFLAG(IS_MAC)
if (load_integrity && if (load_integrity &&
electron::fuses::IsEmbeddedAsarIntegrityValidationEnabled()) { electron::fuses::IsEmbeddedAsarIntegrityValidationEnabled()) {
if (auto* integrity = node->FindDictKey("integrity")) { if (const base::Value::Dict* integrity = node->FindDict("integrity")) {
auto* algorithm = integrity->FindStringKey("algorithm"); const std::string* algorithm = integrity->FindString("algorithm");
auto* hash = integrity->FindStringKey("hash"); const std::string* hash = integrity->FindString("hash");
auto block_size = integrity->FindIntKey("blockSize"); absl::optional<int> block_size = integrity->FindInt("blockSize");
auto* blocks = integrity->FindListKey("blocks"); const base::Value::List* blocks = integrity->FindList("blocks");
if (algorithm && hash && block_size && block_size > 0 && blocks) { if (algorithm && hash && block_size && block_size > 0 && blocks) {
IntegrityPayload integrity_payload; IntegrityPayload integrity_payload;
integrity_payload.hash = *hash; integrity_payload.hash = *hash;
integrity_payload.block_size = integrity_payload.block_size =
static_cast<uint32_t>(block_size.value()); static_cast<uint32_t>(block_size.value());
for (auto& value : blocks->GetListDeprecated()) { for (auto& value : *blocks) {
if (auto* block = value.GetIfString()) { if (const std::string* block = value.GetIfString()) {
integrity_payload.blocks.push_back(*block); integrity_payload.blocks.push_back(*block);
} else { } else {
LOG(FATAL) LOG(FATAL)
@ -279,8 +271,7 @@ bool Archive::Init() {
} }
header_size_ = 8 + size; header_size_ = 8 + size;
header_ = base::DictionaryValue::From( header_ = std::move(value->GetDict());
base::Value::ToUniquePtrValue(std::move(*value)));
return true; return true;
} }
@ -298,13 +289,14 @@ bool Archive::GetFileInfo(const base::FilePath& path, FileInfo* info) const {
if (!header_) if (!header_)
return false; return false;
const base::DictionaryValue* node; const base::Value::Dict* node =
if (!GetNodeFromPath(path.AsUTF8Unsafe(), header_.get(), &node)) GetNodeFromPath(path.AsUTF8Unsafe(), *header_);
if (!node)
return false; return false;
std::string link; const std::string* link = node->FindString("link");
if (node->GetString("link", &link)) if (link)
return GetFileInfo(base::FilePath::FromUTF8Unsafe(link), info); return GetFileInfo(base::FilePath::FromUTF8Unsafe(*link), info);
return FillFileInfoWithNode(info, header_size_, header_validated_, node); return FillFileInfoWithNode(info, header_size_, header_validated_, node);
} }
@ -313,17 +305,18 @@ bool Archive::Stat(const base::FilePath& path, Stats* stats) const {
if (!header_) if (!header_)
return false; return false;
const base::DictionaryValue* node; const base::Value::Dict* node =
if (!GetNodeFromPath(path.AsUTF8Unsafe(), header_.get(), &node)) GetNodeFromPath(path.AsUTF8Unsafe(), *header_);
if (!node)
return false; return false;
if (node->FindKey("link")) { if (node->Find("link")) {
stats->is_file = false; stats->is_file = false;
stats->is_link = true; stats->is_link = true;
return true; return true;
} }
if (node->FindKey("files")) { if (node->Find("files")) {
stats->is_file = false; stats->is_file = false;
stats->is_directory = true; stats->is_directory = true;
return true; return true;
@ -337,19 +330,17 @@ bool Archive::Readdir(const base::FilePath& path,
if (!header_) if (!header_)
return false; return false;
const base::DictionaryValue* node; const base::Value::Dict* node =
if (!GetNodeFromPath(path.AsUTF8Unsafe(), header_.get(), &node)) GetNodeFromPath(path.AsUTF8Unsafe(), *header_);
if (!node)
return false; return false;
const base::DictionaryValue* files_node; const base::Value::Dict* files_node = GetFilesNode(*header_, *node);
if (!GetFilesNode(header_.get(), node, &files_node)) if (!files_node)
return false; return false;
base::DictionaryValue::Iterator iter(*files_node); for (const auto iter : *files_node)
while (!iter.IsAtEnd()) { files->push_back(base::FilePath::FromUTF8Unsafe(iter.first));
files->push_back(base::FilePath::FromUTF8Unsafe(iter.key()));
iter.Advance();
}
return true; return true;
} }
@ -358,13 +349,14 @@ bool Archive::Realpath(const base::FilePath& path,
if (!header_) if (!header_)
return false; return false;
const base::DictionaryValue* node; const base::Value::Dict* node =
if (!GetNodeFromPath(path.AsUTF8Unsafe(), header_.get(), &node)) GetNodeFromPath(path.AsUTF8Unsafe(), *header_);
if (!node)
return false; return false;
std::string link; const std::string* link = node->FindString("link");
if (node->GetString("link", &link)) { if (link) {
*realpath = base::FilePath::FromUTF8Unsafe(link); *realpath = base::FilePath::FromUTF8Unsafe(*link);
return true; return true;
} }

View file

@ -13,12 +13,9 @@
#include "base/files/file.h" #include "base/files/file.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/synchronization/lock.h" #include "base/synchronization/lock.h"
#include "base/values.h"
#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/abseil-cpp/absl/types/optional.h"
namespace base {
class DictionaryValue;
}
namespace asar { namespace asar {
class ScopedTemporaryFile; class ScopedTemporaryFile;
@ -104,7 +101,7 @@ class Archive {
base::File file_; base::File file_;
int fd_ = -1; int fd_ = -1;
uint32_t header_size_ = 0; uint32_t header_size_ = 0;
std::unique_ptr<base::DictionaryValue> header_; absl::optional<base::Value::Dict> header_;
// Cached external temporary files. // Cached external temporary files.
base::Lock external_files_lock_; base::Lock external_files_lock_;