mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-01 05:43:46 +00:00
Fix bug 567069. r=jorendorff/luke
This commit is contained in:
parent
24c1ccd37c
commit
c269e57415
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -1537,6 +1537,81 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static bool
|
||||
SetupFakeFrame(JSContext *cx, ExecuteFrameGuard &frame, JSFrameRegs ®s, JSObject *scopeobj)
|
||||
{
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, scopeobj);
|
||||
JS_ASSERT(fun->minArgs() == 0 && !fun->isInterpreted() && fun->u.n.extra == 0);
|
||||
|
||||
const uintN vplen = 2;
|
||||
const uintN nfixed = 0;
|
||||
if (!cx->stack().getExecuteFrame(cx, js_GetTopStackFrame(cx), vplen, nfixed, frame))
|
||||
return false;
|
||||
|
||||
jsval *vp = frame.getvp();
|
||||
PodZero(vp, vplen);
|
||||
vp[0] = OBJECT_TO_JSVAL(scopeobj);
|
||||
|
||||
JSStackFrame *fp = frame.getFrame();
|
||||
PodZero(fp);
|
||||
fp->fun = fun;
|
||||
fp->argv = vp + 2;
|
||||
fp->scopeChain = scopeobj->getGlobal();
|
||||
|
||||
regs.pc = NULL;
|
||||
regs.sp = fp->slots();
|
||||
|
||||
cx->stack().pushExecuteFrame(cx, frame, regs, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_GetPropertyByIdWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsid id,
|
||||
jsval *vp)
|
||||
{
|
||||
ExecuteFrameGuard frame;
|
||||
JSFrameRegs regs;
|
||||
|
||||
if (!SetupFakeFrame(cx, frame, regs, scopeobj))
|
||||
return false;
|
||||
|
||||
bool ok = JS_GetPropertyById(cx, obj, id, vp);
|
||||
frame.getFrame()->putActivationObjects(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_SetPropertyByIdWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsid id,
|
||||
jsval *vp)
|
||||
{
|
||||
ExecuteFrameGuard frame;
|
||||
JSFrameRegs regs;
|
||||
|
||||
if (!SetupFakeFrame(cx, frame, regs, scopeobj))
|
||||
return false;
|
||||
|
||||
bool ok = JS_SetPropertyById(cx, obj, id, vp);
|
||||
frame.getFrame()->putActivationObjects(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_CallFunctionValueWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsval funval,
|
||||
uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
ExecuteFrameGuard frame;
|
||||
JSFrameRegs regs;
|
||||
|
||||
if (!SetupFakeFrame(cx, frame, regs, scopeobj))
|
||||
return false;
|
||||
|
||||
bool ok = JS_CallFunctionValue(cx, obj, funval, argc, argv, rval);
|
||||
frame.getFrame()->putActivationObjects(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=78:
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -337,6 +337,20 @@ JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_GetPropertyByIdWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsid id,
|
||||
jsval *vp);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_SetPropertyByIdWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsid id,
|
||||
jsval *vp);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_CallFunctionValueWithFakeFrame(JSContext *cx, JSObject *obj, JSObject *scopeobj, jsval funval,
|
||||
uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure);
|
||||
|
||||
|
@ -194,6 +194,11 @@ CanCallerAccess(JSContext *cx, JSObject *wrapperObj, JSObject *unsafeObj)
|
||||
// (nsIPrincipal, strong reference).
|
||||
static const PRUint32 sPrincipalSlot = sNumSlots;
|
||||
|
||||
// Slot for holding the function that we fill our fake frame with.
|
||||
static const PRUint32 sScopeFunSlot = sNumSlots + 1;
|
||||
|
||||
static const PRUint32 sSJOWSlots = sNumSlots + 2;
|
||||
|
||||
// Returns a weak reference.
|
||||
static nsIPrincipal *
|
||||
FindObjectPrincipals(JSContext *cx, JSObject *safeObj, JSObject *innerObj)
|
||||
@ -252,7 +257,7 @@ JSExtendedClass SJOWClass = {
|
||||
// JSClass (JSExtendedClass.base) initialization
|
||||
{ "XPCSafeJSObjectWrapper",
|
||||
JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED |
|
||||
JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots + 1),
|
||||
JSCLASS_HAS_RESERVED_SLOTS(sSJOWSlots),
|
||||
XPC_SJOW_AddProperty, XPC_SJOW_DelProperty,
|
||||
XPC_SJOW_GetProperty, XPC_SJOW_SetProperty,
|
||||
XPC_SJOW_Enumerate, (JSResolveOp)XPC_SJOW_NewResolve,
|
||||
@ -387,6 +392,40 @@ GetUnsafeObject(JSContext *cx, JSObject *obj)
|
||||
|
||||
} // namespace XPCSafeJSObjectWrapper
|
||||
|
||||
static JSBool
|
||||
DummyNative(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
GetScopeFunction(JSContext *cx, JSObject *outerObj)
|
||||
{
|
||||
jsval v;
|
||||
if (!JS_GetReservedSlot(cx, outerObj, sScopeFunSlot, &v)) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (JSVAL_IS_OBJECT(v)) {
|
||||
return JSVAL_TO_OBJECT(v);
|
||||
}
|
||||
|
||||
JSObject *unsafeObj = GetUnsafeObject(cx, outerObj);
|
||||
JSFunction *fun = JS_NewFunction(cx, DummyNative, 0, 0,
|
||||
JS_GetGlobalForObject(cx, unsafeObj),
|
||||
"SJOWContentBoundary");
|
||||
if (!fun) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
if (!JS_SetReservedSlot(cx, outerObj, sScopeFunSlot, OBJECT_TO_JSVAL(funobj))) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return funobj;
|
||||
}
|
||||
|
||||
// Wrap a JS value in a safe wrapper of a function wrapper if
|
||||
// needed. Note that rval must point to something rooted when calling
|
||||
// this function.
|
||||
@ -601,6 +640,11 @@ XPC_SJOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *scopeFun = GetScopeFunction(cx, obj);
|
||||
if (!scopeFun) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
SafeCallGuard guard(cx, FindObjectPrincipals(cx, obj, unsafeObj));
|
||||
if (!guard.ready()) {
|
||||
@ -620,8 +664,10 @@ XPC_SJOW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||
}
|
||||
|
||||
JSBool ok = aIsSet
|
||||
? JS_SetPropertyById(cx, unsafeObj, interned_id, vp)
|
||||
: JS_GetPropertyById(cx, unsafeObj, interned_id, vp);
|
||||
? js_SetPropertyByIdWithFakeFrame(cx, unsafeObj, scopeFun,
|
||||
interned_id, vp)
|
||||
: js_GetPropertyByIdWithFakeFrame(cx, unsafeObj, scopeFun,
|
||||
interned_id, vp);
|
||||
if (!ok) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
@ -820,6 +866,11 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *scopeFun = GetScopeFunction(cx, safeObj);
|
||||
if (!scopeFun) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
SafeCallGuard guard(cx, FindObjectPrincipals(cx, safeObj, funToCall));
|
||||
|
||||
@ -837,8 +888,9 @@ XPC_SJOW_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(v), OBJECT_TO_JSVAL(funToCall),
|
||||
argc, argv, rval)) {
|
||||
if (!js_CallFunctionValueWithFakeFrame(cx, JSVAL_TO_OBJECT(v), scopeFun,
|
||||
OBJECT_TO_JSVAL(funToCall),
|
||||
argc, argv, rval)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
@ -897,6 +949,11 @@ XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
JSObject *scopeFun = GetScopeFunction(cx, callee);
|
||||
if (!scopeFun) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
{
|
||||
SafeCallGuard guard(cx, FindObjectPrincipals(cx, callee, unsafeObj));
|
||||
if (!guard.ready()) {
|
||||
@ -917,8 +974,9 @@ XPC_SJOW_Create(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(v), OBJECT_TO_JSVAL(unsafeObj),
|
||||
argc, argv, rval)) {
|
||||
if (!js_CallFunctionValueWithFakeFrame(cx, JSVAL_TO_OBJECT(v), scopeFun,
|
||||
OBJECT_TO_JSVAL(unsafeObj),
|
||||
argc, argv, rval)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user