Commit 4334c213 authored by Erik Luo's avatar Erik Luo Committed by Commit Bot

Whitelist side-effect-free, lazy property IDL callbacks

Marks common callbacks that produce no JS-observable side-effect,
including
- window.window
- window.location
- location.href
- navigator.userAgent

Bug: 829571
Change-Id: I9404104dc2cd30ffeafbfae83c53c0176a28e1b1
Reviewed-on: https://chromium-review.googlesource.com/1026991
Commit-Queue: Erik Luo <luoe@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553788}
parent 4f85f3c0
...@@ -45,6 +45,10 @@ Expression `div.tabIndex` ...@@ -45,6 +45,10 @@ Expression `div.tabIndex`
has side effect: false, expected: false has side effect: false, expected: false
Expression `div.style` Expression `div.style`
has side effect: false, expected: false has side effect: false, expected: false
Expression `location.href`
has side effect: false, expected: false
Expression `navigator.userAgent`
has side effect: false, expected: false
Expression `div.nodeType` Expression `div.nodeType`
has side effect: false, expected: false has side effect: false, expected: false
Expression `div.nodeName` Expression `div.nodeName`
...@@ -162,7 +166,7 @@ has side effect: false, expected: false ...@@ -162,7 +166,7 @@ has side effect: false, expected: false
Expression `performance` Expression `performance`
has side effect: false, expected: false has side effect: false, expected: false
Expression `window` Expression `window`
has side effect: true, expected: true has side effect: false, expected: false
Expression `window.location` Expression `location`
has side effect: true, expected: true has side effect: false, expected: false
...@@ -54,6 +54,12 @@ ...@@ -54,6 +54,12 @@
await checkHasNoSideEffect(`div.tabIndex`); await checkHasNoSideEffect(`div.tabIndex`);
await checkHasNoSideEffect(`div.style`); await checkHasNoSideEffect(`div.style`);
// Location
await checkHasNoSideEffect(`location.href`);
// Navigator
await checkHasNoSideEffect(`navigator.userAgent`);
// Node // Node
var testNodes = ['div', 'document', 'textNode']; var testNodes = ['div', 'document', 'textNode'];
for (var node of testNodes) { for (var node of testNodes) {
...@@ -88,10 +94,8 @@ ...@@ -88,10 +94,8 @@
await checkHasNoSideEffect(`history`); await checkHasNoSideEffect(`history`);
await checkHasNoSideEffect(`navigator`); await checkHasNoSideEffect(`navigator`);
await checkHasNoSideEffect(`performance`); await checkHasNoSideEffect(`performance`);
await checkHasNoSideEffect(`window`);
// TODO(luoe): add support for LazyData properties. await checkHasNoSideEffect(`location`);
await checkHasSideEffect(`window`);
await checkHasSideEffect(`window.location`);
testRunner.completeTest(); testRunner.completeTest();
......
...@@ -65,22 +65,26 @@ void InstallAttributeInternal( ...@@ -65,22 +65,26 @@ void InstallAttributeInternal(
v8::AccessorNameGetterCallback getter = attribute.getter; v8::AccessorNameGetterCallback getter = attribute.getter;
v8::AccessorNameSetterCallback setter = attribute.setter; v8::AccessorNameSetterCallback setter = attribute.setter;
DCHECK_EQ(attribute.getter_side_effect_type, v8::SideEffectType getter_side_effect_type =
V8DOMConfiguration::kHasSideEffect); attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
? v8::SideEffectType::kHasNoSideEffect
: v8::SideEffectType::kHasSideEffect;
DCHECK(attribute.property_location_configuration); DCHECK(attribute.property_location_configuration);
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnInstance) { V8DOMConfiguration::kOnInstance) {
instance_template->SetNativeDataProperty( instance_template->SetNativeDataProperty(
name, getter, setter, v8::Local<v8::Value>(), name, getter, setter, v8::Local<v8::Value>(),
static_cast<v8::PropertyAttribute>(attribute.attribute), static_cast<v8::PropertyAttribute>(attribute.attribute),
v8::Local<v8::AccessorSignature>()); v8::Local<v8::AccessorSignature>(), v8::AccessControl::DEFAULT,
getter_side_effect_type);
} }
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnPrototype) { V8DOMConfiguration::kOnPrototype) {
prototype_template->SetNativeDataProperty( prototype_template->SetNativeDataProperty(
name, getter, setter, v8::Local<v8::Value>(), name, getter, setter, v8::Local<v8::Value>(),
static_cast<v8::PropertyAttribute>(attribute.attribute), static_cast<v8::PropertyAttribute>(attribute.attribute),
v8::Local<v8::AccessorSignature>()); v8::Local<v8::AccessorSignature>(), v8::AccessControl::DEFAULT,
getter_side_effect_type);
} }
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnInterface) V8DOMConfiguration::kOnInterface)
...@@ -105,18 +109,23 @@ void InstallAttributeInternal( ...@@ -105,18 +109,23 @@ void InstallAttributeInternal(
const unsigned location = config.property_location_configuration; const unsigned location = config.property_location_configuration;
DCHECK(location); DCHECK(location);
DCHECK_EQ(config.getter_side_effect_type, V8DOMConfiguration::kHasSideEffect); v8::SideEffectType getter_side_effect_type =
config.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
? v8::SideEffectType::kHasNoSideEffect
: v8::SideEffectType::kHasSideEffect;
v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Context> context = isolate->GetCurrentContext();
if (location & V8DOMConfiguration::kOnInstance && !instance.IsEmpty()) { if (location & V8DOMConfiguration::kOnInstance && !instance.IsEmpty()) {
instance instance
->SetNativeDataProperty(context, name, getter, setter, ->SetNativeDataProperty(context, name, getter, setter,
v8::Local<v8::Value>(), attribute) v8::Local<v8::Value>(), attribute,
getter_side_effect_type)
.ToChecked(); .ToChecked();
} }
if (location & V8DOMConfiguration::kOnPrototype && !prototype.IsEmpty()) { if (location & V8DOMConfiguration::kOnPrototype && !prototype.IsEmpty()) {
prototype prototype
->SetNativeDataProperty(context, name, getter, setter, ->SetNativeDataProperty(context, name, getter, setter,
v8::Local<v8::Value>(), attribute) v8::Local<v8::Value>(), attribute,
getter_side_effect_type)
.ToChecked(); .ToChecked();
} }
if (location & V8DOMConfiguration::kOnInterface) if (location & V8DOMConfiguration::kOnInterface)
...@@ -134,20 +143,24 @@ void InstallLazyDataAttributeInternal( ...@@ -134,20 +143,24 @@ void InstallLazyDataAttributeInternal(
DCHECK(!attribute.setter); DCHECK(!attribute.setter);
DCHECK_EQ(attribute.world_configuration, V8DOMConfiguration::kAllWorlds); DCHECK_EQ(attribute.world_configuration, V8DOMConfiguration::kAllWorlds);
DCHECK_EQ(attribute.getter_side_effect_type, v8::SideEffectType getter_side_effect_type =
V8DOMConfiguration::kHasSideEffect); attribute.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect
? v8::SideEffectType::kHasNoSideEffect
: v8::SideEffectType::kHasSideEffect;
DCHECK(attribute.property_location_configuration); DCHECK(attribute.property_location_configuration);
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnInstance) { V8DOMConfiguration::kOnInstance) {
instance_template->SetLazyDataProperty( instance_template->SetLazyDataProperty(
name, getter, v8::Local<v8::Value>(), name, getter, v8::Local<v8::Value>(),
static_cast<v8::PropertyAttribute>(attribute.attribute)); static_cast<v8::PropertyAttribute>(attribute.attribute),
getter_side_effect_type);
} }
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnPrototype) { V8DOMConfiguration::kOnPrototype) {
prototype_template->SetLazyDataProperty( prototype_template->SetLazyDataProperty(
name, getter, v8::Local<v8::Value>(), name, getter, v8::Local<v8::Value>(),
static_cast<v8::PropertyAttribute>(attribute.attribute)); static_cast<v8::PropertyAttribute>(attribute.attribute),
getter_side_effect_type);
} }
if (attribute.property_location_configuration & if (attribute.property_location_configuration &
V8DOMConfiguration::kOnInterface) V8DOMConfiguration::kOnInterface)
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
// TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject]. // TODO(foolip): |ancestorOrigins| should have [Unforgeable, SameObject].
readonly attribute DOMStringList ancestorOrigins; readonly attribute DOMStringList ancestorOrigins;
[SetterCallWith=(CurrentWindow,EnteredWindow), CrossOrigin=Setter, RaisesException=Setter] attribute URLString href; [Affects=Nothing, SetterCallWith=(CurrentWindow,EnteredWindow), CrossOrigin=Setter, RaisesException=Setter] attribute URLString href;
// TODO(yukishiino): Use [Unforgeable] stringifier instead of toString. // TODO(yukishiino): Use [Unforgeable] stringifier instead of toString.
DOMString toString(); DOMString toString();
[MeasureAs=LocationOrigin] readonly attribute USVString origin; [MeasureAs=LocationOrigin] readonly attribute USVString origin;
......
...@@ -41,5 +41,5 @@ ...@@ -41,5 +41,5 @@
readonly attribute DOMString product; // constant "Gecko" readonly attribute DOMString product; // constant "Gecko"
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22555 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22555
// boolean taintEnabled(); // constant false // boolean taintEnabled(); // constant false
readonly attribute DOMString userAgent; [Affects=Nothing] readonly attribute DOMString userAgent;
}; };
...@@ -34,12 +34,12 @@ ...@@ -34,12 +34,12 @@
] interface Window : EventTarget { ] interface Window : EventTarget {
// the current browsing context // the current browsing context
// FIXME: The spec uses the WindowProxy type for this and many other attributes. // FIXME: The spec uses the WindowProxy type for this and many other attributes.
[Unforgeable, CrossOrigin] readonly attribute Window window; [Affects=Nothing, Unforgeable, CrossOrigin] readonly attribute Window window;
[Replaceable, CrossOrigin] readonly attribute Window self; [Replaceable, CrossOrigin] readonly attribute Window self;
[Affects=Nothing, Unforgeable, CachedAccessor] readonly attribute Document document; [Affects=Nothing, Unforgeable, CachedAccessor] readonly attribute Document document;
[Replaceable] readonly attribute DOMString origin; [Replaceable] readonly attribute DOMString origin;
attribute DOMString name; attribute DOMString name;
[PutForwards=href, Unforgeable, CrossOrigin=(Getter,Setter), Custom=Getter] readonly attribute Location location; [Affects=Nothing, PutForwards=href, Unforgeable, CrossOrigin=(Getter,Setter), Custom=Getter] readonly attribute Location location;
[Affects=Nothing] readonly attribute History history; [Affects=Nothing] readonly attribute History history;
[Replaceable, MeasureAs=BarPropLocationbar] readonly attribute BarProp locationbar; [Replaceable, MeasureAs=BarPropLocationbar] readonly attribute BarProp locationbar;
[Replaceable, MeasureAs=BarPropMenubar] readonly attribute BarProp menubar; [Replaceable, MeasureAs=BarPropMenubar] readonly attribute BarProp menubar;
......
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