Commit 6c221532 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[inspector] better isArrayLike for injected-script-source.js

We should never check existing of the property by typeof obj.name check.

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

Review-Url: https://codereview.chromium.org/2767323002
Cr-Commit-Position: refs/heads/master@{#44113}
parent 09050c8a
......@@ -114,14 +114,12 @@ function isArrayLike(obj)
{
if (typeof obj !== "object")
return false;
try {
if (typeof obj.splice === "function") {
if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length"))
return false;
var len = obj.length;
return typeof len === "number" && isUInt32(len);
}
} catch (e) {
var splice = InjectedScriptHost.getProperty(obj, "splice");
if (typeof splice === "function") {
if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length"))
return false;
var len = InjectedScriptHost.getProperty(obj, "length");
return typeof len === "number" && isUInt32(len);
}
return false;
}
......@@ -392,7 +390,7 @@ InjectedScript.prototype = {
_propertyDescriptors: function(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly, propertyNamesOnly)
{
var descriptors = [];
descriptors.__proto__ = null;
InjectedScriptHost.nullifyPrototype(descriptors);
var propertyProcessed = { __proto__: null };
var subtype = InjectedScriptHost.subtype(object);
......@@ -423,6 +421,7 @@ InjectedScript.prototype = {
var descriptor;
try {
descriptor = Object.getOwnPropertyDescriptor(o, property);
InjectedScriptHost.nullifyPrototype(descriptor);
var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor);
if (accessorPropertiesOnly && !isAccessorProperty)
continue;
......@@ -437,14 +436,14 @@ InjectedScript.prototype = {
} catch (e) {
if (accessorPropertiesOnly)
continue;
descriptor = { value: e, wasThrown: true };
descriptor = { value: e, wasThrown: true, __proto__: null };
}
// Not all bindings provide proper descriptors. Fall back to the non-configurable, non-enumerable,
// non-writable property.
if (!descriptor) {
try {
descriptor = { value: o[property], writable: false };
descriptor = { value: o[property], writable: false, __proto__: null };
} catch (e) {
// Silent catch.
continue;
......
......@@ -12,6 +12,13 @@ function InjectedScriptHostClass()
*/
InjectedScriptHostClass.prototype.nullifyPrototype = function(obj) {}
/**
* @param {*} obj
* @param {string} name
* @return {*}
*/
InjectedScriptHostClass.prototype.getProperty = function(obj, name) {}
/**
* @param {*} obj
* @return {string}
......
......@@ -58,6 +58,9 @@ v8::Local<v8::Object> V8InjectedScriptHost::create(
setFunctionProperty(context, injectedScriptHost, "nullifyPrototype",
V8InjectedScriptHost::nullifyPrototypeCallback,
debuggerExternal);
setFunctionProperty(context, injectedScriptHost, "getProperty",
V8InjectedScriptHost::getPropertyCallback,
debuggerExternal);
setFunctionProperty(context, injectedScriptHost, "internalConstructorName",
V8InjectedScriptHost::internalConstructorNameCallback,
debuggerExternal);
......@@ -90,6 +93,24 @@ void V8InjectedScriptHost::nullifyPrototypeCallback(
.ToChecked();
}
void V8InjectedScriptHost::getPropertyCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
CHECK(info.Length() == 2 && info[1]->IsString());
if (!info[0]->IsObject()) return;
v8::Isolate* isolate = info.GetIsolate();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::TryCatch tryCatch(isolate);
v8::Isolate::DisallowJavascriptExecutionScope throwJs(
isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
v8::Local<v8::Value> property;
if (info[0]
.As<v8::Object>()
->Get(context, v8::Local<v8::String>::Cast(info[1]))
.ToLocal(&property)) {
info.GetReturnValue().Set(property);
}
}
void V8InjectedScriptHost::internalConstructorNameCallback(
const v8::FunctionCallbackInfo<v8::Value>& info) {
if (info.Length() < 1 || !info[0]->IsObject()) return;
......
......@@ -29,6 +29,7 @@ class V8InjectedScriptHost {
private:
static void nullifyPrototypeCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void getPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>&);
static void internalConstructorNameCallback(
const v8::FunctionCallbackInfo<v8::Value>&);
static void formatAccessorsAsProperties(
......
......@@ -345,6 +345,7 @@ InspectorTest.setupInjectedScriptEnvironment = function(debug) {
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.log('WARNING: you can additionally comment rjsmin in xxd.py to get unminified injected-script-source.js.');
InspectorTest.setupScriptMap();
Protocol.Debugger.enable();
Protocol.Debugger.onPaused(message => {
......
......@@ -827,3 +827,12 @@ Running test: testObjInheritsGetterProperty
]
type : object
}
Running test: testObjWithArrayAsProto
{
description : Array
overflow : false
properties : [
]
type : object
}
......@@ -65,6 +65,8 @@ var objInheritsGetterProperty = {__proto__: parentObj};
allowAccessorFormatting(objInheritsGetterProperty);
`);
InspectorTest.setupInjectedScriptEnvironment();
InspectorTest.runTestSuite([
function testObjectPropertiesPreview(next)
{
......@@ -134,5 +136,12 @@ InspectorTest.runTestSuite([
Protocol.Runtime.evaluate({ "expression": "objInheritsGetterProperty", "generatePreview": true })
.then(result => InspectorTest.logMessage(result.result.result.preview))
.then(next);
},
function testObjWithArrayAsProto(next)
{
Protocol.Runtime.evaluate({ "expression": "Object.create([1,2])", "generatePreview": true })
.then(result => InspectorTest.logMessage(result.result.result.preview))
.then(next);
}
]);
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