chore: modernize base::Value useage in asar/archive (#34796)
This commit is contained in:
parent
c418275228
commit
403bd39d05
2 changed files with 69 additions and 80 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
Loading…
Reference in a new issue