LCOV - code coverage report
Current view: top level - src/inspector - v8-injected-script-host.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 145 158 91.8 %
Date: 2017-10-20 Functions: 10 11 90.9 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/inspector/v8-injected-script-host.h"
       6             : 
       7             : #include "src/base/macros.h"
       8             : #include "src/inspector/injected-script.h"
       9             : #include "src/inspector/string-util.h"
      10             : #include "src/inspector/v8-debugger.h"
      11             : #include "src/inspector/v8-inspector-impl.h"
      12             : #include "src/inspector/v8-internal-value-type.h"
      13             : #include "src/inspector/v8-value-utils.h"
      14             : 
      15             : #include "include/v8-inspector.h"
      16             : 
      17             : namespace v8_inspector {
      18             : 
      19             : namespace {
      20             : 
      21       26496 : void setFunctionProperty(v8::Local<v8::Context> context,
      22             :                          v8::Local<v8::Object> obj, const char* name,
      23             :                          v8::FunctionCallback callback,
      24             :                          v8::Local<v8::External> external) {
      25             :   v8::Local<v8::String> funcName =
      26       26496 :       toV8StringInternalized(context->GetIsolate(), name);
      27             :   v8::Local<v8::Function> func;
      28       26496 :   if (!v8::Function::New(context, callback, external, 0,
      29       26496 :                          v8::ConstructorBehavior::kThrow)
      30       26496 :            .ToLocal(&func))
      31           0 :     return;
      32       26496 :   func->SetName(funcName);
      33       26496 :   createDataProperty(context, obj, funcName, func);
      34             : }
      35             : 
      36             : V8InspectorImpl* unwrapInspector(
      37     6853083 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
      38             :   DCHECK(!info.Data().IsEmpty());
      39             :   DCHECK(info.Data()->IsExternal());
      40             :   V8InspectorImpl* inspector =
      41     6853083 :       static_cast<V8InspectorImpl*>(info.Data().As<v8::External>()->Value());
      42             :   DCHECK(inspector);
      43             :   return inspector;
      44             : }
      45             : 
      46             : }  // namespace
      47             : 
      48        2944 : v8::Local<v8::Object> V8InjectedScriptHost::create(
      49        2944 :     v8::Local<v8::Context> context, V8InspectorImpl* inspector) {
      50             :   v8::Isolate* isolate = inspector->isolate();
      51        2944 :   v8::Local<v8::Object> injectedScriptHost = v8::Object::New(isolate);
      52        2944 :   bool success = injectedScriptHost->SetPrototype(context, v8::Null(isolate))
      53        2944 :                      .FromMaybe(false);
      54             :   DCHECK(success);
      55             :   USE(success);
      56             :   v8::Local<v8::External> debuggerExternal =
      57        2944 :       v8::External::New(isolate, inspector);
      58             :   setFunctionProperty(context, injectedScriptHost, "nullifyPrototype",
      59             :                       V8InjectedScriptHost::nullifyPrototypeCallback,
      60        2944 :                       debuggerExternal);
      61             :   setFunctionProperty(context, injectedScriptHost, "getProperty",
      62             :                       V8InjectedScriptHost::getPropertyCallback,
      63        2944 :                       debuggerExternal);
      64             :   setFunctionProperty(context, injectedScriptHost, "internalConstructorName",
      65             :                       V8InjectedScriptHost::internalConstructorNameCallback,
      66        2944 :                       debuggerExternal);
      67             :   setFunctionProperty(
      68             :       context, injectedScriptHost, "formatAccessorsAsProperties",
      69        2944 :       V8InjectedScriptHost::formatAccessorsAsProperties, debuggerExternal);
      70             :   setFunctionProperty(context, injectedScriptHost, "subtype",
      71        2944 :                       V8InjectedScriptHost::subtypeCallback, debuggerExternal);
      72             :   setFunctionProperty(context, injectedScriptHost, "getInternalProperties",
      73             :                       V8InjectedScriptHost::getInternalPropertiesCallback,
      74        2944 :                       debuggerExternal);
      75             :   setFunctionProperty(context, injectedScriptHost, "objectHasOwnProperty",
      76             :                       V8InjectedScriptHost::objectHasOwnPropertyCallback,
      77        2944 :                       debuggerExternal);
      78             :   setFunctionProperty(context, injectedScriptHost, "bind",
      79        2944 :                       V8InjectedScriptHost::bindCallback, debuggerExternal);
      80             :   setFunctionProperty(context, injectedScriptHost, "proxyTargetValue",
      81             :                       V8InjectedScriptHost::proxyTargetValueCallback,
      82        2944 :                       debuggerExternal);
      83             :   createDataProperty(context, injectedScriptHost,
      84             :                      toV8StringInternalized(isolate, "keys"),
      85        8832 :                      v8::debug::GetBuiltin(isolate, v8::debug::kObjectKeys));
      86             :   createDataProperty(
      87             :       context, injectedScriptHost,
      88             :       toV8StringInternalized(isolate, "getPrototypeOf"),
      89        8832 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetPrototypeOf));
      90             :   createDataProperty(
      91             :       context, injectedScriptHost,
      92             :       toV8StringInternalized(isolate, "getOwnPropertyDescriptor"),
      93             :       v8::debug::GetBuiltin(isolate,
      94        8832 :                             v8::debug::kObjectGetOwnPropertyDescriptor));
      95             :   createDataProperty(
      96             :       context, injectedScriptHost,
      97             :       toV8StringInternalized(isolate, "getOwnPropertyNames"),
      98        8832 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetOwnPropertyNames));
      99             :   createDataProperty(
     100             :       context, injectedScriptHost,
     101             :       toV8StringInternalized(isolate, "getOwnPropertySymbols"),
     102        8832 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetOwnPropertySymbols));
     103        2944 :   return injectedScriptHost;
     104             : }
     105             : 
     106     2441489 : void V8InjectedScriptHost::nullifyPrototypeCallback(
     107     4882978 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     108     2441489 :   CHECK_EQ(1, info.Length());
     109             :   DCHECK(info[0]->IsObject());
     110     4882978 :   if (!info[0]->IsObject()) return;
     111             :   v8::Isolate* isolate = info.GetIsolate();
     112             :   info[0]
     113             :       .As<v8::Object>()
     114     4882978 :       ->SetPrototype(isolate->GetCurrentContext(), v8::Null(isolate))
     115     4882978 :       .ToChecked();
     116             : }
     117             : 
     118     1540492 : void V8InjectedScriptHost::getPropertyCallback(
     119     4620906 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     120     3080984 :   CHECK(info.Length() == 2 && info[1]->IsString());
     121     1540492 :   if (!info[0]->IsObject()) return;
     122             :   v8::Isolate* isolate = info.GetIsolate();
     123     1540492 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     124     1540492 :   v8::TryCatch tryCatch(isolate);
     125             :   v8::Isolate::DisallowJavascriptExecutionScope throwJs(
     126     3080984 :       isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
     127             :   v8::Local<v8::Value> property;
     128     1540492 :   if (info[0]
     129             :           .As<v8::Object>()
     130     1540492 :           ->Get(context, v8::Local<v8::String>::Cast(info[1]))
     131     1540492 :           .ToLocal(&property)) {
     132             :     info.GetReturnValue().Set(property);
     133     1540492 :   }
     134             : }
     135             : 
     136     5108772 : void V8InjectedScriptHost::internalConstructorNameCallback(
     137    10162552 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     138    15326316 :   if (info.Length() < 1 || !info[0]->IsObject()) return;
     139             : 
     140             :   v8::Local<v8::Object> object = info[0].As<v8::Object>();
     141     5053780 :   info.GetReturnValue().Set(object->GetConstructorName());
     142             : }
     143             : 
     144       18525 : void V8InjectedScriptHost::formatAccessorsAsProperties(
     145       18645 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     146             :   DCHECK_EQ(info.Length(), 2);
     147             :   info.GetReturnValue().Set(false);
     148       18525 :   if (!info[1]->IsFunction()) return;
     149             :   // Check that function is user-defined.
     150       18510 :   if (info[1].As<v8::Function>()->ScriptId() != v8::UnboundScript::kNoScriptId)
     151             :     return;
     152             :   info.GetReturnValue().Set(
     153         240 :       unwrapInspector(info)->client()->formatAccessorsAsProperties(info[0]));
     154             : }
     155             : 
     156     7034295 : void V8InjectedScriptHost::subtypeCallback(
     157    14250007 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     158     7215712 :   if (info.Length() < 1) return;
     159             : 
     160             :   v8::Isolate* isolate = info.GetIsolate();
     161             :   v8::Local<v8::Value> value = info[0];
     162     7034295 :   if (value->IsObject()) {
     163             :     v8::Local<v8::Value> internalType = v8InternalValueTypeFrom(
     164     6848943 :         isolate->GetCurrentContext(), v8::Local<v8::Object>::Cast(value));
     165     6848943 :     if (internalType->IsString()) {
     166             :       info.GetReturnValue().Set(internalType);
     167        1050 :       return;
     168             :     }
     169             :   }
     170     7033245 :   if (value->IsArray() || value->IsArgumentsObject()) {
     171      155462 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "array"));
     172             :     return;
     173             :   }
     174     6877783 :   if (value->IsTypedArray()) {
     175         105 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "typedarray"));
     176             :     return;
     177             :   }
     178     6877678 :   if (value->IsDate()) {
     179          63 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "date"));
     180             :     return;
     181             :   }
     182     6877615 :   if (value->IsRegExp()) {
     183          30 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "regexp"));
     184             :     return;
     185             :   }
     186     6877585 :   if (value->IsMap()) {
     187         283 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "map"));
     188             :     return;
     189             :   }
     190     6877302 :   if (value->IsWeakMap()) {
     191         150 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "weakmap"));
     192             :     return;
     193             :   }
     194     6877152 :   if (value->IsSet()) {
     195         305 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "set"));
     196             :     return;
     197             :   }
     198     6876847 :   if (value->IsWeakSet()) {
     199         150 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "weakset"));
     200             :     return;
     201             :   }
     202     6876697 :   if (value->IsMapIterator() || value->IsSetIterator()) {
     203         766 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "iterator"));
     204             :     return;
     205             :   }
     206     6875931 :   if (value->IsGeneratorObject()) {
     207         375 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "generator"));
     208             :     return;
     209             :   }
     210     6875556 :   if (value->IsNativeError()) {
     211       20140 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "error"));
     212             :     return;
     213             :   }
     214     6855416 :   if (value->IsProxy()) {
     215          15 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "proxy"));
     216             :     return;
     217             :   }
     218     6855401 :   if (value->IsPromise()) {
     219        2373 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "promise"));
     220             :     return;
     221             :   }
     222     6853028 :   if (value->IsArrayBuffer() || value->IsSharedArrayBuffer()) {
     223         100 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "arraybuffer"));
     224             :     return;
     225             :   }
     226     6852928 :   if (value->IsDataView()) {
     227          50 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "dataview"));
     228             :     return;
     229             :   }
     230             :   std::unique_ptr<StringBuffer> subtype =
     231     6852878 :       unwrapInspector(info)->client()->valueSubtype(value);
     232     6852878 :   if (subtype) {
     233           0 :     info.GetReturnValue().Set(toV8String(isolate, subtype->string()));
     234             :     return;
     235             :   }
     236             : }
     237             : 
     238         390 : void V8InjectedScriptHost::getInternalPropertiesCallback(
     239         560 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     240         695 :   if (info.Length() < 1) return;
     241             : 
     242         390 :   std::unordered_set<String16> allowedProperties;
     243        1545 :   if (info[0]->IsBooleanObject() || info[0]->IsNumberObject() ||
     244        1145 :       info[0]->IsStringObject() || info[0]->IsSymbolObject()) {
     245          40 :     allowedProperties.insert(String16("[[PrimitiveValue]]"));
     246         370 :   } else if (info[0]->IsPromise()) {
     247          30 :     allowedProperties.insert(String16("[[PromiseStatus]]"));
     248          30 :     allowedProperties.insert(String16("[[PromiseValue]]"));
     249         355 :   } else if (info[0]->IsGeneratorObject()) {
     250          10 :     allowedProperties.insert(String16("[[GeneratorStatus]]"));
     251        1705 :   } else if (info[0]->IsMap() || info[0]->IsWeakMap() || info[0]->IsSet() ||
     252        1295 :              info[0]->IsWeakSet() || info[0]->IsMapIterator() ||
     253         310 :              info[0]->IsSetIterator()) {
     254          90 :     allowedProperties.insert(String16("[[Entries]]"));
     255             :   }
     256         390 :   if (!allowedProperties.size()) return;
     257             : 
     258             :   v8::Isolate* isolate = info.GetIsolate();
     259             :   v8::Local<v8::Array> allProperties;
     260          85 :   if (!unwrapInspector(info)
     261             :            ->debugger()
     262          85 :            ->internalProperties(isolate->GetCurrentContext(), info[0])
     263         170 :            .ToLocal(&allProperties) ||
     264         170 :       !allProperties->IsArray() || allProperties->Length() % 2 != 0)
     265             :     return;
     266             : 
     267             :   {
     268          85 :     v8::Local<v8::Context> context = isolate->GetCurrentContext();
     269          85 :     v8::TryCatch tryCatch(isolate);
     270             :     v8::Isolate::DisallowJavascriptExecutionScope throwJs(
     271             :         isolate,
     272         170 :         v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
     273             : 
     274          85 :     v8::Local<v8::Array> properties = v8::Array::New(isolate);
     275          85 :     if (tryCatch.HasCaught()) return;
     276             : 
     277             :     uint32_t outputIndex = 0;
     278         150 :     for (uint32_t i = 0; i < allProperties->Length(); i += 2) {
     279             :       v8::Local<v8::Value> key;
     280         350 :       if (!allProperties->Get(context, i).ToLocal(&key)) continue;
     281         150 :       if (tryCatch.HasCaught()) {
     282           0 :         tryCatch.Reset();
     283           0 :         continue;
     284             :       }
     285         150 :       String16 keyString = toProtocolStringWithTypeCheck(key);
     286         300 :       if (keyString.isEmpty() ||
     287             :           allowedProperties.find(keyString) == allowedProperties.end())
     288             :         continue;
     289             :       v8::Local<v8::Value> value;
     290         200 :       if (!allProperties->Get(context, i + 1).ToLocal(&value)) continue;
     291         100 :       if (tryCatch.HasCaught()) {
     292           0 :         tryCatch.Reset();
     293           0 :         continue;
     294             :       }
     295         100 :       createDataProperty(context, properties, outputIndex++, key);
     296         100 :       createDataProperty(context, properties, outputIndex++, value);
     297             :     }
     298          85 :     info.GetReturnValue().Set(properties);
     299             :   }
     300             : }
     301             : 
     302          60 : void V8InjectedScriptHost::objectHasOwnPropertyCallback(
     303         180 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     304         240 :   if (info.Length() < 2 || !info[0]->IsObject() || !info[1]->IsString()) return;
     305             :   bool result = info[0]
     306             :                     .As<v8::Object>()
     307             :                     ->HasOwnProperty(info.GetIsolate()->GetCurrentContext(),
     308         120 :                                      v8::Local<v8::String>::Cast(info[1]))
     309         120 :                     .FromMaybe(false);
     310             :   info.GetReturnValue().Set(v8::Boolean::New(info.GetIsolate(), result));
     311             : }
     312             : 
     313     2540233 : void V8InjectedScriptHost::bindCallback(
     314    10160932 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     315     5080466 :   if (info.Length() < 2 || !info[1]->IsString()) return;
     316             :   InjectedScript* injectedScript =
     317     2540233 :       InjectedScript::fromInjectedScriptHost(info.GetIsolate(), info.Holder());
     318     2540233 :   if (!injectedScript) return;
     319             : 
     320     2540233 :   v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
     321             :   v8::Local<v8::String> v8groupName =
     322     2540233 :       info[1]->ToString(context).ToLocalChecked();
     323     2540233 :   String16 groupName = toProtocolStringWithTypeCheck(v8groupName);
     324     2540233 :   int id = injectedScript->bindObject(info[0], groupName);
     325             :   info.GetReturnValue().Set(id);
     326             : }
     327             : 
     328           0 : void V8InjectedScriptHost::proxyTargetValueCallback(
     329           0 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     330           0 :   if (info.Length() != 1 || !info[0]->IsProxy()) {
     331           0 :     UNREACHABLE();
     332             :     return;
     333             :   }
     334             :   v8::Local<v8::Object> target = info[0].As<v8::Proxy>();
     335           0 :   while (target->IsProxy())
     336           0 :     target = v8::Local<v8::Proxy>::Cast(target)->GetTarget();
     337             :   info.GetReturnValue().Set(target);
     338           0 : }
     339             : 
     340             : }  // namespace v8_inspector

Generated by: LCOV version 1.10