Пример #1
0
// 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;
}
Пример #2
0
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);
}