Bug 761620 - Throw an exception for unpreservable weak map keys. r=billm

This commit is contained in:
Andrew McCreight 2012-08-08 11:05:58 -07:00
parent 6c2dc1c4e5
commit 8a8a3e7167
3 changed files with 33 additions and 14 deletions

View File

@ -117,7 +117,7 @@ MSG_DEF(JSMSG_TOO_BIG_TO_ENCODE, 63, 0, JSEXN_INTERNALERR, "data are to bi
MSG_DEF(JSMSG_ARG_INDEX_OUT_OF_RANGE, 64, 1, JSEXN_RANGEERR, "argument {0} accesses an index that is out of range")
MSG_DEF(JSMSG_SPREAD_TOO_LARGE, 65, 0, JSEXN_RANGEERR, "array too large due to spread operand(s)")
MSG_DEF(JSMSG_SOURCE_TOO_LONG, 66, 0, JSEXN_RANGEERR, "source is too long")
MSG_DEF(JSMSG_UNUSED67, 67, 0, JSEXN_NONE, "")
MSG_DEF(JSMSG_BAD_WEAKMAP_KEY, 67, 0, JSEXN_TYPEERR, "cannot use the given object as a weak map key")
MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_INTERNALERR, "bad script XDR magic number")
MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")

View File

@ -249,19 +249,20 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
thisObj->setPrivate(map);
}
// Preserve wrapped native keys to prevent wrapper optimization.
if (key->getClass()->ext.isWrappedNative) {
MOZ_ASSERT(cx->runtime->preserveWrapperCallback, "wrapped native weak map key needs preserveWrapperCallback");
if (!cx->runtime->preserveWrapperCallback(cx, key)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_WEAKMAP_KEY);
return false;
}
}
if (!map->put(key, value)) {
JS_ReportOutOfMemory(cx);
return false;
}
// Preserve wrapped native keys to prevent wrapper optimization.
if (key->getClass()->ext.isWrappedNative) {
if (!cx->runtime->preserveWrapperCallback ||
!cx->runtime->preserveWrapperCallback(cx, key)) {
JS_ReportWarning(cx, "Failed to preserve wrapper of wrapped native weak map key.");
}
}
args.rval().setUndefined();
return true;
}

View File

@ -213,14 +213,32 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=668855
make_live_map();
let unpreservable_native_key = function () {
// We only allow natives that support wrapper preservation to be used as weak
// map keys. We should be able to try to add unpreservable natives as keys without
// crashing (bug 711616), but we should throw an error (bug 761620).
let dummy_test_map = new WeakMap;
// bug 711616: should be able to do this without crashing. JS warning is expected.
let div_fail = false;
try {
dummy_test_map.set(document.createElement("div").style, 1);
} catch (e) {
div_fail = true;
}
ok(div_fail, "Using elem.style as a weak map key should produce an exception because it can't be wrapper preserved.");
// JS warning is expected.
let navi_fail = false;
try {
dummy_test_map.set(window.navigator, 1);
} catch (e) {
navi_fail = true;
}
ok(navi_fail, "Using window.navigator as a weak map key should produce an exception because it can't be wrapper preserved.");
}
unpreservable_native_key();
/* set up for running precise GC/CC then checking the results */