Bug 655921 - Check for Function being forbidden before creating the function private which would ordinarily be returned. Also create that function private with an explicitly specified parent, that being the Function function's global object. r=mrbkap

--HG--
extra : rebase_source : d0638bf75648e5dc0f9bb0c1fcf61559d1422771
This commit is contained in:
Jeff Walden 2011-05-10 14:56:49 -07:00
parent 90cdb85452
commit a0caea8ac7
2 changed files with 19 additions and 18 deletions

View File

@ -2436,37 +2436,28 @@ Function(JSContext *cx, uintN argc, Value *vp)
{
CallArgs call = CallArgsFromVp(argc, vp);
JS::Anchor<JSObject *> obj(NewFunction(cx, NULL));
/* Block this call if security callbacks forbid it. */
GlobalObject *global = call.callee().getGlobal();
if (!global->isEvalAllowed(cx)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CSP_BLOCKED_FUNCTION);
return false;
}
JS::Anchor<JSObject *> obj(NewFunction(cx, *global));
if (!obj.get())
return false;
JSObject &calleeParent = *call.callee().getParent();
/*
* NB: (new Function) is not lexically closed by its caller, it's just an
* anonymous function in the top-level scope that its constructor inhabits.
* Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42,
* and so would a call to f from another top-level's script or function.
*
* In older versions, before call objects, a new Function was adopted by
* its running context's globalObject, which might be different from the
* top-level reachable from scopeChain (in HTML frames, e.g.).
*/
JSFunction *fun = js_NewFunction(cx, obj.get(), NULL, 0, JSFUN_LAMBDA | JSFUN_INTERPRETED,
&calleeParent, cx->runtime->atomState.anonymousAtom);
global, cx->runtime->atomState.anonymousAtom);
if (!fun)
return false;
/*
* CSP check: whether new Function() is allowed at all.
* Report errors via CSP is done in the script security manager.
* js_CheckContentSecurityPolicy is defined in jsobj.cpp
*/
if (!js_CheckContentSecurityPolicy(cx, &calleeParent)) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CSP_BLOCKED_FUNCTION);
return false;
}
EmptyShape *emptyCallShape = EmptyShape::getEmptyCallShape(cx);
if (!emptyCallShape)
return false;

View File

@ -1254,6 +1254,16 @@ out:
}
} /* namespace detail */
static JS_ALWAYS_INLINE JSObject *
NewFunction(JSContext *cx, js::GlobalObject &global)
{
JSObject *proto;
if (!js_GetClassPrototype(cx, &global, JSProto_Function, &proto))
return NULL;
return detail::NewObject<WithProto::Given, true>(cx, &js_FunctionClass, proto, &global,
gc::FINALIZE_OBJECT2);
}
static JS_ALWAYS_INLINE JSObject *
NewFunction(JSContext *cx, JSObject *parent)
{