bug 311024: Make sure eval grabs the right scope object. r=brendan sr=jst

This commit is contained in:
mrbkap%gmail.com 2005-10-08 00:28:45 +00:00
parent a2934cfe59
commit ac604da132
13 changed files with 163 additions and 14 deletions

View File

@ -856,3 +856,11 @@ calDateTime::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
return NS_ERROR_NOT_IMPLEMENTED;
}
/* JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
NS_IMETHODIMP
calDateTime::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
JSObject *obj, JSObject **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -411,6 +411,7 @@ static const char kDOMStringBundleURL[] =
nsIXPCScriptable::WANT_NEWENUMERATE | \
nsIXPCScriptable::WANT_EQUALITY | \
nsIXPCScriptable::WANT_OUTER_OBJECT | \
nsIXPCScriptable::WANT_INNER_OBJECT | \
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
#define NODE_SCRIPTABLE_FLAGS \
@ -3407,6 +3408,15 @@ nsDOMClassInfo::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
return NS_ERROR_UNEXPECTED;
}
NS_IMETHODIMP
nsDOMClassInfo::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
NS_ERROR("nsDOMClassInfo::InnerObject Don't call me!");
return NS_ERROR_UNEXPECTED;
}
// static
nsIClassInfo *
@ -6097,11 +6107,7 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
nsGlobalWindow *win =
nsGlobalWindow::FromWrapper(wrapper)->GetOuterWindowInternal();
if (win) {
// Return the outer window.
*_retval = win->GetGlobalJSObject();
} else {
if (!win) {
// If we no longer have an outer window. No code should ever be
// running on a window w/o an outer, which means this hook should
// never be called when we have no outer. But just in case, return
@ -6109,11 +6115,45 @@ nsWindowSH::OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
// window.
*_retval = nsnull;
return NS_ERROR_UNEXPECTED;
}
// Return the outer window.
*_retval = win->GetGlobalJSObject();
return NS_OK;
}
NS_IMETHODIMP
nsWindowSH::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval)
{
nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper);
if (win->IsInnerWindow()) {
// Return the inner window.
*_retval = obj;
} else {
// Try to find the current inner window.
nsGlobalWindow *inner = win->GetCurrentInnerWindowInternal();
if (!inner) {
// Yikes! No inner window! Instead of leaking the outer window into the
// scope chain, let's return an error.
*_retval = nsnull;
return NS_ERROR_UNEXPECTED;
}
*_retval = inner->GetGlobalJSObject();
}
return NS_OK;
}
// DOM Location helper

View File

@ -444,6 +444,8 @@ public:
JSObject * obj, jsval val, PRBool *bp);
NS_IMETHOD OuterObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval);
NS_IMETHOD InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx,
JSObject * obj, JSObject * *_retval);
static JSBool JS_DLL_CALLBACK GlobalScopePolluterNewResolve(JSContext *cx,
JSObject *obj,

View File

@ -891,12 +891,12 @@ struct JSExtendedClass {
JSClass base;
JSEqualityOp equality;
JSObjectOp outerObject;
JSObjectOp innerObject;
jsword reserved0;
jsword reserved1;
jsword reserved2;
jsword reserved3;
jsword reserved4;
jsword reserved5;
};
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
@ -934,7 +934,7 @@ struct JSExtendedClass {
/* Initializer for unused members of statically initialized JSClass structs. */
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0,0,0
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0,0
/* For detailed comments on these function pointer types, see jspubtd.h. */
struct JSObjectOps {

View File

@ -1156,6 +1156,11 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
#endif
}
/* Ensure we compile this eval with the right object in the scope chain. */
OBJ_TO_INNER_OBJECT(cx, scopeobj);
if (!scopeobj)
return JS_FALSE;
str = JSVAL_TO_STRING(argv[0]);
if (caller) {
file = caller->script->filename;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=80:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -100,6 +101,16 @@ struct JSObjectMap {
? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v) \
: JS_TRUE)
#define OBJ_TO_INNER_OBJECT(cx,obj) \
JS_BEGIN_MACRO \
JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \
if (clasp_->flags & JSCLASS_IS_EXTENDED) { \
JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \
if (xclasp_->innerObject) \
obj = xclasp_->innerObject(cx, obj); \
} \
JS_END_MACRO
/*
* In the original JS engine design, obj->slots pointed to a vector of length
* JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object,

View File

@ -1,4 +1,5 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=80:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -201,6 +202,11 @@ script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
principals = NULL;
}
/* Ensure we compile this script with the right (inner) principals. */
OBJ_TO_INNER_OBJECT(cx, scopeobj);
if (!scopeobj)
return JS_FALSE;
/*
* Compile the new script using the caller's scope chain, a la eval().
* Unlike jsobj.c:obj_eval, however, we do not set JSFRAME_EVAL in fp's

View File

@ -252,7 +252,7 @@ JS_FRIEND_DATA(JSExtendedClass) js_NamespaceClass = {
NULL, NULL, NULL, NULL,
NULL, NULL, namespace_mark, NULL },
namespace_equality,
NULL,
NULL, NULL,
JSCLASS_NO_RESERVED_MEMBERS
};
@ -455,7 +455,7 @@ JS_FRIEND_DATA(JSExtendedClass) js_QNameClass = {
NULL, NULL, NULL, NULL,
NULL, NULL, qname_mark, NULL },
qname_equality,
NULL,
NULL, NULL,
JSCLASS_NO_RESERVED_MEMBERS
};

View File

@ -53,7 +53,7 @@
* to *_retval unless they want to return PR_FALSE.
*/
[uuid(f617776f-c0f8-465f-8e60-268a1bf05a76)]
[uuid(9cc0c2e0-f769-4f14-8cd6-2d2d40466f6c)]
interface nsIXPCScriptable : nsISupports
{
/* bitflags used for 'flags' (only 32 bits available!) */
@ -88,6 +88,7 @@ interface nsIXPCScriptable : nsISupports
const PRUint32 DONT_REFLECT_INTERFACE_NAMES = 1 << 27;
const PRUint32 WANT_EQUALITY = 1 << 28;
const PRUint32 WANT_OUTER_OBJECT = 1 << 29;
const PRUint32 WANT_INNER_OBJECT = 1 << 30;
// The high order bit is RESERVED for consumers of these flags.
// No implementor of this interface should ever return flags
@ -168,4 +169,7 @@ interface nsIXPCScriptable : nsISupports
JSObjectPtr outerObject(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj);
JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper,
in JSContextPtr cx, in JSObjectPtr obj);
};

View File

@ -118,6 +118,9 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::GetScriptableFlags(PRUint32 *aFlags)
#ifdef XPC_MAP_WANT_OUTER_OBJECT
nsIXPCScriptable::WANT_OUTER_OBJECT |
#endif
#ifdef XPC_MAP_WANT_INNER_OBJECT
nsIXPCScriptable::WANT_INNER_OBJECT |
#endif
#ifdef XPC_MAP_FLAGS
XPC_MAP_FLAGS |
@ -224,6 +227,11 @@ NS_IMETHODIMP XPC_MAP_CLASSNAME::OuterObject(nsIXPConnectWrappedNative *wrapper,
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
#ifndef XPC_MAP_WANT_INNER_OBJECT
NS_IMETHODIMP XPC_MAP_CLASSNAME::InnerObject(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, JSObject * *_retval)
{NS_ERROR("never called"); return NS_ERROR_NOT_IMPLEMENTED;}
#endif
/**************************************************************/
#undef XPC_MAP_CLASSNAME

View File

@ -1439,6 +1439,7 @@ public:
JSBool WantMark() GET_IT(WANT_MARK)
JSBool WantEquality() GET_IT(WANT_EQUALITY)
JSBool WantOuterObject() GET_IT(WANT_OUTER_OBJECT)
JSBool WantInnerObject() GET_IT(WANT_INNER_OBJECT)
JSBool UseJSStubForAddProperty() GET_IT(USE_JSSTUB_FOR_ADDPROPERTY)
JSBool UseJSStubForDelProperty() GET_IT(USE_JSSTUB_FOR_DELPROPERTY)
JSBool UseJSStubForSetProperty() GET_IT(USE_JSSTUB_FOR_SETPROPERTY)

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=80:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
@ -819,6 +820,44 @@ XPC_WN_OuterObject(JSContext *cx, JSObject *obj)
return obj;
}
JS_STATIC_DLL_CALLBACK(JSObject *)
XPC_WN_InnerObject(JSContext *cx, JSObject *obj)
{
XPCWrappedNative *wrapper =
XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj);
if(!wrapper)
{
Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
return nsnull;
}
if(!wrapper->IsValid())
{
Throw(NS_ERROR_XPC_HAS_BEEN_SHUTDOWN, cx);
return nsnull;
}
XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
if(si && si->GetFlags().WantInnerObject())
{
JSObject *newThis;
nsresult rv =
si->GetCallback()->InnerObject(wrapper, cx, obj, &newThis);
if(NS_FAILED(rv))
{
Throw(rv, cx);
return nsnull;
}
obj = newThis;
}
return obj;
}
JSExtendedClass XPC_WN_NoHelper_JSClass = {
{
@ -849,7 +888,9 @@ JSExtendedClass XPC_WN_NoHelper_JSClass = {
nsnull // spare;
},
XPC_WN_Equality,
XPC_WN_OuterObject
XPC_WN_OuterObject,
XPC_WN_InnerObject,
JSCLASS_NO_RESERVED_MEMBERS
};
@ -1378,6 +1419,7 @@ XPCNativeScriptableShared::PopulateJSClass()
mJSClass.equality = XPC_WN_Equality;
mJSClass.outerObject = XPC_WN_OuterObject;
mJSClass.innerObject = XPC_WN_InnerObject;
}
/***************************************************************************/

View File

@ -476,7 +476,14 @@ mozStorageStatementWrapper::OuterObject(nsIXPConnectWrappedNative *wrapper,
return NS_ERROR_NOT_IMPLEMENTED;
}
/* JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
NS_IMETHODIMP
mozStorageStatementWrapper::InnerObject(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj,
JSObject **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/*************************************************************************
****
@ -737,8 +744,14 @@ mozStorageStatementRow::OuterObject(nsIXPConnectWrappedNative *wrapper,
return NS_ERROR_NOT_IMPLEMENTED;
}
/* JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
NS_IMETHODIMP
mozStorageStatementRow::InnerObject(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj,
JSObject **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/*************************************************************************
****
@ -1014,3 +1027,12 @@ mozStorageStatementParams::OuterObject(nsIXPConnectWrappedNative *wrapper,
return NS_ERROR_NOT_IMPLEMENTED;
}
/* JSObjectPtr innerObject(in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj); */
NS_IMETHODIMP
mozStorageStatementParams::InnerObject(nsIXPConnectWrappedNative *wrapper,
JSContext *cx, JSObject *obj,
JSObject **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}