зеркало из https://github.com/mozilla/gecko-dev.git
28390, 28866, 34364 r=brendan@mozilla.org 35701 r=jst@netscape.com
This commit is contained in:
Родитель
73308e499a
Коммит
e356de6476
|
@ -105,7 +105,7 @@ interface nsIScriptSecurityManager : nsISupports
|
|||
boolean CanExecuteScripts(in nsIPrincipal principal);
|
||||
|
||||
/**
|
||||
* Return true if the given JavaScript function was compiled with
|
||||
* Return true if the given JavaScript function object was compiled with
|
||||
* a principal that is allowed to execute scripts.
|
||||
*/
|
||||
boolean CanExecuteFunction(in voidStar jsFunction);
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "nsIXPCSecurityManager.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsDOMPropEnums.h"
|
||||
|
@ -125,6 +126,20 @@ private:
|
|||
NS_IMETHOD
|
||||
CheckXPCPermissions(JSContext *cx);
|
||||
|
||||
NS_IMETHOD
|
||||
GetFramePrincipal(JSContext *cx, JSStackFrame *fp, nsIPrincipal **result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetScriptPrincipal(JSContext *cx, JSScript *script, nsIPrincipal **result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetFunctionObjectPrincipal(JSContext *cx, JSObject *obj,
|
||||
nsIPrincipal **result);
|
||||
|
||||
NS_IMETHOD
|
||||
GetPrincipalAndFrame(JSContext *cx, nsIPrincipal **result,
|
||||
JSStackFrame **frameResult);
|
||||
|
||||
NS_IMETHOD
|
||||
InitFromPrefs();
|
||||
|
||||
|
|
|
@ -84,6 +84,23 @@ GetCurrentContext() {
|
|||
return cx;
|
||||
}
|
||||
|
||||
static JSContext *
|
||||
GetSafeContext() {
|
||||
// Get the "safe" JSContext: our JSContext of last resort
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIJSContextStack, stack, "nsThreadJSContextStack",
|
||||
&rv);
|
||||
if (NS_FAILED(rv))
|
||||
return nsnull;
|
||||
nsCOMPtr<nsIThreadJSContextStack> tcs = do_QueryInterface(stack);
|
||||
JSContext *cx;
|
||||
if (NS_FAILED(tcs->GetSafeJSContext(&cx)))
|
||||
return nsnull;
|
||||
return cx;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static nsDOMProp
|
||||
findDomProp(const char *propName, int n);
|
||||
|
||||
|
@ -655,20 +672,74 @@ nsScriptSecurityManager::CanExecuteScripts(nsIPrincipal *principal,
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CanExecuteFunction(void *jsFunc,
|
||||
nsScriptSecurityManager::CanExecuteFunction(void *jsFuncObj,
|
||||
PRBool *result)
|
||||
{
|
||||
// norris TODO: figure out JSContext strategy, replace nsnulls below
|
||||
// JavaScript is disabled, but we must still execute system JavaScript
|
||||
JSScript *script = JS_GetFunctionScript(nsnull, (JSFunction *) jsFunc);
|
||||
if (!script)
|
||||
return NS_ERROR_FAILURE;
|
||||
JSPrincipals *jsprin = JS_GetScriptPrincipals(nsnull, script);
|
||||
if (!jsprin)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsJSPrincipals *nsJSPrin = (nsJSPrincipals *) jsprin;
|
||||
JSContext *cx = GetCurrentContext();
|
||||
if (!cx) {
|
||||
cx = GetSafeContext();
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = GetFunctionObjectPrincipal(cx, (JSObject *) jsFuncObj,
|
||||
getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (!principal) {
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
return CanExecuteScripts(principal, result);
|
||||
}
|
||||
|
||||
return CanExecuteScripts(nsJSPrin->nsIPrincipalPtr, result);
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetScriptPrincipal(JSContext *cx,
|
||||
JSScript *script,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
if (!script) {
|
||||
*result = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
JSPrincipals *jsp = JS_GetScriptPrincipals(cx, script);
|
||||
if (!jsp) {
|
||||
// Script didn't have principals -- shouldn't happen.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsJSPrincipals *nsJSPrin = NS_STATIC_CAST(nsJSPrincipals *, jsp);
|
||||
*result = nsJSPrin->nsIPrincipalPtr;
|
||||
if (!result)
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ADDREF(*result);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
|
||||
JSObject *obj,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, obj);
|
||||
if (JS_GetFunctionObject(fun) != obj) {
|
||||
// Function has been cloned; get principals from scope
|
||||
return GetObjectPrincipal(cx, obj, result);
|
||||
}
|
||||
JSScript *script = JS_GetFunctionScript(cx, fun);
|
||||
return GetScriptPrincipal(cx, script, result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
|
||||
JSStackFrame *fp,
|
||||
nsIPrincipal **result)
|
||||
{
|
||||
JSObject *obj = JS_GetFrameFunctionObject(cx, fp);
|
||||
if (!obj) {
|
||||
// Must be in a top-level script. Get principal from the script.
|
||||
JSScript *script = JS_GetFrameScript(cx, fp);
|
||||
return GetScriptPrincipal(cx, script, result);
|
||||
}
|
||||
return GetFunctionObjectPrincipal(cx, obj, result);
|
||||
}
|
||||
|
||||
|
||||
|
@ -685,42 +756,36 @@ nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
|
|||
*result = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
while (fp) {
|
||||
JSScript *script = JS_GetFrameScript(cx, fp);
|
||||
if (script) {
|
||||
JSPrincipals *principals = JS_GetScriptPrincipals(cx, script);
|
||||
if (!principals) {
|
||||
// Script didn't have principals!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// First check if the principal is even able to enable the
|
||||
// given capability. If not, don't look any further.
|
||||
nsJSPrincipals *nsJSPrin = (nsJSPrincipals *) principals;
|
||||
PRInt16 canEnable;
|
||||
rv = nsJSPrin->nsIPrincipalPtr->CanEnableCapability(capability,
|
||||
&canEnable);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (canEnable != nsIPrincipal::ENABLE_GRANTED &&
|
||||
canEnable != nsIPrincipal::ENABLE_WITH_USER_PERMISSION)
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now see if the capability is enabled.
|
||||
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
||||
rv = nsJSPrin->nsIPrincipalPtr->IsCapabilityEnabled(capability,
|
||||
annotation,
|
||||
result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (*result)
|
||||
return NS_OK;
|
||||
do {
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (NS_FAILED(GetFramePrincipal(cx, fp, getter_AddRefs(principal)))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
fp = JS_FrameIterator(cx, &fp);
|
||||
}
|
||||
if (!principal)
|
||||
continue;
|
||||
|
||||
// First check if the principal is even able to enable the
|
||||
// given capability. If not, don't look any further.
|
||||
PRInt16 canEnable;
|
||||
rv = principal->CanEnableCapability(capability, &canEnable);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (canEnable != nsIPrincipal::ENABLE_GRANTED &&
|
||||
canEnable != nsIPrincipal::ENABLE_WITH_USER_PERMISSION)
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now see if the capability is enabled.
|
||||
void *annotation = JS_GetFrameAnnotation(cx, fp);
|
||||
rv = principal->IsCapabilityEnabled(capability, annotation,
|
||||
result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (*result)
|
||||
return NS_OK;
|
||||
} while ((fp = JS_FrameIterator(cx, &fp)) != nsnull);
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -847,28 +912,21 @@ CheckConfirmDialog(const PRUnichar *szMessage, const PRUnichar *szCheckMessage,
|
|||
return (buttonPressed == 0);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetPrincipalAndFrame(JSContext *cx, nsIPrincipal **result,
|
||||
JSStackFrame **frameResult)
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::GetPrincipalAndFrame(JSContext *cx,
|
||||
nsIPrincipal **result,
|
||||
JSStackFrame **frameResult)
|
||||
{
|
||||
// Get principals from innermost frame of JavaScript or Java.
|
||||
JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
|
||||
fp = JS_FrameIterator(cx, &fp);
|
||||
while (fp) {
|
||||
JSScript *script = JS_GetFrameScript(cx, fp);
|
||||
if (script) {
|
||||
JSPrincipals *principals = JS_GetScriptPrincipals(cx, script);
|
||||
if (!principals) {
|
||||
// Script didn't have principals!
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsJSPrincipals *nsJSPrin = (nsJSPrincipals *) principals;
|
||||
*result = nsJSPrin->nsIPrincipalPtr;
|
||||
NS_ADDREF(*result);
|
||||
for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp)) {
|
||||
if (NS_FAILED(GetFramePrincipal(cx, fp, result))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (*result) {
|
||||
*frameResult = fp;
|
||||
return NS_OK;
|
||||
}
|
||||
fp = JS_FrameIterator(cx, &fp);
|
||||
}
|
||||
*result = nsnull;
|
||||
return NS_OK;
|
||||
|
|
|
@ -703,11 +703,8 @@ nsJSContext::CallEventHandler(void *aTarget, void *aHandler, PRUint32 argc,
|
|||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
jsval funval = OBJECT_TO_JSVAL(aHandler);
|
||||
JSFunction* fun = ::JS_ValueToFunction(mContext, funval);
|
||||
|
||||
PRBool ok;
|
||||
rv = securityManager->CanExecuteFunction(fun, &ok);
|
||||
rv = securityManager->CanExecuteFunction(aHandler, &ok);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -726,6 +723,7 @@ nsJSContext::CallEventHandler(void *aTarget, void *aHandler, PRUint32 argc,
|
|||
|
||||
jsval val;
|
||||
if (ok) {
|
||||
jsval funval = OBJECT_TO_JSVAL(aHandler);
|
||||
ok = ::JS_CallFunctionValue(mContext, (JSObject *)aTarget, funval,
|
||||
argc, (jsval *)argv, &val);
|
||||
}
|
||||
|
|
|
@ -391,20 +391,23 @@ NS_IMETHODIMP
|
|||
LocationImpl::GetPathname(nsString& aPathname)
|
||||
{
|
||||
nsAutoString href;
|
||||
nsIURI *url;
|
||||
nsIURI *uri;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
result = GetHref(href);
|
||||
if (NS_OK == result) {
|
||||
result = NS_NewURI(&url, href);
|
||||
result = NS_NewURI(&uri, href);
|
||||
if (NS_OK == result) {
|
||||
char* file;
|
||||
result = url->GetPath(&file);
|
||||
if (result == NS_OK) {
|
||||
aPathname.AssignWithConversion(file);
|
||||
nsCRT::free(file);
|
||||
nsCOMPtr<nsIURL> url = do_QueryInterface(uri);
|
||||
if (url) {
|
||||
char* file;
|
||||
result = url->GetFilePath(&file);
|
||||
if (result == NS_OK) {
|
||||
aPathname.AssignWithConversion(file);
|
||||
nsCRT::free(file);
|
||||
}
|
||||
}
|
||||
NS_IF_RELEASE(url);
|
||||
NS_IF_RELEASE(uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -339,8 +339,23 @@ js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
ok = wp->handler(cx, obj, js_IdToValue(sym_id(sym)),
|
||||
OBJ_GET_SLOT(cx, obj, wp->sprop->slot), vp,
|
||||
wp->closure);
|
||||
if (ok)
|
||||
if (ok) {
|
||||
/*
|
||||
* Create pseudo-frame for call to setter so that any
|
||||
* stackwalking security code in the setter will correctly
|
||||
* identify the guilty party.
|
||||
*/
|
||||
JSObject *funobj = (JSObject *) wp->closure;
|
||||
JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj);
|
||||
JSStackFrame frame;
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
frame.script = fun->script;
|
||||
frame.fun = fun;
|
||||
frame.down = cx->fp;
|
||||
cx->fp = &frame;
|
||||
ok = wp->setter(cx, obj, id, vp);
|
||||
cx->fp = frame.down;
|
||||
}
|
||||
DropWatchPoint(cx, wp);
|
||||
return ok;
|
||||
}
|
||||
|
@ -644,6 +659,12 @@ JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp)
|
|||
return fp->fun;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
return fp->argv && fp->fun ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_IsContructorFrame(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
|
|
|
@ -158,6 +158,9 @@ JS_GetFrameThis(JSContext *cx, JSStackFrame *fp);
|
|||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_IsContructorFrame(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
|
|
|
@ -2564,7 +2564,9 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
|||
if (!prop) {
|
||||
*vp = JSVAL_VOID;
|
||||
*attrsp = 0;
|
||||
return JS_TRUE;
|
||||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
return !clasp->checkAccess ||
|
||||
clasp->checkAccess(cx, obj, id, mode, vp);
|
||||
}
|
||||
if (!OBJ_IS_NATIVE(pobj)) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
|
|
Загрузка…
Ссылка в новой задаче