Bug 819131 - Preserve reflector delegate weak map keys. r=billm

This commit is contained in:
Andrew McCreight 2012-05-25 09:07:24 -07:00
parent 2229501656
commit ca5d0dc894
4 changed files with 76 additions and 8 deletions

View File

@ -262,6 +262,22 @@ WeakMap_delete(JSContext *cx, unsigned argc, Value *vp)
return CallNonGenericMethod<IsWeakMap, WeakMap_delete_impl>(cx, args);
}
static bool
TryPreserveReflector(JSContext *cx, HandleObject obj)
{
if (obj->getClass()->ext.isWrappedNative ||
(obj->getClass()->flags & JSCLASS_IS_DOMJSCLASS) ||
(obj->isProxy() && GetProxyHandler(obj)->family() == GetListBaseHandlerFamily()))
{
JS_ASSERT(cx->runtime->preserveWrapperCallback);
if (!cx->runtime->preserveWrapperCallback(cx, obj)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_WEAKMAP_KEY);
return false;
}
}
return true;
}
JS_ALWAYS_INLINE bool
WeakMap_set_impl(JSContext *cx, CallArgs args)
{
@ -291,15 +307,13 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
}
// Preserve wrapped native keys to prevent wrapper optimization.
if (key->getClass()->ext.isWrappedNative ||
(key->getClass()->flags & JSCLASS_IS_DOMJSCLASS) ||
(key->isProxy() && GetProxyHandler(key)->family() == GetListBaseHandlerFamily()))
{
JS_ASSERT(cx->runtime->preserveWrapperCallback);
if (!cx->runtime->preserveWrapperCallback(cx, key)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_WEAKMAP_KEY);
if (!TryPreserveReflector(cx, key))
return false;
if (JSWeakmapKeyDelegateOp op = key->getClass()->ext.weakmapKeyDelegateOp) {
RootedObject delegate(cx, op(key));
if (delegate && !TryPreserveReflector(cx, delegate))
return false;
}
}
JS_ASSERT(key->compartment() == thisObj->compartment());

View File

@ -91,6 +91,8 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
file_bug802557.html \
test_bug803730.html \
test_bug809547.html \
file_crosscompartment_weakmap.html \
test_crosscompartment_weakmap.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,8 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Cross-Compartment DOM WeakMaps</title>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test Cross-Compartment DOM WeakMaps</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<script type="application/javascript">
var my_map = WeakMap();
function setup() {
var item = window.frames[0].document.querySelector("body");
my_map.set(item, "success_string");
var navi_fail = false;
try {
my_map.set(window.frames[0].navigator, 1);
} catch (e) {
navi_fail = true;
}
ok(navi_fail, "Using window.navigator as a weak map key across compartments should produce an exception because it can't be wrapper preserved.");
}
function runTest() {
setup();
SpecialPowers.forceGC();
SpecialPowers.forceCC();
SpecialPowers.forceGC();
SpecialPowers.forceCC();
var item = window.frames[0].document.querySelector("body");
is(my_map.get(item), "success_string", "Preserve reflectors used cross-compartment as weak map keys.");
}
</script>
<iframe src="file_crosscompartment_weakmap.html" onload="runTest()"></iframe>
</pre>
</body>
</html>