Example #1
0
void
nsJSUtils::ReportPendingException(JSContext *aContext)
{
  if (JS_IsExceptionPending(aContext)) {
    bool saved = JS_SaveFrameChain(aContext);
    {
      // JS_SaveFrameChain set the compartment of aContext to null, so we need
      // to enter a compartment.  The question is, which one? We don't want to
      // enter the original compartment of aContext (or the compartment of the
      // current exception on aContext, for that matter) because when we
      // JS_ReportPendingException the JS engine can try to duck-type the
      // exception and produce a JSErrorReport.  It will then pass that
      // JSErrorReport to the error reporter on aContext, which might expose
      // information from it to script via onerror handlers.  So it's very
      // important that the duck typing happen in the same compartment as the
      // onerror handler.  In practice, that's the compartment of the window (or
      // otherwise default global) of aContext, so use that here.
      nsIScriptContext* scx = GetScriptContextFromJSContext(aContext);
      JS::Rooted<JSObject*> scope(aContext);
      scope = scx ? scx->GetWindowProxy()
                  : js::DefaultObjectForContextOrNull(aContext);
      if (!scope) {
        // The SafeJSContext has no default object associated with it.
        MOZ_ASSERT(NS_IsMainThread());
        MOZ_ASSERT(aContext == nsContentUtils::GetSafeJSContext());
        scope = xpc::UnprivilegedJunkScope(); // Usage approved by bholley
      }
      JSAutoCompartment ac(aContext, scope);
      JS_ReportPendingException(aContext);
    }
    if (saved) {
      JS_RestoreFrameChain(aContext);
    }
  }
}
Example #2
0
void
nsJSUtils::ReportPendingException(JSContext *aContext)
{
  if (JS_IsExceptionPending(aContext)) {
    bool saved = JS_SaveFrameChain(aContext);
    {
      JSAutoCompartment ac(aContext, js::DefaultObjectForContextOrNull(aContext));
      JS_ReportPendingException(aContext);
    }
    if (saved) {
      JS_RestoreFrameChain(aContext);
    }
  }
}
bool
CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
{
    if (!JS_SaveFrameChain(cx))
        return false;

    bool ok = false;
    {
        JSAutoCompartment ac(cx, trusted_glob);
        ok = JS_CallFunctionValue(cx, nullptr, JS::ObjectValue(*trusted_fun),
                                  0, nullptr, vp);
    }
    JS_RestoreFrameChain(cx);
    return ok;
}
static bool
CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
{
    JS::CallArgs args = JS::CallArgsFromVp(argc, vp);

    if (!JS_SaveFrameChain(cx))
        return false;

    bool ok = false;
    {
        JSAutoCompartment ac(cx, trusted_glob);
        JS::RootedValue funVal(cx, JS::ObjectValue(*trusted_fun));
        ok = JS_CallFunctionValue(cx, JS::NullPtr(), funVal, JS::HandleValueArray::empty(), args.rval());
    }
    JS_RestoreFrameChain(cx);
    return ok;
}
Example #5
0
void
nsJSUtils::ReportPendingException(JSContext *aContext)
{
    if (JS_IsExceptionPending(aContext)) {
        bool saved = JS_SaveFrameChain(aContext);
        {
            nsIScriptContext* scx = GetScriptContextFromJSContext(aContext);
            JS::Rooted<JSObject*> scope(aContext);
            scope = scx ? scx->GetWindowProxy()
                    : js::DefaultObjectForContextOrNull(aContext);
            JSAutoCompartment ac(aContext, scope);
            JS_ReportPendingException(aContext);
        }
        if (saved) {
            JS_RestoreFrameChain(aContext);
        }
    }
}
Example #6
0
/* void push (in JSContext cx); */
NS_IMETHODIMP
XPCJSContextStack::Push(JSContext * cx)
{
    JS_ASSERT_IF(cx, JS_GetContextThread(cx));
    if(!mStack.AppendElement(cx))
        return NS_ERROR_OUT_OF_MEMORY;
    if(mStack.Length() > 1)
    {
        XPCJSContextInfo & e = mStack[mStack.Length() - 2];
        if(e.cx)
        {
            if(e.cx == cx)
            {
                nsIScriptSecurityManager* ssm = XPCWrapper::GetSecurityManager();
                if(ssm)
                {
                    nsIPrincipal* globalObjectPrincipal =
                        GetPrincipalFromCx(cx);
                    if(globalObjectPrincipal)
                    {
                        nsIPrincipal* subjectPrincipal = ssm->GetCxSubjectPrincipal(cx);
                        PRBool equals = PR_FALSE;
                        globalObjectPrincipal->Equals(subjectPrincipal, &equals);
                        if(equals)
                        {
                            return NS_OK;
                        }
                    }
                }
            }

            {
                // Push() can be called outside any request for e.cx.
                JSAutoRequest ar(e.cx);
                e.frame = JS_SaveFrameChain(e.cx);
            }

            if(!cx)
                e.suspendDepth = JS_SuspendRequest(e.cx);
        }
    }
    return NS_OK;
}
JSBool
CallTrusted(JSContext *cx, unsigned argc, jsval *vp)
{
    if (!JS_SaveFrameChain(cx))
        return JS_FALSE;

    JSBool ok = JS_FALSE;
    {
        JSAutoEnterCompartment ac;
        ok = ac.enter(cx, trusted_glob.get());
        if (!ok)
            goto out;
        ok = JS_CallFunctionValue(cx, NULL, OBJECT_TO_JSVAL(trusted_fun.get()),
                                  0, NULL, vp);
    }
  out:
    JS_RestoreFrameChain(cx);
    return ok;
}
  SafeCallGuard(JSContext *cx, nsIPrincipal *principal)
    : cx(cx) {
    nsIScriptSecurityManager_1_9_2 *ssm = XPCWrapper::GetSecurityManager();
    if (ssm) {
      // Note: We pass null as the target frame pointer because we know that
      // we're about to set aside the frame chain.
      nsresult rv = ssm->PushContextPrincipal(cx, nsnull, principal);
      if (NS_FAILED(rv)) {
        NS_WARNING("Not allowing call because we're out of memory");
        JS_ReportOutOfMemory(cx);
        this->cx = nsnull;
        return;
      }
    }

    js_SaveAndClearRegExpStatics(cx, &statics, &tvr, &tvr2);
    fp = JS_SaveFrameChain(cx);
    options =
      JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
  }
nsresult
nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement)
{
    NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method");

    if (!mJSMethodObject) {
        // Nothing to do here
        return NS_OK;
    }

    // Get the script context the same way
    // nsXBLProtoImpl::InstallImplementation does.
    nsIDocument* document = aBoundElement->OwnerDoc();

    nsIScriptGlobalObject* global = document->GetScriptGlobalObject();
    if (!global) {
        return NS_OK;
    }

    nsCOMPtr<nsIScriptContext> context = global->GetContext();
    if (!context) {
        return NS_OK;
    }

    JSContext* cx = context->GetNativeContext();

    JSObject* globalObject = global->GetGlobalJSObject();

    nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
    jsval v;
    nsresult rv =
        nsContentUtils::WrapNative(cx, globalObject, aBoundElement, &v,
                                   getter_AddRefs(wrapper));
    NS_ENSURE_SUCCESS(rv, rv);

    JSObject* thisObject = JSVAL_TO_OBJECT(v);

    JSAutoRequest ar(cx);
    JSAutoEnterCompartment ac;

    if (!ac.enter(cx, thisObject))
        return NS_ERROR_UNEXPECTED;

    // Clone the function object, using thisObject as the parent so "this" is in
    // the scope chain of the resulting function (for backwards compat to the
    // days when this was an event handler).
    JSObject* method = ::JS_CloneFunctionObject(cx, mJSMethodObject, thisObject);
    if (!method)
        return NS_ERROR_OUT_OF_MEMORY;

    // Now call the method

    // Use nsCxPusher to make sure we call ScriptEvaluated when we're done.
    nsCxPusher pusher;
    NS_ENSURE_STATE(pusher.Push(aBoundElement));

    // Check whether it's OK to call the method.
    rv = nsContentUtils::GetSecurityManager()->CheckFunctionAccess(cx, method,
            thisObject);

    JSBool ok = JS_TRUE;
    if (NS_SUCCEEDED(rv)) {
        jsval retval;
        ok = ::JS_CallFunctionValue(cx, thisObject, OBJECT_TO_JSVAL(method),
                                    0 /* argc */, nsnull /* argv */, &retval);
    }

    if (!ok) {
        // If a constructor or destructor threw an exception, it doesn't stop
        // anything else.  We just report it.  Note that we need to set aside the
        // frame chain here, since the constructor invocation is not related to
        // whatever is on the stack right now, really.
        JSBool saved = JS_SaveFrameChain(cx);
        JS_ReportPendingException(cx);
        if (saved)
            JS_RestoreFrameChain(cx);
        return NS_ERROR_FAILURE;
    }

    return NS_OK;
}