[inspector] guard against missing CommandLineAPIScope
Fixed: chromium:986051 Change-Id: I01ef94fe43ac5c8734890706a6dccd01e008bfec Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2153215 Reviewed-by: Peter Marshall <petermarshall@chromium.org> Commit-Queue: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#67204}
This commit is contained in:
parent
7d23e5abc0
commit
3b60af8669
@ -783,15 +783,11 @@ static bool isCommandLineAPIGetter(const String16& name) {
|
||||
|
||||
void V8Console::CommandLineAPIScope::accessorGetterCallback(
|
||||
v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
|
||||
CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(
|
||||
info.Data().As<v8::External>()->Value());
|
||||
DCHECK(scope);
|
||||
|
||||
CommandLineAPIScope* scope = *static_cast<CommandLineAPIScope**>(
|
||||
info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
if (scope->m_cleanup) {
|
||||
bool removed = info.Holder()->Delete(context, name).FromMaybe(false);
|
||||
DCHECK(removed);
|
||||
USE(removed);
|
||||
if (scope == nullptr) {
|
||||
USE(info.Holder()->Delete(context, name).FromMaybe(false));
|
||||
return;
|
||||
}
|
||||
v8::Local<v8::Object> commandLineAPI = scope->m_commandLineAPI;
|
||||
@ -815,16 +811,14 @@ void V8Console::CommandLineAPIScope::accessorGetterCallback(
|
||||
void V8Console::CommandLineAPIScope::accessorSetterCallback(
|
||||
v8::Local<v8::Name> name, v8::Local<v8::Value> value,
|
||||
const v8::PropertyCallbackInfo<void>& info) {
|
||||
CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(
|
||||
info.Data().As<v8::External>()->Value());
|
||||
CommandLineAPIScope* scope = *static_cast<CommandLineAPIScope**>(
|
||||
info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
|
||||
if (scope == nullptr) return;
|
||||
v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext();
|
||||
if (!info.Holder()->Delete(context, name).FromMaybe(false)) return;
|
||||
if (!info.Holder()->CreateDataProperty(context, name, value).FromMaybe(false))
|
||||
return;
|
||||
bool removed =
|
||||
scope->m_installedMethods->Delete(context, name).FromMaybe(false);
|
||||
DCHECK(removed);
|
||||
USE(removed);
|
||||
USE(scope->m_installedMethods->Delete(context, name).FromMaybe(false));
|
||||
}
|
||||
|
||||
V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
@ -833,14 +827,15 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
: m_context(context),
|
||||
m_commandLineAPI(commandLineAPI),
|
||||
m_global(global),
|
||||
m_installedMethods(v8::Set::New(context->GetIsolate())),
|
||||
m_cleanup(false) {
|
||||
m_installedMethods(v8::Set::New(context->GetIsolate())) {
|
||||
v8::MicrotasksScope microtasksScope(context->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
v8::Local<v8::Array> names;
|
||||
if (!m_commandLineAPI->GetOwnPropertyNames(context).ToLocal(&names)) return;
|
||||
v8::Local<v8::External> externalThis =
|
||||
v8::External::New(context->GetIsolate(), this);
|
||||
m_thisReference =
|
||||
v8::ArrayBuffer::New(context->GetIsolate(), sizeof(CommandLineAPIScope*));
|
||||
*static_cast<CommandLineAPIScope**>(
|
||||
m_thisReference->GetBackingStore()->Data()) = this;
|
||||
for (uint32_t i = 0; i < names->Length(); ++i) {
|
||||
v8::Local<v8::Value> name;
|
||||
if (!names->Get(context, i).ToLocal(&name) || !name->IsName()) continue;
|
||||
@ -851,7 +846,7 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
->SetAccessor(context, v8::Local<v8::Name>::Cast(name),
|
||||
CommandLineAPIScope::accessorGetterCallback,
|
||||
CommandLineAPIScope::accessorSetterCallback,
|
||||
externalThis, v8::DEFAULT, v8::DontEnum,
|
||||
m_thisReference, v8::DEFAULT, v8::DontEnum,
|
||||
v8::SideEffectType::kHasNoSideEffect)
|
||||
.FromMaybe(false)) {
|
||||
bool removed = m_installedMethods->Delete(context, name).FromMaybe(false);
|
||||
@ -865,7 +860,8 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
|
||||
V8Console::CommandLineAPIScope::~CommandLineAPIScope() {
|
||||
v8::MicrotasksScope microtasksScope(m_context->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
m_cleanup = true;
|
||||
*static_cast<CommandLineAPIScope**>(
|
||||
m_thisReference->GetBackingStore()->Data()) = nullptr;
|
||||
v8::Local<v8::Array> names = m_installedMethods->AsArray();
|
||||
for (uint32_t i = 0; i < names->Length(); ++i) {
|
||||
v8::Local<v8::Value> name;
|
||||
|
@ -42,7 +42,7 @@ class V8Console : public v8::debug::ConsoleDelegate {
|
||||
v8::Local<v8::Object> m_commandLineAPI;
|
||||
v8::Local<v8::Object> m_global;
|
||||
v8::Local<v8::Set> m_installedMethods;
|
||||
bool m_cleanup;
|
||||
v8::Local<v8::ArrayBuffer> m_thisReference;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CommandLineAPIScope);
|
||||
};
|
||||
|
76
test/inspector/runtime/regress-986051-expected.txt
Normal file
76
test/inspector/runtime/regress-986051-expected.txt
Normal file
@ -0,0 +1,76 @@
|
||||
Regression test for 986051
|
||||
Regression test
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
description : 1
|
||||
type : number
|
||||
value : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
exceptionDetails : {
|
||||
columnNumber : 1
|
||||
exception : {
|
||||
className : ReferenceError
|
||||
description : ReferenceError: $0 is not defined at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
exceptionId : <exceptionId>
|
||||
lineNumber : 1
|
||||
scriptId : <scriptId>
|
||||
stackTrace : {
|
||||
callFrames : [
|
||||
[0] : {
|
||||
columnNumber : 0
|
||||
functionName :
|
||||
lineNumber : 0
|
||||
scriptId : <scriptId>
|
||||
url :
|
||||
}
|
||||
]
|
||||
}
|
||||
text : Uncaught
|
||||
}
|
||||
result : {
|
||||
className : ReferenceError
|
||||
description : ReferenceError: $0 is not defined at <anonymous>:1:1
|
||||
objectId : <objectId>
|
||||
subtype : error
|
||||
type : object
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
className : global
|
||||
description : global
|
||||
objectId : <objectId>
|
||||
type : object
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
id : <messageId>
|
||||
result : {
|
||||
result : {
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
}
|
25
test/inspector/runtime/regress-986051.js
Normal file
25
test/inspector/runtime/regress-986051.js
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2020 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 {Protocol} = InspectorTest.start(
|
||||
"Regression test for 986051");
|
||||
|
||||
Protocol.Runtime.enable();
|
||||
(async function() {
|
||||
InspectorTest.log("Regression test");
|
||||
evaluateRepl('1', true);
|
||||
evaluateRepl('$0', false);
|
||||
evaluateRepl('Object.defineProperty(globalThis, "$0", {configurable: false});', true);
|
||||
evaluateRepl('$0', true);
|
||||
evaluateRepl('$0', false);
|
||||
InspectorTest.completeTest();
|
||||
})();
|
||||
|
||||
async function evaluateRepl(expression, includeCommandLineAPI) {
|
||||
InspectorTest.logMessage(await Protocol.Runtime.evaluate({
|
||||
expression,
|
||||
includeCommandLineAPI,
|
||||
replMode: true,
|
||||
}));
|
||||
}
|
Loading…
Reference in New Issue
Block a user