blob: 0d03d4210c204d7a231ed7fc38d9cb0824f2689a [file] [log] [blame]
// |reftest| skip-if(!xulRuntime.shell) -- needs newGlobal()
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var gTestfile = "indirect-proxy-preventExtensions-error-realm.js";
var BUGNUMBER = 1085566;
var summary =
"The preventExtensions trap should return success/failure (with the " +
"outermost preventExtension caller deciding what to do in response), " +
"rather than throwing a TypeError itself";
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
var g = newGlobal();
// Someday indirect proxies will be thrown into the lake of fire and sulfur
// alongside the beast and the false prophet, to be tormented day and night for
// ever and ever. When that happens, this test will need to be updated.
//
// The requirements for |p| are that 1) it be a cross-compartment wrapper, 2) to
// a proxy, 3) whose C++ preventExtensions handler method returns true while
// setting |*succeeded = false|. The other options when this test was written)
// were a global scope polluter (WindowNamedPropertiesHandler), a window object
// (nsOuterWindowProxy), a DOM proxy (DOMProxyHandler), a SecurityWrapper, a
// DebugScopeProxy (seemingly never directly exposed to script), and an
// XrayWrapper. Sadly none of these are simply available in both shell and
// browser, so indirect proxies are it.
//
// (The other option would be to do this with a jsapi-test that defines a custom
// proxy, but this was easier to write. Maybe in the future, if no other such
// proxies arise before indirect proxies die.)
var p = g.Proxy.create({}, {});
try
{
// What we expect to happen is this:
//
// * Object.preventExtensions delegates to
// * cross-compartment wrapper preventExtensions trap, which delegates to
// * indirect proxy preventExtensions trap, which sets |*succeeded = false|
// *and does not throw or return false (in the JSAPI sense)*
//
// Returning false does not immediately create an error. Instead that bubbles
// backward through the layers to the initial [[PreventExtensions]] call, made
// by Object.preventExtensions. That function then creates and throws a
// TypeError in response to that false result -- from its realm, not from the
// indirect proxy's realm.
Object.preventExtensions(p);
throw new Error("didn't throw at all");
}
catch (e)
{
assertEq(e instanceof TypeError, true,
"expected a TypeError from this global, instead got " + e +
", from " +
(e.constructor === TypeError
? "this global"
: e.constructor === g.TypeError
? "the proxy's global"
: "somewhere else (!!!)"));
}
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete");