1616namespace node {
1717namespace inspector {
1818
19+ using v8::Array;
20+ using v8::Boolean;
21+ using v8::Context;
1922using v8::HandleScope;
23+ using v8::Int32;
2024using v8::Isolate;
2125using v8::Local;
26+ using v8::LocalVector;
27+ using v8::Number;
2228using v8::Object;
2329using v8::Uint8Array;
2430using v8::Value;
2531
2632constexpr size_t kDefaultMaxTotalBufferSize = 100 * 1024 * 1024 ; // 100MB
33+ constexpr size_t kMaxProtocolValueDepth = 100 ;
2734
2835static void ThrowEventError (v8::Isolate* isolate, const std::string& message) {
2936 isolate->ThrowException (v8::Exception::TypeError (
3037 v8::String::NewFromUtf8 (isolate, message.c_str ()).ToLocalChecked ()));
3138}
3239
3340static std::unique_ptr<protocol::Value> V8ToProtocolValue (
34- Isolate* isolate, v8::Local<v8::Context> context, Local<Value> value) {
41+ Isolate* isolate,
42+ Local<Context> context,
43+ Local<Value> value,
44+ LocalVector<Object>* ancestors) {
3545 if (value->IsNullOrUndefined ()) {
3646 return protocol::Value::null ();
3747 }
3848 if (value->IsBoolean ()) {
39- return protocol::FundamentalValue::create (value.As <v8:: Boolean>()->Value ());
49+ return protocol::FundamentalValue::create (value.As <Boolean>()->Value ());
4050 }
4151 if (value->IsInt32 ()) {
42- return protocol::FundamentalValue::create (value.As <v8:: Int32>()->Value ());
52+ return protocol::FundamentalValue::create (value.As <Int32>()->Value ());
4353 }
4454 if (value->IsNumber ()) {
45- return protocol::FundamentalValue::create (value.As <v8:: Number>()->Value ());
55+ return protocol::FundamentalValue::create (value.As <Number>()->Value ());
4656 }
4757 if (value->IsString ()) {
4858 return protocol::StringValue::create (ToProtocolString (isolate, value));
4959 }
60+
61+ if (!value->IsObject ()) {
62+ return nullptr ;
63+ }
64+
65+ Local<Object> object = value.As <Object>();
66+ if (ancestors->size () >= kMaxProtocolValueDepth ) {
67+ return nullptr ;
68+ }
69+ for (const auto & ancestor : *ancestors) {
70+ if (ancestor == object) {
71+ return nullptr ;
72+ }
73+ }
74+ ancestors->push_back (object);
75+ auto pop_ancestor = OnScopeLeave ([ancestors]() { ancestors->pop_back (); });
76+
5077 if (value->IsArray ()) {
51- Local<v8:: Array> array = value.As <v8:: Array>();
78+ Local<Array> array = value.As <Array>();
5279 std::unique_ptr<protocol::ListValue> list = protocol::ListValue::create ();
5380 list->reserve (array->Length ());
5481 for (uint32_t i = 0 ; i < array->Length (); i++) {
@@ -57,43 +84,46 @@ static std::unique_ptr<protocol::Value> V8ToProtocolValue(
5784 return nullptr ;
5885 }
5986 std::unique_ptr<protocol::Value> protocol_value =
60- V8ToProtocolValue (isolate, context, element);
87+ V8ToProtocolValue (isolate, context, element, ancestors );
6188 if (!protocol_value) {
6289 return nullptr ;
6390 }
6491 list->pushValue (std::move (protocol_value));
6592 }
6693 return list;
6794 }
68- if (value->IsObject ()) {
69- Local<Object> object = value.As <Object>();
70- Local<v8::Array> property_names;
71- if (!object->GetOwnPropertyNames (context).ToLocal (&property_names)) {
95+
96+ Local<Array> property_names;
97+ if (!object->GetOwnPropertyNames (context).ToLocal (&property_names)) {
98+ return nullptr ;
99+ }
100+ std::unique_ptr<protocol::DictionaryValue> dict =
101+ protocol::DictionaryValue::create ();
102+ for (uint32_t i = 0 ; i < property_names->Length (); i++) {
103+ Local<Value> property_name;
104+ if (!property_names->Get (context, i).ToLocal (&property_name) ||
105+ !property_name->IsString ()) {
72106 return nullptr ;
73107 }
74- std::unique_ptr<protocol::DictionaryValue> dict =
75- protocol::DictionaryValue::create ();
76- for (uint32_t i = 0 ; i < property_names->Length (); i++) {
77- Local<Value> property_name;
78- if (!property_names->Get (context, i).ToLocal (&property_name) ||
79- !property_name->IsString ()) {
80- return nullptr ;
81- }
82- Local<Value> property;
83- if (!object->Get (context, property_name).ToLocal (&property)) {
84- return nullptr ;
85- }
86- std::unique_ptr<protocol::Value> protocol_value =
87- V8ToProtocolValue (isolate, context, property);
88- if (!protocol_value) {
89- return nullptr ;
90- }
91- dict->setValue (ToProtocolString (isolate, property_name),
92- std::move (protocol_value));
108+ Local<Value> property;
109+ if (!object->Get (context, property_name).ToLocal (&property)) {
110+ return nullptr ;
111+ }
112+ std::unique_ptr<protocol::Value> protocol_value =
113+ V8ToProtocolValue (isolate, context, property, ancestors);
114+ if (!protocol_value) {
115+ return nullptr ;
93116 }
94- return dict;
117+ dict->setValue (ToProtocolString (isolate, property_name),
118+ std::move (protocol_value));
95119 }
96- return nullptr ;
120+ return dict;
121+ }
122+
123+ static std::unique_ptr<protocol::Value> V8ToProtocolValue (
124+ Isolate* isolate, Local<Context> context, Local<Value> value) {
125+ LocalVector<Object> ancestors (isolate);
126+ return V8ToProtocolValue (isolate, context, value, &ancestors);
97127}
98128
99129// Create a protocol::Network::Headers from the v8 object.
0 commit comments