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-04-26 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-native.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-copier.h"
      14             : 
      15             : #include "include/v8-inspector.h"
      16             : 
      17             : namespace v8_inspector {
      18             : 
      19             : namespace {
      20             : 
      21       36981 : 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       36981 :       toV8StringInternalized(context->GetIsolate(), name);
      27             :   v8::Local<v8::Function> func;
      28       36981 :   if (!v8::Function::New(context, callback, external, 0,
      29       36981 :                          v8::ConstructorBehavior::kThrow)
      30       73962 :            .ToLocal(&func))
      31           0 :     return;
      32       36981 :   func->SetName(funcName);
      33       36981 :   createDataProperty(context, obj, funcName, func);
      34             : }
      35             : 
      36             : V8InspectorImpl* unwrapInspector(
      37    10149592 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
      38             :   DCHECK(!info.Data().IsEmpty());
      39             :   DCHECK(info.Data()->IsExternal());
      40             :   V8InspectorImpl* inspector =
      41    10149592 :       static_cast<V8InspectorImpl*>(info.Data().As<v8::External>()->Value());
      42             :   DCHECK(inspector);
      43             :   return inspector;
      44             : }
      45             : 
      46             : }  // namespace
      47             : 
      48        4109 : v8::Local<v8::Object> V8InjectedScriptHost::create(
      49        4109 :     v8::Local<v8::Context> context, V8InspectorImpl* inspector) {
      50             :   v8::Isolate* isolate = inspector->isolate();
      51        4109 :   v8::Local<v8::Object> injectedScriptHost = v8::Object::New(isolate);
      52        4109 :   bool success = injectedScriptHost->SetPrototype(context, v8::Null(isolate))
      53        4109 :                      .FromMaybe(false);
      54             :   DCHECK(success);
      55             :   USE(success);
      56             :   v8::Local<v8::External> debuggerExternal =
      57        4109 :       v8::External::New(isolate, inspector);
      58             :   setFunctionProperty(context, injectedScriptHost, "nullifyPrototype",
      59             :                       V8InjectedScriptHost::nullifyPrototypeCallback,
      60        4109 :                       debuggerExternal);
      61             :   setFunctionProperty(context, injectedScriptHost, "getProperty",
      62             :                       V8InjectedScriptHost::getPropertyCallback,
      63        4109 :                       debuggerExternal);
      64             :   setFunctionProperty(context, injectedScriptHost, "internalConstructorName",
      65             :                       V8InjectedScriptHost::internalConstructorNameCallback,
      66        4109 :                       debuggerExternal);
      67             :   setFunctionProperty(
      68             :       context, injectedScriptHost, "formatAccessorsAsProperties",
      69        4109 :       V8InjectedScriptHost::formatAccessorsAsProperties, debuggerExternal);
      70             :   setFunctionProperty(context, injectedScriptHost, "subtype",
      71        4109 :                       V8InjectedScriptHost::subtypeCallback, debuggerExternal);
      72             :   setFunctionProperty(context, injectedScriptHost, "getInternalProperties",
      73             :                       V8InjectedScriptHost::getInternalPropertiesCallback,
      74        4109 :                       debuggerExternal);
      75             :   setFunctionProperty(context, injectedScriptHost, "objectHasOwnProperty",
      76             :                       V8InjectedScriptHost::objectHasOwnPropertyCallback,
      77        4109 :                       debuggerExternal);
      78             :   setFunctionProperty(context, injectedScriptHost, "bind",
      79        4109 :                       V8InjectedScriptHost::bindCallback, debuggerExternal);
      80             :   setFunctionProperty(context, injectedScriptHost, "proxyTargetValue",
      81             :                       V8InjectedScriptHost::proxyTargetValueCallback,
      82        4109 :                       debuggerExternal);
      83             :   createDataProperty(context, injectedScriptHost,
      84             :                      toV8StringInternalized(isolate, "keys"),
      85       12327 :                      v8::debug::GetBuiltin(isolate, v8::debug::kObjectKeys));
      86             :   createDataProperty(
      87             :       context, injectedScriptHost,
      88             :       toV8StringInternalized(isolate, "getPrototypeOf"),
      89       12327 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetPrototypeOf));
      90             :   createDataProperty(
      91             :       context, injectedScriptHost,
      92             :       toV8StringInternalized(isolate, "getOwnPropertyDescriptor"),
      93             :       v8::debug::GetBuiltin(isolate,
      94       12327 :                             v8::debug::kObjectGetOwnPropertyDescriptor));
      95             :   createDataProperty(
      96             :       context, injectedScriptHost,
      97             :       toV8StringInternalized(isolate, "getOwnPropertyNames"),
      98       12327 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetOwnPropertyNames));
      99             :   createDataProperty(
     100             :       context, injectedScriptHost,
     101             :       toV8StringInternalized(isolate, "getOwnPropertySymbols"),
     102       12327 :       v8::debug::GetBuiltin(isolate, v8::debug::kObjectGetOwnPropertySymbols));
     103        4109 :   return injectedScriptHost;
     104             : }
     105             : 
     106     3562089 : void V8InjectedScriptHost::nullifyPrototypeCallback(
     107     7124178 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     108     3562089 :   CHECK(info.Length() == 1);
     109             :   DCHECK(info[0]->IsObject());
     110     7124178 :   if (!info[0]->IsObject()) return;
     111             :   v8::Isolate* isolate = info.GetIsolate();
     112             :   info[0]
     113             :       .As<v8::Object>()
     114     7124178 :       ->SetPrototype(isolate->GetCurrentContext(), v8::Null(isolate))
     115     7124178 :       .ToChecked();
     116             : }
     117             : 
     118     2270048 : void V8InjectedScriptHost::getPropertyCallback(
     119     6810144 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     120     4540096 :   CHECK(info.Length() == 2 && info[1]->IsString());
     121     2270048 :   if (!info[0]->IsObject()) return;
     122             :   v8::Isolate* isolate = info.GetIsolate();
     123     2270048 :   v8::Local<v8::Context> context = isolate->GetCurrentContext();
     124     2270048 :   v8::TryCatch tryCatch(isolate);
     125             :   v8::Isolate::DisallowJavascriptExecutionScope throwJs(
     126     4540096 :       isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
     127             :   v8::Local<v8::Value> property;
     128     2270048 :   if (info[0]
     129             :           .As<v8::Object>()
     130     2270048 :           ->Get(context, v8::Local<v8::String>::Cast(info[1]))
     131     4540096 :           .ToLocal(&property)) {
     132             :     info.GetReturnValue().Set(property);
     133     2270048 :   }
     134             : }
     135             : 
     136     7590332 : void V8InjectedScriptHost::internalConstructorNameCallback(
     137    15094328 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     138    22770996 :   if (info.Length() < 1 || !info[0]->IsObject()) return;
     139             : 
     140             :   v8::Local<v8::Object> object = info[0].As<v8::Object>();
     141     7503996 :   info.GetReturnValue().Set(object->GetConstructorName());
     142             : }
     143             : 
     144        8916 : void V8InjectedScriptHost::formatAccessorsAsProperties(
     145        9000 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     146             :   DCHECK_EQ(info.Length(), 2);
     147             :   info.GetReturnValue().Set(false);
     148        8916 :   if (!info[1]->IsFunction()) return;
     149             :   // Check that function is user-defined.
     150        8898 :   if (info[1].As<v8::Function>()->ScriptId() != v8::UnboundScript::kNoScriptId)
     151             :     return;
     152             :   info.GetReturnValue().Set(
     153         168 :       unwrapInspector(info)->client()->formatAccessorsAsProperties(info[0]));
     154             : }
     155             : 
     156    10415478 : void V8InjectedScriptHost::subtypeCallback(
     157    21097028 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     158    10681550 :   if (info.Length() < 1) return;
     159             : 
     160             :   v8::Isolate* isolate = info.GetIsolate();
     161             :   v8::Local<v8::Value> value = info[0];
     162    10415478 :   if (value->IsObject()) {
     163             :     v8::Local<v8::Value> internalType = v8InternalValueTypeFrom(
     164    10187910 :         isolate->GetCurrentContext(), v8::Local<v8::Object>::Cast(value));
     165    10187910 :     if (internalType->IsString()) {
     166             :       info.GetReturnValue().Set(internalType);
     167        1044 :       return;
     168             :     }
     169             :   }
     170    10414434 :   if (value->IsArray() || value->IsArgumentsObject()) {
     171      244182 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "array"));
     172             :     return;
     173             :   }
     174    10170252 :   if (value->IsTypedArray()) {
     175         126 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "typedarray"));
     176             :     return;
     177             :   }
     178    10170126 :   if (value->IsDate()) {
     179          98 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "date"));
     180             :     return;
     181             :   }
     182    10170028 :   if (value->IsRegExp()) {
     183          36 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "regexp"));
     184             :     return;
     185             :   }
     186    10169992 :   if (value->IsMap()) {
     187         362 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "map"));
     188             :     return;
     189             :   }
     190    10169630 :   if (value->IsWeakMap()) {
     191         180 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "weakmap"));
     192             :     return;
     193             :   }
     194    10169450 :   if (value->IsSet()) {
     195         366 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "set"));
     196             :     return;
     197             :   }
     198    10169084 :   if (value->IsWeakSet()) {
     199         180 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "weakset"));
     200             :     return;
     201             :   }
     202    10168904 :   if (value->IsMapIterator() || value->IsSetIterator()) {
     203         996 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "iterator"));
     204             :     return;
     205             :   }
     206    10167908 :   if (value->IsGeneratorObject()) {
     207         450 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "generator"));
     208             :     return;
     209             :   }
     210    10167458 :   if (value->IsNativeError()) {
     211       15564 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "error"));
     212             :     return;
     213             :   }
     214    10151894 :   if (value->IsProxy()) {
     215          18 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "proxy"));
     216             :     return;
     217             :   }
     218    10151876 :   if (value->IsPromise()) {
     219        2470 :     info.GetReturnValue().Set(toV8StringInternalized(isolate, "promise"));
     220             :     return;
     221             :   }
     222             :   std::unique_ptr<StringBuffer> subtype =
     223    10149406 :       unwrapInspector(info)->client()->valueSubtype(value);
     224    10149406 :   if (subtype) {
     225           0 :     info.GetReturnValue().Set(toV8String(isolate, subtype->string()));
     226             :     return;
     227             :   }
     228             : }
     229             : 
     230         366 : void V8InjectedScriptHost::getInternalPropertiesCallback(
     231         570 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     232         630 :   if (info.Length() < 1) return;
     233             : 
     234         366 :   std::unordered_set<String16> allowedProperties;
     235        1446 :   if (info[0]->IsBooleanObject() || info[0]->IsNumberObject() ||
     236        1068 :       info[0]->IsStringObject() || info[0]->IsSymbolObject()) {
     237          48 :     allowedProperties.insert(String16("[[PrimitiveValue]]"));
     238         342 :   } else if (info[0]->IsPromise()) {
     239          36 :     allowedProperties.insert(String16("[[PromiseStatus]]"));
     240          36 :     allowedProperties.insert(String16("[[PromiseValue]]"));
     241         324 :   } else if (info[0]->IsGeneratorObject()) {
     242          12 :     allowedProperties.insert(String16("[[GeneratorStatus]]"));
     243         630 :   } else if (info[0]->IsMapIterator() || info[0]->IsSetIterator()) {
     244          24 :     allowedProperties.insert(String16("[[IteratorHasMore]]"));
     245          24 :     allowedProperties.insert(String16("[[IteratorIndex]]"));
     246          24 :     allowedProperties.insert(String16("[[IteratorKind]]"));
     247          24 :     allowedProperties.insert(String16("[[Entries]]"));
     248        1170 :   } else if (info[0]->IsMap() || info[0]->IsWeakMap() || info[0]->IsSet() ||
     249         270 :              info[0]->IsWeakSet()) {
     250          84 :     allowedProperties.insert(String16("[[Entries]]"));
     251             :   }
     252         366 :   if (!allowedProperties.size()) return;
     253             : 
     254             :   v8::Isolate* isolate = info.GetIsolate();
     255             :   v8::Local<v8::Array> allProperties;
     256         102 :   if (!unwrapInspector(info)
     257             :            ->debugger()
     258         102 :            ->internalProperties(isolate->GetCurrentContext(), info[0])
     259         306 :            .ToLocal(&allProperties) ||
     260         204 :       !allProperties->IsArray() || allProperties->Length() % 2 != 0)
     261             :     return;
     262             : 
     263             :   {
     264         102 :     v8::Local<v8::Context> context = isolate->GetCurrentContext();
     265         102 :     v8::TryCatch tryCatch(isolate);
     266             :     v8::Isolate::DisallowJavascriptExecutionScope throwJs(
     267             :         isolate,
     268         204 :         v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
     269             : 
     270         102 :     v8::Local<v8::Array> properties = v8::Array::New(isolate);
     271         102 :     if (tryCatch.HasCaught()) return;
     272             : 
     273             :     uint32_t outputIndex = 0;
     274         180 :     for (uint32_t i = 0; i < allProperties->Length(); i += 2) {
     275             :       v8::Local<v8::Value> key;
     276         384 :       if (!allProperties->Get(context, i).ToLocal(&key)) continue;
     277         180 :       if (tryCatch.HasCaught()) {
     278           0 :         tryCatch.Reset();
     279           0 :         continue;
     280             :       }
     281         180 :       String16 keyString = toProtocolStringWithTypeCheck(key);
     282         360 :       if (keyString.isEmpty() ||
     283             :           allowedProperties.find(keyString) == allowedProperties.end())
     284             :         continue;
     285             :       v8::Local<v8::Value> value;
     286         312 :       if (!allProperties->Get(context, i + 1).ToLocal(&value)) continue;
     287         156 :       if (tryCatch.HasCaught()) {
     288           0 :         tryCatch.Reset();
     289           0 :         continue;
     290             :       }
     291         156 :       createDataProperty(context, properties, outputIndex++, key);
     292         156 :       createDataProperty(context, properties, outputIndex++, value);
     293             :     }
     294         102 :     info.GetReturnValue().Set(properties);
     295             :   }
     296             : }
     297             : 
     298          24 : void V8InjectedScriptHost::objectHasOwnPropertyCallback(
     299          72 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     300          96 :   if (info.Length() < 2 || !info[0]->IsObject() || !info[1]->IsString()) return;
     301             :   bool result = info[0]
     302             :                     .As<v8::Object>()
     303             :                     ->HasOwnProperty(info.GetIsolate()->GetCurrentContext(),
     304          48 :                                      v8::Local<v8::String>::Cast(info[1]))
     305          48 :                     .FromMaybe(false);
     306             :   info.GetReturnValue().Set(v8::Boolean::New(info.GetIsolate(), result));
     307             : }
     308             : 
     309     3780575 : void V8InjectedScriptHost::bindCallback(
     310    15122300 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     311     7561150 :   if (info.Length() < 2 || !info[1]->IsString()) return;
     312             :   InjectedScriptNative* injectedScriptNative =
     313             :       InjectedScriptNative::fromInjectedScriptHost(info.GetIsolate(),
     314     3780575 :                                                    info.Holder());
     315     3780575 :   if (!injectedScriptNative) return;
     316             : 
     317     3780575 :   v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
     318             :   v8::Local<v8::String> v8groupName =
     319     3780575 :       info[1]->ToString(context).ToLocalChecked();
     320     3780575 :   String16 groupName = toProtocolStringWithTypeCheck(v8groupName);
     321     3780575 :   int id = injectedScriptNative->bind(info[0], groupName);
     322             :   info.GetReturnValue().Set(id);
     323             : }
     324             : 
     325           0 : void V8InjectedScriptHost::proxyTargetValueCallback(
     326           0 :     const v8::FunctionCallbackInfo<v8::Value>& info) {
     327           0 :   if (info.Length() != 1 || !info[0]->IsProxy()) {
     328           0 :     UNREACHABLE();
     329             :     return;
     330             :   }
     331             :   v8::Local<v8::Object> target = info[0].As<v8::Proxy>();
     332           0 :   while (target->IsProxy())
     333           0 :     target = v8::Local<v8::Proxy>::Cast(target)->GetTarget();
     334             :   info.GetReturnValue().Set(target);
     335           0 : }
     336             : 
     337             : }  // namespace v8_inspector

Generated by: LCOV version 1.10