Bug 1430164. Stop doing weird sandbox-callable-wrapping for DOM constructors. r=bholley

This fixes DOM constructor identity in web extension content scripts to work as expected.

MozReview-Commit-ID: Ab4sFWiMU6c
This commit is contained in:
Boris Zbarsky 2018-01-12 14:28:28 -05:00
parent ee77b9ffec
commit 4b3ce3fd3c
4 changed files with 65 additions and 1 deletions

View File

@ -2617,6 +2617,20 @@ UseDOMXray(JSObject* obj)
IsDOMIfaceAndProtoClass(clasp);
}
inline bool
IsDOMConstructor(JSObject* obj)
{
if (JS_IsNativeFunction(obj, dom::Constructor)) {
// NamedConstructor, like Image
return true;
}
const js::Class* clasp = js::GetObjectClass(obj);
// Check for a DOM interface object.
return dom::IsDOMIfaceAndProtoClass(clasp) &&
dom::DOMIfaceAndProtoJSClass::FromJSClass(clasp)->mType == dom::eInterface;
}
#ifdef DEBUG
inline bool
HasConstructor(JSObject* obj)

View File

@ -756,6 +756,19 @@ bool WrapAccessorFunction(JSContext* cx, Op& op, PropertyDescriptor* desc,
return true;
}
static bool
IsMaybeWrappedDOMConstructor(JSObject* obj)
{
// We really care about the underlying object here, which might be wrapped
// in cross-compartment wrappers.
obj = js::CheckedUnwrap(obj);
if (!obj) {
return false;
}
return dom::IsDOMConstructor(obj);
}
bool
xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext* cx,
JS::Handle<JSObject*> proxy,
@ -780,7 +793,11 @@ xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext* cx,
return false;
if (desc.value().isObject()) {
RootedObject val (cx, &desc.value().toObject());
if (JS::IsCallable(val)) {
if (JS::IsCallable(val) &&
// Don't wrap DOM constructors: they don't care about the "this"
// they're invoked with anyway, being constructors. And if we wrap
// them here we break invariants like Node == Node and whatnot.
!IsMaybeWrappedDOMConstructor(val)) {
val = WrapCallable(cx, val, proxy);
if (!val)
return false;

View File

@ -89,6 +89,7 @@ skip-if = os == 'win' || os == 'mac' || (os == 'linux' && !debug) # bug 1131110,
[test_bug1126911.html]
[test_bug1281071.xul]
[test_bug1390159.xul]
[test_bug1430164.html]
[test_chrometoSource.xul]
[test_cloneInto.xul]
[test_cows.xul]

View File

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1430164
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1430164</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1430164 **/
var Cu = Components.utils;
var s = new Cu.Sandbox(window, { sandboxPrototype: window } );
var t;
var desc;
try {
t = Cu.evalInSandbox('Node === Node', s);
ok(t, "Object identity should be sane");
t = Cu.evalInSandbox('Node === this.Node', s);
ok(t, "Node should match this.Node in toplevel");
t = Cu.evalInSandbox('Node === window.Node', s);
ok(t, "Node should match window.Node");
} catch (e) {
ok(false, "Should not get an exception: " + e);
}
</script>
</head>
</html>