Bug 1081990 - Turn off COWs for Functions. r=gabor

This commit is contained in:
Bobby Holley 2014-10-18 11:02:10 +02:00
Родитель 8d92103817
Коммит ad9fdda6a1
5 изменённых файлов: 25 добавлений и 67 удалений

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

@ -152,7 +152,12 @@ function compartment_test()
ok(/Privileged Junk/.test(cpowLocation),
"child->parent CPOWs should live in the privileged junk scope: " + cpowLocation);
is(obj(), 42, "child->parent CPOW is invokable");
is(obj.expando, undefined, "child->parent CPOW cannot access properties");
try {
obj.expando;
ok(false, "child->parent CPOW cannot access properties");
} catch (e) {
ok(true, "child->parent CPOW cannot access properties");
}
return results;
}

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

@ -101,55 +101,18 @@ function COWTests() {
isPropHidden(getCOW(nonempty), name, "object without exposedProps");
});
// Test function objects without __exposedProps__
// Test function objects.
var func = function(x) { return 42; };
func.__exposedProps__ = { foo: "r" };
func.foo = "foo property";
var funcCOW = getCOW(func);
PROPS_TO_TEST.forEach(function(name) {
isPropHidden(funcCOW, name, "function without exposedProps");
});
is([name for (name in funcCOW)].length, 0,
"function without exposedProps shouldn't have any properties");
is(funcCOW(), 42, "COW without exposedProps should still be callable");
// Test function objects with __exposedProps__
var func = function(x) { return 42; };
func.foo = "foo property";
func.__exposedProps__ = { foo: "r" };
var funcCOWr = getCOW(func);
PROPS_TO_TEST.forEach(function(name) {
if (name == "foo") {
isProp(funcCOWr, name, "foo property",
"function with exposedProps");
}
else {
isPropHidden(funcCOWr, name, "function with exposedProps");
}
});
is([name for (name in funcCOWr)].length, 1,
"function with exposedProps should only enumerate exposed props");
is([name for (name in funcCOWr)][0], "foo",
"function with exposedProps should only enumerate exposed props");
is(funcCOWr(), 42, "COW with exposedProps should be callable");
// Test function objects with __exposedProps__
var func = function(x) { return 42; };
func.foo = "foo property";
func.__exposedProps__ = { foo: "r", bar: "r" };
var funcCOWr2 = getCOW(func);
PROPS_TO_TEST.forEach(function(name) {
if (name == "foo") {
isProp(funcCOWr2, name, "foo property",
"function with more exposedProps");
}
else {
isPropHidden(funcCOWr2, name, "function with more exposedProps");
}
});
is([name for (name in funcCOWr2)].length, 1,
"function with exposedProps should only enumerate exposed props");
is([name for (name in funcCOWr2)][0], "foo",
"function with exposedProps should only enumerate exposed props");
try {
funcCOW.foo;
ok(false, 'Functions are no longer COWable');
} catch (e) {
ok(/denied|insecure/.test(e), 'Functions are no longer COWable');
}
is(funcCOW(), 42, "Chrome functions should be callable");
// Test object with empty exposedProps
var strict = { __exposedProps__: {}, foo: "foo property" };

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

@ -228,8 +228,7 @@ ExposedPropertiesOnly::check(JSContext *cx, HandleObject wrapper, HandleId id, W
RootedObject wrappedObject(cx, Wrapper::wrappedObject(wrapper));
if (act == Wrapper::CALL)
return true;
return false;
// For the case of getting a property descriptor, we allow if either GET or SET
// is allowed, and rely on FilteringWrapper to filter out any disallowed accessors.

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

@ -107,10 +107,6 @@ struct ExposedPropertiesOnly : public Policy {
static bool allowNativeCall(JSContext *cx, JS::IsAcceptableThis test, JS::NativeImpl impl) {
return false;
}
static bool checkCall(JSContext *cx, JS::HandleObject wrapper, const JS::CallArgs &args) {
// XXXbholley - This goes away in the next patch.
return AccessCheck::checkPassToPrivilegedCode(cx, wrapper, args);
}
};
}

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

@ -113,20 +113,7 @@ WrapperFactory::WaiveXray(JSContext *cx, JSObject *objArg)
static bool
ForceCOWBehavior(JSObject *obj)
{
JSProtoKey key = IdentifyStandardInstanceOrPrototype(obj);
if (key == JSProto_Function && GetXrayType(obj) == XrayForDOMObject) {
// This means that we've got a DOM constructor, which we never want to
// expose COW-style.
return false;
}
if (key == JSProto_Object || key == JSProto_Function) {
MOZ_ASSERT(GetXrayType(obj) == XrayForJSObject,
"We should use XrayWrappers for standard ES Object, Array, and Function "
"instances modulo this hack");
return true;
}
return false;
return IdentifyStandardInstanceOrPrototype(obj) == JSProto_Object;
}
inline bool
@ -483,6 +470,14 @@ WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj,
wrapper = &CrossCompartmentWrapper::singleton;
}
// If this is a chrome function being exposed to content, we need to allow
// call (but nothing else).
else if (originIsChrome && !targetIsChrome &&
IdentifyStandardInstance(obj) == JSProto_Function)
{
wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton;
}
// If this is a chrome object being exposed to content without Xrays, use
// a COW.
//