Bug 976148 - Implement Xrays to Function objects. r=gabor

This commit is contained in:
Bobby Holley 2014-06-19 09:57:06 -07:00
Родитель 8f66c46332
Коммит 02c638ea36
5 изменённых файлов: 33 добавлений и 16 удалений

Просмотреть файл

@ -29,8 +29,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=448587.xul
const Cu = Components.utils;
var sandbox = new Cu.Sandbox("about:blank");
var fwrapper = Cu.evalInSandbox("function f() {} f", sandbox);
is(fwrapper.prototype, Cu.evalInSandbox("f.prototype", sandbox),
"we don't censor .prototype through .wrappedJSObject");
is(Cu.unwaiveXrays(Cu.waiveXrays(fwrapper).prototype), Cu.evalInSandbox("f.prototype", sandbox),
".prototype visible through .wrappedJSObject");
is(fwrapper.prototype, undefined, ".prototype invisible through Xrays");
]]>
</script>
</window>

Просмотреть файл

@ -56,7 +56,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=812415
is(Cu.evalInSandbox('regFun.name', expanded), 'reg', "Expanded can see regular function's name");
checkThrows('expFun.name', regular, "Regular can't see expanded function's name");
Cu.evalInSandbox('regFun.expando = 30', expanded);
is(expanded.regFun.expando, 30, "Expanded can set expandos");
is(Cu.evalInSandbox('regFun.expando', expanded), 30, "Expanded can set expandos");
checkThrows('expFun.expando = 29', regular, "Regular can't set expandos");
// Check __proto__ stuff.

Просмотреть файл

@ -65,7 +65,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
is(global(num), iwin, "correct global for num");
var obj = new iwin.Object();
obj.foo = 2;
var withProto = iwin.Object.create(obj);
var withProto = Cu.unwaiveXrays(Cu.waiveXrays(iwin).Object.create(obj));
is(global(withProto), iwin, "correct global for withProto");
is(Cu.waiveXrays(withProto).foo, 2, "Inherits properly");
@ -242,7 +242,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681
}
function testObject() {
testXray('Object', iwin.Object.create(new iwin.Object()), new iwin.Object(), []);
testXray('Object', Cu.unwaiveXrays(Cu.waiveXrays(iwin).Object.create(new iwin.Object())),
new iwin.Object(), []);
// Construct an object full of tricky things.
var trickyObject =

Просмотреть файл

@ -128,9 +128,9 @@ static bool
ForceCOWBehavior(JSObject *obj)
{
JSProtoKey key = IdentifyStandardInstanceOrPrototype(obj);
if (key == JSProto_Object || key == JSProto_Array) {
if (key == JSProto_Object || key == JSProto_Array || key == JSProto_Function) {
MOZ_ASSERT(GetXrayType(obj) == XrayForJSObject,
"We should use XrayWrappers for standard ES Object and Array "
"We should use XrayWrappers for standard ES Object, Array, and Function "
"instances modulo this hack");
return true;
}
@ -360,13 +360,6 @@ SelectWrapper(bool securityWrapper, bool wantXrays, XrayType xrayType,
if (!wantXrays || xrayType == NotXray) {
if (!securityWrapper)
return &CrossCompartmentWrapper::singleton;
// In general, we don't want opaque function wrappers to be callable.
// But in the case of XBL, we rely on content being able to invoke
// functions exposed from the XBL scope. We could remove this exception,
// if needed, by using ExportFunction to generate the content-side
// representations of XBL methods.
else if (originIsXBLScope)
return &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton;
return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
}
@ -390,7 +383,15 @@ SelectWrapper(bool securityWrapper, bool wantXrays, XrayType xrayType,
CrossOriginAccessiblePropertiesOnly>::singleton;
// There's never any reason to expose pure JS objects to non-subsuming actors.
// Just use an opaque wrapper in this case.
//
// In general, we don't want opaque function wrappers to be callable.
// But in the case of XBL, we rely on content being able to invoke
// functions exposed from the XBL scope. We could remove this exception,
// if needed, by using ExportFunction to generate the content-side
// representations of XBL methods.
MOZ_ASSERT(xrayType == XrayForJSObject);
if (originIsXBLScope)
return &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton;
return &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton;
}

Просмотреть файл

@ -71,6 +71,7 @@ IsJSXraySupported(JSProtoKey key)
case JSProto_Date:
case JSProto_Object:
case JSProto_Array:
case JSProto_Function:
return true;
default:
return false;
@ -171,6 +172,8 @@ public:
class XrayTraits
{
public:
XrayTraits() {}
static JSObject* getTargetObject(JSObject *wrapper) {
return js::UncheckedUnwrap(wrapper, /* stopAtOuter = */ false);
}
@ -224,6 +227,9 @@ private:
JSObject* attachExpandoObject(JSContext *cx, HandleObject target,
nsIPrincipal *origin,
HandleObject exclusiveGlobal);
XrayTraits(XrayTraits &) MOZ_DELETE;
const XrayTraits& operator=(XrayTraits &) MOZ_DELETE;
};
class XPCWrappedNativeXrayTraits : public XrayTraits
@ -349,7 +355,11 @@ public:
static bool call(JSContext *cx, HandleObject wrapper,
const JS::CallArgs &args, js::Wrapper& baseInstance)
{
// We'll handle this when we start supporting Functions.
JSXrayTraits &self = JSXrayTraits::singleton;
RootedObject holder(cx, self.ensureHolder(cx, wrapper));
if (self.getProtoKey(holder) == JSProto_Function)
return baseInstance.call(cx, wrapper, args);
RootedValue v(cx, ObjectValue(*wrapper));
js_ReportIsNotFunction(cx, v);
return false;
@ -358,7 +368,11 @@ public:
static bool construct(JSContext *cx, HandleObject wrapper,
const JS::CallArgs &args, js::Wrapper& baseInstance)
{
// We'll handle this when we start supporting Functions.
JSXrayTraits &self = JSXrayTraits::singleton;
RootedObject holder(cx, self.ensureHolder(cx, wrapper));
if (self.getProtoKey(holder) == JSProto_Function)
return baseInstance.construct(cx, wrapper, args);
RootedValue v(cx, ObjectValue(*wrapper));
js_ReportIsNotFunction(cx, v);
return false;