Commit 2629f811 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] Increased chances of successful InjectedScriptSource compilation

- added InspectorTest.setupInjectedScriptEnvironment method which mutates current context,
- clear prototype of InjectedScript function and domAttributesWithObservableSideEffectOnGet.

Second point increases chances that injected-script-source would be successfully compiled.

BUG=chromium:693338
R=dgozman@chromium.org,luoe@chromium.org

Review-Url: https://codereview.chromium.org/2770823003
Cr-Commit-Position: refs/heads/master@{#44081}
parent 4e9ca103
...@@ -157,11 +157,11 @@ function isSymbol(obj) ...@@ -157,11 +157,11 @@ function isSymbol(obj)
* @type {!Object<string, !Object<string, boolean>>} * @type {!Object<string, !Object<string, boolean>>}
* @const * @const
*/ */
var domAttributesWithObservableSideEffectOnGet = nullifyObjectProto({}); var domAttributesWithObservableSideEffectOnGet = {
domAttributesWithObservableSideEffectOnGet["Request"] = nullifyObjectProto({}); Request: { body: true, __proto__: null },
domAttributesWithObservableSideEffectOnGet["Request"]["body"] = true; Response: { body: true, __proto__: null },
domAttributesWithObservableSideEffectOnGet["Response"] = nullifyObjectProto({}); __proto__: null
domAttributesWithObservableSideEffectOnGet["Response"]["body"] = true; }
/** /**
* @param {!Object} object * @param {!Object} object
...@@ -186,6 +186,7 @@ function doesAttributeHaveObservableSideEffectOnGet(object, attribute) ...@@ -186,6 +186,7 @@ function doesAttributeHaveObservableSideEffectOnGet(object, attribute)
var InjectedScript = function() var InjectedScript = function()
{ {
} }
InjectedScriptHost.nullifyPrototype(InjectedScript);
/** /**
* @type {!Object.<string, boolean>} * @type {!Object.<string, boolean>}
......
...@@ -7,6 +7,11 @@ function InjectedScriptHostClass() ...@@ -7,6 +7,11 @@ function InjectedScriptHostClass()
{ {
} }
/**
* @param {*} obj
*/
InjectedScriptHostClass.prototype.nullifyPrototype = function(obj) {}
/** /**
* @param {*} obj * @param {*} obj
* @return {string} * @return {string}
......
...@@ -55,6 +55,9 @@ v8::Local<v8::Object> V8InjectedScriptHost::create( ...@@ -55,6 +55,9 @@ v8::Local<v8::Object> V8InjectedScriptHost::create(
USE(success); USE(success);
v8::Local<v8::External> debuggerExternal = v8::Local<v8::External> debuggerExternal =
v8::External::New(isolate, inspector); v8::External::New(isolate, inspector);
setFunctionProperty(context, injectedScriptHost, "nullifyPrototype",
V8InjectedScriptHost::nullifyPrototypeCallback,
debuggerExternal);
setFunctionProperty(context, injectedScriptHost, "internalConstructorName", setFunctionProperty(context, injectedScriptHost, "internalConstructorName",
V8InjectedScriptHost::internalConstructorNameCallback, V8InjectedScriptHost::internalConstructorNameCallback,
debuggerExternal); debuggerExternal);
...@@ -77,6 +80,16 @@ v8::Local<v8::Object> V8InjectedScriptHost::create( ...@@ -77,6 +80,16 @@ v8::Local<v8::Object> V8InjectedScriptHost::create(
return injectedScriptHost; return injectedScriptHost;
} }
void V8InjectedScriptHost::nullifyPrototypeCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
CHECK(info.Length() == 1 && info[0]->IsObject());
v8::Isolate* isolate = info.GetIsolate();
info[0]
.As<v8::Object>()
->SetPrototype(isolate->GetCurrentContext(), v8::Null(isolate))
.ToChecked();
}
void V8InjectedScriptHost::internalConstructorNameCallback( void V8InjectedScriptHost::internalConstructorNameCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) { const v8::FunctionCallbackInfo<v8::Value>& info) {
if (info.Length() < 1 || !info[0]->IsObject()) return; if (info.Length() < 1 || !info[0]->IsObject()) return;
......
...@@ -27,6 +27,8 @@ class V8InjectedScriptHost { ...@@ -27,6 +27,8 @@ class V8InjectedScriptHost {
static v8::Local<v8::Object> create(v8::Local<v8::Context>, V8InspectorImpl*); static v8::Local<v8::Object> create(v8::Local<v8::Context>, V8InspectorImpl*);
private: private:
static void nullifyPrototypeCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void internalConstructorNameCallback( static void internalConstructorNameCallback(
const v8::FunctionCallbackInfo<v8::Value>&); const v8::FunctionCallbackInfo<v8::Value>&);
static void formatAccessorsAsProperties( static void formatAccessorsAsProperties(
......
...@@ -6,6 +6,7 @@ const expression = ` ...@@ -6,6 +6,7 @@ const expression = `
Object.defineProperty(Object.prototype, 'RemoteObject', { Object.defineProperty(Object.prototype, 'RemoteObject', {
configurable: true, configurable: true,
set(v) { set(v) {
console.log("Should never be called");
delete Object.prototype.RemoteObject; delete Object.prototype.RemoteObject;
this.RemoteObject = v; this.RemoteObject = v;
...@@ -25,6 +26,7 @@ const expression = ` ...@@ -25,6 +26,7 @@ const expression = `
detachInspector(); detachInspector();
attachInspector(); attachInspector();
console.log("First inspector activity after attaching inspector"); console.log("First inspector activity after attaching inspector");
console.log("End of test");
`; `;
Protocol.Runtime.enable(); Protocol.Runtime.enable();
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
'./protocol-test.js', './protocol-test.js',
'./runtime/', './runtime/',
'./testcfg.py', './testcfg.py',
'../../src/inspector/injected-script-source.js',
'<(PRODUCT_DIR)/inspector-test<(EXECUTABLE_SUFFIX)', '<(PRODUCT_DIR)/inspector-test<(EXECUTABLE_SUFFIX)',
], ],
}, },
......
...@@ -317,3 +317,38 @@ InspectorTest._dispatchMessage = function(messageObject) ...@@ -317,3 +317,38 @@ InspectorTest._dispatchMessage = function(messageObject)
InspectorTest.loadScript = function(fileName) { InspectorTest.loadScript = function(fileName) {
InspectorTest.addScript(utils.read(fileName)); InspectorTest.addScript(utils.read(fileName));
} }
InspectorTest.setupInjectedScriptEnvironment = function(debug) {
let scriptSource = '';
// First define all getters on Object.prototype.
let injectedScriptSource = utils.read('src/inspector/injected-script-source.js');
let getterRegex = /\.[a-zA-Z0-9]+/g;
let match;
let getters = new Set();
while (match = getterRegex.exec(injectedScriptSource)) {
getters.add(match[0].substr(1));
}
// TODO(kozyatinskiy): pass builtins to injected script source.
getters.delete('constructor');
scriptSource += `(function installSettersAndGetters() {
let defineProperty = Object.defineProperty;
let ObjectPrototype = Object.prototype;\n`;
scriptSource += Array.from(getters).map(getter => `
defineProperty(ObjectPrototype, '${getter}', {
set() { debugger; throw 42; }, get() { debugger; throw 42; },
__proto__: null
});
`).join('\n') + '})();';
InspectorTest.addScript(scriptSource);
if (debug) {
InspectorTest.log('WARNING: InspectorTest.setupInjectedScriptEnvironment with debug flag for debugging only and should not be landed.');
InspectorTest.log('WARNING: run test with --expose-inspector-scripts flag to get more details.');
InspectorTest.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Debugger.onPaused(message => {
let callFrames = message.params.callFrames;
InspectorTest.logSourceLocations(callFrames.map(frame => frame.location));
})
}
}
Checks that Runtime.evaluate works with dirty context.
{
method : Runtime.consoleAPICalled
params : {
args : [
[0] : {
description : 42
type : number
value : 42
}
]
executionContextId : <executionContextId>
stackTrace : {
callFrames : [
[0] : {
columnNumber : 8
functionName :
lineNumber : 0
scriptId : <scriptId>
url :
}
]
}
timestamp : <timestamp>
type : log
}
}
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
InspectorTest.log('Checks that Runtime.evaluate works with dirty context.');
InspectorTest.setupInjectedScriptEnvironment();
Protocol.Runtime.enable();
Protocol.Runtime.onConsoleAPICalled(InspectorTest.logMessage);
Protocol.Runtime.evaluate({expression: 'console.log(42)'})
.then(InspectorTest.logMessage)
.then(InspectorTest.completeTest);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment