예제 #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);
    }
  }
}
예제 #2
0
/* JSContext pop (); */
NS_IMETHODIMP
XPCJSContextStack::Pop(JSContext * *_retval)
{
    NS_ASSERTION(!mStack.IsEmpty(), "ThreadJSContextStack underflow");

    PRUint32 idx = mStack.Length() - 1; // The thing we're popping
    NS_ASSERTION(!mStack[idx].frame,
                 "Shouldn't have a pending frame to restore on the context "
                 "we're popping!");

    if(_retval)
        *_retval = mStack[idx].cx;

    mStack.RemoveElementAt(idx);
    if(idx > 0)
    {
        --idx; // Advance to new top of the stack

        XPCJSContextInfo & e = mStack[idx];
        NS_ASSERTION(!e.frame || e.cx, "Shouldn't have frame without a cx!");
        if(e.requestDepth)
            JS_ResumeRequest(e.cx, e.requestDepth);

        e.requestDepth = 0;

        if(e.cx && e.frame)
        {
            // Pop() can be called outside any request for e.cx.
            JSAutoRequest ar(e.cx);
            JS_RestoreFrameChain(e.cx, e.frame);
            e.frame = nsnull;
        }
    }
    return NS_OK;
}
예제 #3
0
 ~SafeCallGuard() {
   if (cx) {
     JS_SetOptions(cx, options);
     JS_RestoreFrameChain(cx, fp);
     js_RestoreRegExpStatics(cx, &statics, &tvr, &tvr2);
     nsIScriptSecurityManager_1_9_2 *ssm = XPCWrapper::GetSecurityManager();
     if (ssm) {
       ssm->PopContextPrincipal(cx);
     }
   }
 }
예제 #4
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;
}
예제 #6
0
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;
}
예제 #7
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);
        }
    }
}
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;
}
예제 #9
0
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;
}