зеркало из https://github.com/mozilla/gecko-dev.git
Bug 819131 - Preserve reflector delegate weak map keys. r=billm
This commit is contained in:
Родитель
63c963b476
Коммит
b6b93daa9e
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Cross-Compartment DOM WeakMaps</title>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -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>
|
Загрузка…
Ссылка в новой задаче