Commit 363996f7 authored by Erik Luo's avatar Erik Luo Committed by Commit Bot

[inspector] whitelist side-effect-free console API callbacks

This CL whitelists Console Command Line API callbacks on the V8 side.

Bug: chromium:810176
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I7afdd6bd4263cb4cb18bdf02b37ab3e822ae5c96
Reviewed-on: https://chromium-review.googlesource.com/1016094
Commit-Queue: Erik Luo <luoe@chromium.org>
Reviewed-by: 's avatarAleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52747}
parent bca2b694
......@@ -162,16 +162,16 @@ void returnDataCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(info.Data());
}
void createBoundFunctionProperty(v8::Local<v8::Context> context,
v8::Local<v8::Object> console,
v8::Local<v8::Value> data, const char* name,
v8::FunctionCallback callback,
const char* description = nullptr) {
void createBoundFunctionProperty(
v8::Local<v8::Context> context, v8::Local<v8::Object> console,
v8::Local<v8::Value> data, const char* name, v8::FunctionCallback callback,
const char* description = nullptr,
v8::SideEffectType side_effect_type = v8::SideEffectType::kHasSideEffect) {
v8::Local<v8::String> funcName =
toV8StringInternalized(context->GetIsolate(), name);
v8::Local<v8::Function> func;
if (!v8::Function::New(context, callback, data, 0,
v8::ConstructorBehavior::kThrow)
v8::ConstructorBehavior::kThrow, side_effect_type)
.ToLocal(&func))
return;
func->SetName(funcName);
......@@ -180,7 +180,8 @@ void createBoundFunctionProperty(v8::Local<v8::Context> context,
toV8String(context->GetIsolate(), description);
v8::Local<v8::Function> toStringFunction;
if (v8::Function::New(context, returnDataCallback, returnValue, 0,
v8::ConstructorBehavior::kThrow)
v8::ConstructorBehavior::kThrow,
v8::SideEffectType::kHasNoSideEffect)
.ToLocal(&toStringFunction))
createDataProperty(context, func, toV8StringInternalized(
context->GetIsolate(), "toString"),
......@@ -651,9 +652,9 @@ void V8Console::installMemoryGetter(v8::Local<v8::Context> context,
v8::Local<v8::External> data = v8::External::New(isolate, this);
console->SetAccessorProperty(
toV8StringInternalized(isolate, "memory"),
v8::Function::New(context,
&V8Console::call<&V8Console::memoryGetterCallback>,
data, 0, v8::ConstructorBehavior::kThrow)
v8::Function::New(
context, &V8Console::call<&V8Console::memoryGetterCallback>, data, 0,
v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasNoSideEffect)
.ToLocalChecked(),
v8::Function::New(context,
&V8Console::call<&V8Console::memorySetterCallback>,
......@@ -701,10 +702,12 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI(
createBoundFunctionProperty(context, commandLineAPI, data, "keys",
&V8Console::call<&V8Console::keysCallback>,
"function keys(object) { [Command Line API] }");
"function keys(object) { [Command Line API] }",
v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "values",
&V8Console::call<&V8Console::valuesCallback>,
"function values(object) { [Command Line API] }");
"function values(object) { [Command Line API] }",
v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(
context, commandLineAPI, data, "debug",
&V8Console::call<&V8Console::debugFunctionCallback>,
......@@ -734,17 +737,23 @@ v8::Local<v8::Object> V8Console::createCommandLineAPI(
"function queryObjects(constructor) { [Command Line API] }");
createBoundFunctionProperty(
context, commandLineAPI, data, "$_",
&V8Console::call<&V8Console::lastEvaluationResultCallback>);
&V8Console::call<&V8Console::lastEvaluationResultCallback>, nullptr,
v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "$0",
&V8Console::call<&V8Console::inspectedObject0>);
&V8Console::call<&V8Console::inspectedObject0>,
nullptr, v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "$1",
&V8Console::call<&V8Console::inspectedObject1>);
&V8Console::call<&V8Console::inspectedObject1>,
nullptr, v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "$2",
&V8Console::call<&V8Console::inspectedObject2>);
&V8Console::call<&V8Console::inspectedObject2>,
nullptr, v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "$3",
&V8Console::call<&V8Console::inspectedObject3>);
&V8Console::call<&V8Console::inspectedObject3>,
nullptr, v8::SideEffectType::kHasNoSideEffect);
createBoundFunctionProperty(context, commandLineAPI, data, "$4",
&V8Console::call<&V8Console::inspectedObject4>);
&V8Console::call<&V8Console::inspectedObject4>,
nullptr, v8::SideEffectType::kHasNoSideEffect);
m_inspector->client()->installAdditionalCommandLineAPI(context,
commandLineAPI);
......@@ -827,7 +836,8 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
->SetAccessor(context, v8::Local<v8::Name>::Cast(name),
CommandLineAPIScope::accessorGetterCallback,
CommandLineAPIScope::accessorSetterCallback,
externalThis, v8::DEFAULT, v8::DontEnum)
externalThis, v8::DEFAULT, v8::DontEnum,
v8::SideEffectType::kHasNoSideEffect)
.FromMaybe(false)) {
bool removed = m_installedMethods->Delete(context, name).FromMaybe(false);
DCHECK(removed);
......
Tests Command Line API evaluations with throwOnSideEffect.
Expression: console.memory
42
Expression: $_
43
Expression: $0
undefined
Expression: $1
undefined
Expression: $2
undefined
Expression: $3
undefined
Expression: $4
undefined
Method: console.debug
EvalError: Possible side-effect in debug-evaluate
function debug() { [native code] }
Method: console.error
EvalError: Possible side-effect in debug-evaluate
function error() { [native code] }
Method: console.info
EvalError: Possible side-effect in debug-evaluate
function info() { [native code] }
Method: console.log
EvalError: Possible side-effect in debug-evaluate
function log() { [native code] }
Method: console.warn
EvalError: Possible side-effect in debug-evaluate
function warn() { [native code] }
Method: console.dir
EvalError: Possible side-effect in debug-evaluate
function dir() { [native code] }
Method: console.dirxml
EvalError: Possible side-effect in debug-evaluate
function dirxml() { [native code] }
Method: console.table
EvalError: Possible side-effect in debug-evaluate
function table() { [native code] }
Method: console.trace
EvalError: Possible side-effect in debug-evaluate
function trace() { [native code] }
Method: console.group
EvalError: Possible side-effect in debug-evaluate
function group() { [native code] }
Method: console.groupEnd
EvalError: Possible side-effect in debug-evaluate
function groupEnd() { [native code] }
Method: console.groupCollapsed
EvalError: Possible side-effect in debug-evaluate
function groupCollapsed() { [native code] }
Method: console.clear
EvalError: Possible side-effect in debug-evaluate
function clear() { [native code] }
Method: console.count
EvalError: Possible side-effect in debug-evaluate
function count() { [native code] }
Method: console.assert
EvalError: Possible side-effect in debug-evaluate
function assert() { [native code] }
Method: console.profile
EvalError: Possible side-effect in debug-evaluate
function profile() { [native code] }
Method: console.profileEnd
EvalError: Possible side-effect in debug-evaluate
function profileEnd() { [native code] }
Method: console.time
EvalError: Possible side-effect in debug-evaluate
function time() { [native code] }
Method: console.timeEnd
EvalError: Possible side-effect in debug-evaluate
function timeEnd() { [native code] }
Method: debug
EvalError: Possible side-effect in debug-evaluate
function debug(function, condition) { [Command Line API] }
Method: undebug
EvalError: Possible side-effect in debug-evaluate
function undebug(function) { [Command Line API] }
Method: monitor
EvalError: Possible side-effect in debug-evaluate
function monitor(function) { [Command Line API] }
Method: unmonitor
EvalError: Possible side-effect in debug-evaluate
function unmonitor(function) { [Command Line API] }
Method: keys
Array(2)
function keys(object) { [Command Line API] }
Method: values
Array(2)
function values(object) { [Command Line API] }
Method: inspect
EvalError: Possible side-effect in debug-evaluate
function inspect(object) { [Command Line API] }
Method: copy
EvalError: Possible side-effect in debug-evaluate
function copy(value) { [Command Line API] }
Method: queryObjects
EvalError: Possible side-effect in debug-evaluate
function queryObjects(constructor) { [Command Line API] }
// Copyright 2018 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.
let {session, contextGroup, Protocol} = InspectorTest.start(
'Tests Command Line API evaluations with throwOnSideEffect.');
session.setupScriptMap();
contextGroup.addScript(`
function f() {
}
var obj = {x: 1, y: 2};
//# sourceURL=test.js`);
Protocol.Runtime.enable();
Protocol.Debugger.enable();
(async function() {
utils.setMemoryInfoForTest(42);
await testExpression('console.memory');
await Protocol.Runtime.evaluate(
{expression: '43', objectGroup: 'console', includeCommandLineAPI: true});
await testExpression('$_');
await testExpression('$0');
await testExpression('$1');
await testExpression('$2');
await testExpression('$3');
await testExpression('$4');
await testMethod('console.debug');
await testMethod('console.error');
await testMethod('console.info');
await testMethod('console.log');
await testMethod('console.warn');
await testMethod('console.dir');
await testMethod('console.dirxml');
await testMethod('console.table');
await testMethod('console.trace');
await testMethod('console.group');
await testMethod('console.groupEnd');
await testMethod('console.groupCollapsed');
await testMethod('console.clear');
await testMethod('console.count');
await testMethod('console.assert');
await testMethod('console.profile');
await testMethod('console.profileEnd');
await testMethod('console.time');
await testMethod('console.timeEnd');
await testMethod('debug', ['f']);
await testMethod('undebug', ['f']);
await testMethod('monitor');
await testMethod('unmonitor');
await testMethod('keys', ['obj']);
await testMethod('values', ['obj']);
await testMethod('inspect');
await testMethod('copy', ['1']);
await testMethod('queryObjects', ['Array']);
InspectorTest.completeTest();
async function testExpression(expression) {
InspectorTest.log(`\nExpression: ${expression}`);
await evaluateAndPrint(expression);
}
async function testMethod(method, args = []) {
InspectorTest.log(`\nMethod: ${method}`);
await evaluateAndPrint(`${method}(${args.join(', ')})`);
await evaluateAndPrint(`${method}.toString()`);
}
async function evaluateAndPrint(expression) {
const result = (await Protocol.Runtime.evaluate({
expression,
throwOnSideEffect: true,
includeCommandLineAPI: true
})).result;
if (result.exceptionDetails)
InspectorTest.logMessage(result.exceptionDetails.exception.description);
else if (result.result)
InspectorTest.logMessage(
result.result.description || result.result.value ||
result.result.type);
}
})();
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