◐ Shell
clean mode source ↗

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"

5869

namespace node {

@@ -85,14 +88,27 @@ protocol::DispatchResponse DOMStorageAgent::getDOMStorageItems(

8588

"DOMStorage domain is not enabled");

8689

}

8790

bool 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+90102

auto 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) {

93105

auto 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)) {

220236

return;

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;

225241

if (!storage_map_obj->GetOwnPropertyNames(context).ToLocal(&property_names)) {

@@ -235,9 +251,32 @@ void DOMStorageAgent::registerStorage(Local<Context> context,

235251

if (!storage_map_obj->Get(context, key_value).ToLocal(&value_value)) {

236252

return;

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