mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
Bug 1043690 part 2. Change the codegen for DOM proxies to ignore named props when looking up property descriptors on [[Set]]. r=efaust
This commit is contained in:
parent
6bc778bcca
commit
b1c1e22da4
@ -83,11 +83,12 @@ GetWindowFromGlobal(JSObject* aGlobal)
|
||||
}
|
||||
|
||||
bool
|
||||
WindowNamedPropertiesHandler::getOwnPropertyDescriptor(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
const
|
||||
WindowNamedPropertiesHandler::getOwnPropDescriptor(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
bool /* unused */,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
const
|
||||
{
|
||||
if (!JSID_IS_STRING(aId)) {
|
||||
// Nothing to do if we're resolving a non-string property.
|
||||
|
@ -28,10 +28,11 @@ public:
|
||||
return false;
|
||||
}
|
||||
virtual bool
|
||||
getOwnPropertyDescriptor(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
const MOZ_OVERRIDE;
|
||||
getOwnPropDescriptor(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
bool /* unused */,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc)
|
||||
const MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
|
@ -9637,13 +9637,14 @@ class CGProxyUnwrap(CGAbstractMethod):
|
||||
type=self.descriptor.nativeType)
|
||||
|
||||
|
||||
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
|
||||
class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod):
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('bool', 'ignoreNamedProps'),
|
||||
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc')]
|
||||
ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args,
|
||||
ClassMethod.__init__(self, "getOwnPropDescriptor", "bool", args,
|
||||
virtual=True, override=True, const=True)
|
||||
self.descriptor = descriptor
|
||||
|
||||
@ -9714,6 +9715,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod):
|
||||
condition = "!HasPropertyOnPrototype(cx, proxy, id)"
|
||||
if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'):
|
||||
condition = "(!isXray || %s)" % condition
|
||||
condition = "!ignoreNamedProps && " + condition
|
||||
if self.descriptor.supportsIndexedProperties():
|
||||
condition = "!IsArrayIndex(index) && " + condition
|
||||
namedGet = (CGIfWrapper(CGProxyNamedGetter(self.descriptor, templateValues),
|
||||
@ -10372,7 +10374,7 @@ class CGDOMJSProxyHandler(CGClass):
|
||||
def __init__(self, descriptor):
|
||||
assert (descriptor.supportsIndexedProperties() or
|
||||
descriptor.supportsNamedProperties())
|
||||
methods = [CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor),
|
||||
methods = [CGDOMJSProxyHandler_getOwnPropDescriptor(descriptor),
|
||||
CGDOMJSProxyHandler_defineProperty(descriptor),
|
||||
ClassUsingDeclaration("mozilla::dom::DOMProxyHandler",
|
||||
"defineProperty"),
|
||||
|
@ -183,6 +183,16 @@ BaseDOMProxyHandler::getPropertyDescriptor(JSContext* cx,
|
||||
return JS_GetPropertyDescriptorById(cx, proto, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const
|
||||
{
|
||||
return getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ false,
|
||||
desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
MutableHandle<JSPropertyDescriptor> desc, bool* defined) const
|
||||
@ -221,7 +231,30 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
if (done) {
|
||||
return true;
|
||||
}
|
||||
return mozilla::dom::BaseDOMProxyHandler::set(cx, proxy, receiver, id, strict, vp);
|
||||
|
||||
// Make sure to ignore our named properties when checking for own
|
||||
// property descriptors for a set.
|
||||
JS::Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ true,
|
||||
&desc)) {
|
||||
return false;
|
||||
}
|
||||
bool descIsOwn = desc.object() != nullptr;
|
||||
if (!desc.object()) {
|
||||
// Don't just use getPropertyDescriptor, unlike BaseProxyHandler::set,
|
||||
// because that would call getOwnPropertyDescriptor on ourselves. Instead,
|
||||
// directly delegate to the proto, if any.
|
||||
JS::Rooted<JSObject*> proto(cx);
|
||||
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
||||
return false;
|
||||
}
|
||||
if (proto && !JS_GetPropertyDescriptorById(cx, proto, id, &desc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id,
|
||||
&desc, descIsOwn, strict, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -49,6 +49,9 @@ public:
|
||||
bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
|
||||
bool watch(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JSObject*> callable) const MOZ_OVERRIDE;
|
||||
@ -70,6 +73,16 @@ protected:
|
||||
virtual bool ownPropNames(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned flags,
|
||||
JS::AutoIdVector& props) const = 0;
|
||||
|
||||
// Hook for subclasses to allow set() to ignore named props while other things
|
||||
// that look at property descriptors see them. This is intentionally not
|
||||
// named getOwnPropertyDescriptor to avoid subclasses that override it hiding
|
||||
// our public getOwnPropertyDescriptor.
|
||||
virtual bool getOwnPropDescriptor(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
bool ignoreNamedProps,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const = 0;
|
||||
};
|
||||
|
||||
class DOMProxyHandler : public BaseDOMProxyHandler
|
||||
|
@ -43,6 +43,7 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure; bug 926547
|
||||
[test_scalarvaluestring.html]
|
||||
skip-if = debug == false
|
||||
[test_sequence_wrapping.html]
|
||||
[test_setWithNamedGetterNoNamedSetter.html]
|
||||
[test_throwing_method_noDCE.html]
|
||||
[test_treat_non_object_as_null.html]
|
||||
[test_traceProtos.html]
|
||||
|
40
dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html
Normal file
40
dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html
Normal file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1043690
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1043690</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1043690">Mozilla Bug 1043690</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<form>
|
||||
<input name="action">
|
||||
</form>
|
||||
</div>
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1043690 **/
|
||||
var f = document.querySelector("form");
|
||||
var i = document.querySelector("input");
|
||||
ise(f.getAttribute("action"), null, "Should have no action attribute");
|
||||
ise(f.action, i, "form.action should be the input");
|
||||
f.action = "http://example.org";
|
||||
ise(f.getAttribute("action"), "http://example.org",
|
||||
"Should have an action attribute now");
|
||||
ise(f.action, i, "form.action should still be the input");
|
||||
i.remove();
|
||||
ise(f.action, "http://example.org/",
|
||||
"form.action should no longer be shadowed");
|
||||
|
||||
|
||||
</script>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user