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) ...@@ -114,14 +114,12 @@ function isArrayLike(obj)
{ {
if (typeof obj !== "object") if (typeof obj !== "object")
return false; return false;
try { var splice = InjectedScriptHost.getProperty(obj, "splice");
if (typeof obj.splice === "function") { if (typeof splice === "function") {
if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length")) if (!InjectedScriptHost.objectHasOwnProperty(/** @type {!Object} */ (obj), "length"))
return false; return false;
var len = obj.length; var len = InjectedScriptHost.getProperty(obj, "length");
return typeof len === "number" && isUInt32(len); return typeof len === "number" && isUInt32(len);
}
} catch (e) {
} }
return false; return false;
} }
...@@ -392,7 +390,7 @@ InjectedScript.prototype = { ...@@ -392,7 +390,7 @@ InjectedScript.prototype = {
_propertyDescriptors: function(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly, propertyNamesOnly) _propertyDescriptors: function(object, addPropertyIfNeeded, ownProperties, accessorPropertiesOnly, propertyNamesOnly)
{ {
var descriptors = []; var descriptors = [];
descriptors.__proto__ = null; InjectedScriptHost.nullifyPrototype(descriptors);
var propertyProcessed = { __proto__: null }; var propertyProcessed = { __proto__: null };
var subtype = InjectedScriptHost.subtype(object); var subtype = InjectedScriptHost.subtype(object);
...@@ -423,6 +421,7 @@ InjectedScript.prototype = { ...@@ -423,6 +421,7 @@ InjectedScript.prototype = {
var descriptor; var descriptor;
try { try {
descriptor = Object.getOwnPropertyDescriptor(o, property); descriptor = Object.getOwnPropertyDescriptor(o, property);
InjectedScriptHost.nullifyPrototype(descriptor);
var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor); var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor);
if (accessorPropertiesOnly && !isAccessorProperty) if (accessorPropertiesOnly && !isAccessorProperty)
continue; continue;
...@@ -437,14 +436,14 @@ InjectedScript.prototype = { ...@@ -437,14 +436,14 @@ InjectedScript.prototype = {
} catch (e) { } catch (e) {
if (accessorPropertiesOnly) if (accessorPropertiesOnly)
continue; 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, // Not all bindings provide proper descriptors. Fall back to the non-configurable, non-enumerable,
// non-writable property. // non-writable property.
if (!descriptor) { if (!descriptor) {
try { try {
descriptor = { value: o[property], writable: false }; descriptor = { value: o[property], writable: false, __proto__: null };
} catch (e) { } catch (e) {
// Silent catch. // Silent catch.
continue; continue;
......
...@@ -12,6 +12,13 @@ function InjectedScriptHostClass() ...@@ -12,6 +12,13 @@ function InjectedScriptHostClass()
*/ */
InjectedScriptHostClass.prototype.nullifyPrototype = function(obj) {} InjectedScriptHostClass.prototype.nullifyPrototype = function(obj) {}
/**
* @param {*} obj
* @param {string} name
* @return {*}
*/
InjectedScriptHostClass.prototype.getProperty = function(obj, name) {}
/** /**
* @param {*} obj * @param {*} obj
* @return {string} * @return {string}
......
...@@ -58,6 +58,9 @@ v8::Local<v8::Object> V8InjectedScriptHost::create( ...@@ -58,6 +58,9 @@ v8::Local<v8::Object> V8InjectedScriptHost::create(
setFunctionProperty(context, injectedScriptHost, "nullifyPrototype", setFunctionProperty(context, injectedScriptHost, "nullifyPrototype",
V8InjectedScriptHost::nullifyPrototypeCallback, V8InjectedScriptHost::nullifyPrototypeCallback,
debuggerExternal); debuggerExternal);
setFunctionProperty(context, injectedScriptHost, "getProperty",
V8InjectedScriptHost::getPropertyCallback,
debuggerExternal);
setFunctionProperty(context, injectedScriptHost, "internalConstructorName", setFunctionProperty(context, injectedScriptHost, "internalConstructorName",
V8InjectedScriptHost::internalConstructorNameCallback, V8InjectedScriptHost::internalConstructorNameCallback,
debuggerExternal); debuggerExternal);
...@@ -90,6 +93,24 @@ void V8InjectedScriptHost::nullifyPrototypeCallback( ...@@ -90,6 +93,24 @@ void V8InjectedScriptHost::nullifyPrototypeCallback(
.ToChecked(); .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( 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;
......
...@@ -29,6 +29,7 @@ class V8InjectedScriptHost { ...@@ -29,6 +29,7 @@ class V8InjectedScriptHost {
private: private:
static void nullifyPrototypeCallback( static void nullifyPrototypeCallback(
const v8::FunctionCallbackInfo<v8::Value>&); const v8::FunctionCallbackInfo<v8::Value>&);
static void getPropertyCallback(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(
......
...@@ -345,6 +345,7 @@ InspectorTest.setupInjectedScriptEnvironment = function(debug) { ...@@ -345,6 +345,7 @@ InspectorTest.setupInjectedScriptEnvironment = function(debug) {
if (debug) { if (debug) {
InspectorTest.log('WARNING: InspectorTest.setupInjectedScriptEnvironment with debug flag for debugging only and should not be landed.'); 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: 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(); InspectorTest.setupScriptMap();
Protocol.Debugger.enable(); Protocol.Debugger.enable();
Protocol.Debugger.onPaused(message => { Protocol.Debugger.onPaused(message => {
......
...@@ -827,3 +827,12 @@ Running test: testObjInheritsGetterProperty ...@@ -827,3 +827,12 @@ Running test: testObjInheritsGetterProperty
] ]
type : object type : object
} }
Running test: testObjWithArrayAsProto
{
description : Array
overflow : false
properties : [
]
type : object
}
...@@ -65,6 +65,8 @@ var objInheritsGetterProperty = {__proto__: parentObj}; ...@@ -65,6 +65,8 @@ var objInheritsGetterProperty = {__proto__: parentObj};
allowAccessorFormatting(objInheritsGetterProperty); allowAccessorFormatting(objInheritsGetterProperty);
`); `);
InspectorTest.setupInjectedScriptEnvironment();
InspectorTest.runTestSuite([ InspectorTest.runTestSuite([
function testObjectPropertiesPreview(next) function testObjectPropertiesPreview(next)
{ {
...@@ -134,5 +136,12 @@ InspectorTest.runTestSuite([ ...@@ -134,5 +136,12 @@ InspectorTest.runTestSuite([
Protocol.Runtime.evaluate({ "expression": "objInheritsGetterProperty", "generatePreview": true }) Protocol.Runtime.evaluate({ "expression": "objInheritsGetterProperty", "generatePreview": true })
.then(result => InspectorTest.logMessage(result.result.result.preview)) .then(result => InspectorTest.logMessage(result.result.result.preview))
.then(next); .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