inspector: auto collect webstorage data · nodejs/node@4f3f21b
11#include "dom_storage_agent.h"
2+#include <optional>
23#include "env-inl.h"
34#include "inspector/inspector_object_utils.h"
5+#include "util.h"
6+#include "v8-exception.h"
47#include "v8-isolate.h"
5869namespace node {
@@ -85,14 +88,27 @@ protocol::DispatchResponse DOMStorageAgent::getDOMStorageItems(
8588"DOMStorage domain is not enabled");
8689 }
8790bool is_local_storage = storageId->getIsLocalStorage();
88-const std::unordered_map<std::string, std::string>& storage_map =
89- is_local_storage ? local_storage_map_ : session_storage_map_;
91+const StorageMap* storage_map =
92+ is_local_storage ? &local_storage_map_ : &session_storage_map_;
93+ std::optional<StorageMap> storage_map_fallback;
94+if (storage_map->empty()) {
95+auto web_storage_obj = getWebStorage(is_local_storage);
96+if (web_storage_obj) {
97+ storage_map_fallback = web_storage_obj.value()->GetAll();
98+ storage_map = &storage_map_fallback.value();
99+ }
100+ }
101+90102auto result =
91103 std::make_unique<protocol::Array<protocol::Array<protocol::String>>>();
92-for (const auto& pair : storage_map) {
104+for (const auto& pair : *storage_map) {
93105auto item = std::make_unique<protocol::Array<protocol::String>>();
94- item->push_back(pair.first);
95- item->push_back(pair.second);
106+ item->push_back(protocol::StringUtil::fromUTF16(
107+reinterpret_cast<const uint16_t*>(pair.first.data()),
108+ pair.first.size()));
109+ item->push_back(protocol::StringUtil::fromUTF16(
110+reinterpret_cast<const uint16_t*>(pair.second.data()),
111+ pair.second.size()));
96112 result->push_back(std::move(item));
97113 }
98114 *items = std::move(result);
@@ -219,7 +235,7 @@ void DOMStorageAgent::registerStorage(Local<Context> context,
219235 .ToLocal(&storage_map_obj)) {
220236return;
221237 }
222-std::unordered_map<std::string, std::string>& storage_map =
238+StorageMap& storage_map =
223239 is_local_storage ? local_storage_map_ : session_storage_map_;
224240 Local<Array> property_names;
225241if (!storage_map_obj->GetOwnPropertyNames(context).ToLocal(&property_names)) {
@@ -235,9 +251,32 @@ void DOMStorageAgent::registerStorage(Local<Context> context,
235251if (!storage_map_obj->Get(context, key_value).ToLocal(&value_value)) {
236252return;
237253 }
238- node::Utf8Value key_utf8(isolate, key_value);
239- node::Utf8Value value_utf8(isolate, value_value);
240- storage_map[*key_utf8] = *value_utf8;
254+ node::TwoByteValue key_utf16(isolate, key_value);
255+ node::TwoByteValue value_utf16(isolate, value_value);
256+ storage_map[key_utf16.ToU16String()] = value_utf16.ToU16String();
257+ }
258+}
259+260+std::optional<node::webstorage::Storage*> DOMStorageAgent::getWebStorage(
261+bool is_local_storage) {
262+ v8::Isolate* isolate = env_->isolate();
263+ v8::HandleScope handle_scope(isolate);
264+ v8::Local<v8::Object> global = env_->context()->Global();
265+ v8::Local<v8::Value> web_storage_val;
266+ v8::TryCatch try_catch(isolate);
267+if (!global
268+ ->Get(env_->context(),
269+ is_local_storage
270+ ? FIXED_ONE_BYTE_STRING(isolate, "localStorage")
271+ : FIXED_ONE_BYTE_STRING(isolate, "sessionStorage"))
272+ .ToLocal(&web_storage_val) ||
273+ !web_storage_val->IsObject() || try_catch.HasCaught()) {
274+return std::nullopt;
275+ } else {
276+ node::webstorage::Storage* storage;
277+ASSIGN_OR_RETURN_UNWRAP(
278+ &storage, web_storage_val.As<v8::Object>(), std::nullopt);
279+return storage;
241280 }
242281}
243282