28390, 28866, 34364
r=brendan@mozilla.org
35701
r=jst@netscape.com
This commit is contained in:
norris%netscape.com 2000-04-14 03:14:53 +00:00
Родитель 73308e499a
Коммит e356de6476
8 изменённых файлов: 177 добавлений и 77 удалений

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

@ -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);