// If you change this code, change also nsContentUtils::CanAccessNativeAnon()! JSBool AllowedToAct(JSContext *cx, jsid id) { // TODO bug 508928: Refactor this with the XOW security checking code. nsIScriptSecurityManager *ssm = GetSecurityManager(); if (!ssm) { return JS_TRUE; } JSStackFrame *fp; nsIPrincipal *principal = ssm->GetCxSubjectPrincipalAndFrame(cx, &fp); if (!principal) { return ThrowException(NS_ERROR_UNEXPECTED, cx); } if (!fp) { if (!JS_FrameIterator(cx, &fp)) { // No code at all is running. So we must be arriving here as the result // of C++ code asking us to do something. Allow access. return JS_TRUE; } // Some code is running, we can't make the assumption, as above, but we // can't use a native frame, so clear fp. fp = nsnull; } else if (!fp->hasScript()) { fp = nsnull; } PRBool privileged; if (NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) && privileged) { // Chrome things are allowed to touch us. return JS_TRUE; } // XXX HACK EWW! Allow chrome://global/ access to these things, even // if they've been cloned into less privileged contexts. const char *filename; if (fp && (filename = fp->getScript()->filename) && !strncmp(filename, prefix, NS_ARRAY_LENGTH(prefix) - 1)) { return JS_TRUE; } // Before we throw, check for UniversalXPConnect. nsresult rv = ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged); if (NS_SUCCEEDED(rv) && privileged) { return JS_TRUE; } if (JSID_IS_VOID(id)) { ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } else { // TODO Localize me? jsval idval; JSString *str; if (JS_IdToValue(cx, id, &idval) && (str = JS_ValueToString(cx, idval))) { JS_ReportError(cx, "Permission denied to access property '%hs' from a non-chrome context", JS_GetStringChars(str)); } } return JS_FALSE; }
static JSBool Exception(JSContext *cx, JSObject *obj, uintN argc, Value *argv, Value *rval) { JSString *message, *filename; JSStackFrame *fp; if (!JS_IsConstructing(cx)) { /* * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when * called as functions, without operator new. But as we do not give * each constructor a distinct JSClass, whose .name member is used by * NewNativeClassInstance to find the class prototype, we must get the * class prototype ourselves. */ if (!argv[-2].toObject().getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState .classPrototypeAtom), rval)) { return JS_FALSE; } JSObject *errProto = &rval->toObject(); obj = NewNativeClassInstance(cx, &js_ErrorClass, errProto, errProto->getParent()); if (!obj) return JS_FALSE; rval->setObject(*obj); } /* * If it's a new object of class Exception, then null out the private * data so that the finalizer doesn't attempt to free it. */ if (obj->getClass() == &js_ErrorClass) obj->setPrivate(NULL); /* Set the 'message' property. */ if (argc != 0) { message = js_ValueToString(cx, argv[0]); if (!message) return JS_FALSE; argv[0].setString(message); } else { message = cx->runtime->emptyString; } /* Set the 'fileName' property. */ if (argc > 1) { filename = js_ValueToString(cx, argv[1]); if (!filename) return JS_FALSE; argv[1].setString(filename); fp = NULL; } else { fp = js_GetScriptedCaller(cx, NULL); if (fp) { filename = FilenameToString(cx, fp->getScript()->filename); if (!filename) return JS_FALSE; } else { filename = cx->runtime->emptyString; } } /* Set the 'lineNumber' property. */ uint32_t lineno; if (argc > 2) { if (!ValueToECMAUint32(cx, argv[2], &lineno)) return JS_FALSE; } else { if (!fp) fp = js_GetScriptedCaller(cx, NULL); lineno = (fp && fp->pc(cx)) ? js_FramePCToLineNumber(cx, fp) : 0; } return (obj->getClass() != &js_ErrorClass) || InitExnPrivate(cx, obj, message, filename, lineno, NULL); }