nsresult nsJSUtils::CompileFunction(JSContext* aCx, JS::Handle<JSObject*> aTarget, JS::CompileOptions& aOptions, const nsACString& aName, uint32_t aArgCount, const char** aArgArray, const nsAString& aBody, JSObject** aFunctionObject) { MOZ_ASSERT(js::GetEnterCompartmentDepth(aCx) > 0); MOZ_ASSERT_IF(aTarget, js::IsObjectInContextCompartment(aTarget, aCx)); MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN); mozilla::DebugOnly<nsIScriptContext*> ctx = GetScriptContextFromJSContext(aCx); MOZ_ASSERT_IF(ctx, ctx->IsContextInitialized()); // Do the junk Gecko is supposed to do before calling into JSAPI. if (aTarget) { JS::ExposeObjectToActiveJS(aTarget); } // Compile. JSFunction* fun = JS::CompileFunction(aCx, aTarget, aOptions, PromiseFlatCString(aName).get(), aArgCount, aArgArray, PromiseFlatString(aBody).get(), aBody.Length()); if (!fun) { ReportPendingException(aCx); return NS_ERROR_FAILURE; } *aFunctionObject = JS_GetFunctionObject(fun); return NS_OK; }
danger::AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull) { MOZ_ASSERT_IF(!allowNull, cx); // Hold a strong ref to the nsIScriptContext, if any. This ensures that we // only destroy the mContext of an nsJSContext when it is not on the cx stack // (and therefore not in use). See nsJSContext::DestroyJSContext(). if (cx) mScx = GetScriptContextFromJSContext(cx); XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack(); if (!stack->Push(cx)) { MOZ_CRASH(); } mStackDepthAfterPush = stack->Count(); #ifdef DEBUG mPushedContext = cx; mCompartmentDepthOnEntry = cx ? js::GetEnterCompartmentDepth(cx) : 0; #endif // Enter a request and a compartment for the duration that the cx is on the // stack if non-null. if (cx) { mAutoRequest.emplace(cx); } }
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); } } }
AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull) { MOZ_ASSERT_IF(!allowNull, cx); // Hold a strong ref to the nsIScriptContext, if any. This ensures that we // only destroy the mContext of an nsJSContext when it is not on the cx stack // (and therefore not in use). See nsJSContext::DestroyJSContext(). if (cx) mScx = GetScriptContextFromJSContext(cx); XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack(); if (!stack->Push(cx)) { MOZ_CRASH(); } mStackDepthAfterPush = stack->Count(); #ifdef DEBUG mPushedContext = cx; mCompartmentDepthOnEntry = cx ? js::GetEnterCompartmentDepth(cx) : 0; #endif // Enter a request and a compartment for the duration that the cx is on the // stack if non-null. if (cx) { mAutoRequest.construct(cx); // DOM JSContexts don't store their default compartment object on the cx. JSObject *compartmentObject = mScx ? mScx->GetWindowProxy() : js::DefaultObjectForContextOrNull(cx); if (compartmentObject) mAutoCompartment.construct(cx, compartmentObject); } }
JSObject* GetDefaultScopeFromJSContext(JSContext *cx) { // DOM JSContexts don't store their default compartment object on // the cx, so in those cases we need to fetch it via the scx // instead. nsIScriptContext *scx = GetScriptContextFromJSContext(cx); return scx ? scx->GetWindowProxy() : nullptr; }
static nsIPrincipal* GetPrincipalFromCx(JSContext *cx) { nsIScriptContext* scriptContext = GetScriptContextFromJSContext(cx); if(scriptContext) { nsCOMPtr<nsIScriptObjectPrincipal> globalData = do_QueryInterface(scriptContext->GetGlobalObject()); if(globalData) return globalData->GetPrincipal(); } return nsnull; }
static void exit_js_impl(JNIEnv *jEnv, JSContext *cx) { // The main idea is to execute terminate function if have any; if (cx) { nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) { scriptContext->ScriptEvaluated(PR_TRUE); } } return; }
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); } } }
// static already_AddRefed<IDBTransaction> IDBTransaction::Create(JSContext* aCx, IDBDatabase* aDatabase, nsTArray<nsString>& aObjectStoreNames, PRUint16 aMode, PRUint32 aTimeout) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsRefPtr<IDBTransaction> transaction = new IDBTransaction(); transaction->mDatabase = aDatabase; transaction->mMode = aMode; transaction->mTimeout = aTimeout; if (!transaction->mObjectStoreNames.AppendElements(aObjectStoreNames)) { NS_ERROR("Out of memory!"); return nsnull; } if (!transaction->mCachedStatements.Init()) { NS_ERROR("Failed to initialize hash!"); return nsnull; } nsIScriptContext* context = GetScriptContextFromJSContext(aCx); if (context) { transaction->mScriptContext = context; nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(context->GetGlobalObject()); if (window) { transaction->mOwner = window->GetCurrentInnerWindow(); } } if (!transaction->mOwner) { NS_ERROR("Couldn't get script context and owner!"); return nsnull; } return transaction.forget(); }
nsresult nsJSUtils::CompileFunction(JSContext* aCx, JS::HandleObject aTarget, JS::CompileOptions& aOptions, const nsACString& aName, uint32_t aArgCount, const char** aArgArray, const nsAString& aBody, JSObject** aFunctionObject) { MOZ_ASSERT(js::GetEnterCompartmentDepth(aCx) > 0); MOZ_ASSERT_IF(aTarget, js::IsObjectInContextCompartment(aTarget, aCx)); MOZ_ASSERT_IF(aOptions.versionSet, aOptions.version != JSVERSION_UNKNOWN); mozilla::DebugOnly<nsIScriptContext*> ctx = GetScriptContextFromJSContext(aCx); MOZ_ASSERT_IF(ctx, ctx->IsContextInitialized()); // Since aTarget and aCx are same-compartment, there should be no distinction // between the object principal and the cx principal. // However, aTarget may be null in the wacky aShared case. So use the cx. JSPrincipals* p = JS_GetCompartmentPrincipals(js::GetContextCompartment(aCx)); aOptions.setPrincipals(p); // Do the junk Gecko is supposed to do before calling into JSAPI. if (aTarget) { JS::ExposeObjectToActiveJS(aTarget); } // Compile. JSFunction* fun = JS::CompileFunction(aCx, aTarget, aOptions, PromiseFlatCString(aName).get(), aArgCount, aArgArray, PromiseFlatString(aBody).get(), aBody.Length()); if (!fun) { ReportPendingException(aCx); return NS_ERROR_FAILURE; } *aFunctionObject = JS_GetFunctionObject(fun); return NS_OK; }
// // Native method UpdateEnabled // static JSBool InstallTriggerGlobalUpdateEnabled(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj); if (!nativeThis) return JS_FALSE; *rval = JSVAL_FALSE; nsIScriptGlobalObject *globalObject = nsnull; nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) globalObject = scriptContext->GetGlobalObject(); PRBool nativeRet = PR_FALSE; if (globalObject) nativeThis->UpdateEnabled(globalObject, XPI_GLOBAL, &nativeRet); *rval = BOOLEAN_TO_JSVAL(nativeRet); return JS_TRUE; }
AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull) : mScriptIsRunning(false) { MOZ_ASSERT_IF(!allowNull, cx); // Hold a strong ref to the nsIScriptContext, if any. This ensures that we // only destroy the mContext of an nsJSContext when it is not on the cx stack // (and therefore not in use). See nsJSContext::DestroyJSContext(). if (cx) mScx = GetScriptContextFromJSContext(cx); // NB: The GetDynamicScriptContext is historical and might not be sane. XPCJSContextStack *stack = XPCJSRuntime::Get()->GetJSContextStack(); if (cx && nsJSUtils::GetDynamicScriptContext(cx) && stack->HasJSContext(cx)) { // If the context is on the stack, that means that a script // is running at the moment in the context. mScriptIsRunning = true; } if (!stack->Push(cx)) { MOZ_CRASH(); } #ifdef DEBUG mPushedContext = cx; mCompartmentDepthOnEntry = cx ? js::GetEnterCompartmentDepth(cx) : 0; #endif // Enter a request and a compartment for the duration that the cx is on the // stack if non-null. // // NB: We call UnmarkGrayContext so that this can obsolete the need for the // old XPCAutoRequest as well. if (cx) { mAutoRequest.construct(cx); if (js::DefaultObjectForContextOrNull(cx)) mAutoCompartment.construct(cx, js::DefaultObjectForContextOrNull(cx)); xpc_UnmarkGrayContext(cx); } }
/* * Class: com_google_gwt_dev_shell_moz_LowLevelMoz * Method: _executeScriptWithInfo * Signature: (ILjava/lang/String;Ljava/lang/String;I)Z */ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1executeScriptWithInfo (JNIEnv* env, jclass llClass, jint scriptObjectInt, jstring code, jstring file, jint line) { Tracer tracer("LowLevelMoz._executeScriptWithInfo"); JStringWrap jcode(env, code); if (!jcode.jstr()) { tracer.setFail("null code string"); return JNI_FALSE; } JStringWrap jfile(env, file); if (!jfile.str()) { tracer.setFail("null file name"); return JNI_FALSE; } tracer.log("code=%s, file=%s, line=%d", jcode.str(), jfile.str(), line); JSContext* cx = JsRootedValue::currentContext(); nsCOMPtr<nsIScriptContext> scriptContext(GetScriptContextFromJSContext(cx)); nsIScriptGlobalObject* scriptObject = NS_REINTERPRET_CAST(nsIScriptGlobalObject*, scriptObjectInt); JSObject* scriptWindow = reinterpret_cast<JSObject*>(scriptObject->GetGlobalJSObject()); nsXPIDLString scriptString; scriptString = jcode.jstr(); nsXPIDLString aRetValue; PRBool aIsUndefined; if (NS_FAILED(scriptContext->EvaluateString(scriptString, scriptWindow, 0, jfile.str(), line, 0, aRetValue, &aIsUndefined))) { tracer.setFail("EvaluateString failed"); return JNI_FALSE; } return JNI_TRUE; }
// // Native method InstallChrome // static JSBool InstallTriggerGlobalInstallChrome(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj); if (!nativeThis) return JS_FALSE; uint32 chromeType = NOT_CHROME; nsAutoString sourceURL; nsAutoString name; *rval = JSVAL_FALSE; // get chromeType first, the update enabled check for skins skips whitelisting if (argc >=1) { if (!JS_ValueToECMAUint32(cx, argv[0], &chromeType)) return JS_FALSE; } // make sure XPInstall is enabled, return if not nsIScriptGlobalObject *globalObject = nsnull; nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) globalObject = scriptContext->GetGlobalObject(); if (!globalObject) return JS_TRUE; // get window.location to construct relative URLs nsCOMPtr<nsIURI> baseURL; JSObject* global = JS_GetGlobalObject(cx); if (global) { jsval v; if (JS_GetProperty(cx,global,"location",&v)) { nsAutoString location; ConvertJSValToStr( location, cx, v ); NS_NewURI(getter_AddRefs(baseURL), location); } } if ( argc >= 3 ) { ConvertJSValToStr(sourceURL, cx, argv[1]); ConvertJSValToStr(name, cx, argv[2]); if (baseURL) { nsCAutoString resolvedURL; baseURL->Resolve(NS_ConvertUTF16toUTF8(sourceURL), resolvedURL); sourceURL = NS_ConvertUTF8toUTF16(resolvedURL); } // Make sure caller is allowed to load this url. nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, sourceURL); if (NS_FAILED(rv)) return JS_FALSE; if ( chromeType & CHROME_ALL ) { // there's at least one known chrome type nsCOMPtr<nsIURI> checkuri; nsresult rv = nativeThis->GetOriginatingURI(globalObject, getter_AddRefs(checkuri)); if (NS_SUCCEEDED(rv)) { nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo()); nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(name.get(), sourceURL.get(), nsnull)); if (trigger && item) { // trigger will free item when complete trigger->Add(item.forget()); nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject)); nsCOMPtr<nsIXPIInstallInfo> installInfo = new nsXPIInstallInfo(win, checkuri, trigger, chromeType); if (installInfo) { // installInfo owns trigger now trigger.forget(); PRBool enabled = PR_FALSE; nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled); if (!enabled) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(installInfo, "xpinstall-install-blocked", nsnull); } else { PRBool nativeRet = PR_FALSE; nativeThis->StartInstall(installInfo, &nativeRet); *rval = BOOLEAN_TO_JSVAL(nativeRet); } } } } } } return JS_TRUE; }
bool PushJSContextNoScriptContext(JSContext *aCx) { MOZ_ASSERT_IF(aCx, !GetScriptContextFromJSContext(aCx)); return XPCJSRuntime::Get()->GetJSContextStack()->Push(aCx); }
nsIScriptContext * nsJSUtils::GetDynamicScriptContext(JSContext *aContext) { return GetScriptContextFromJSContext(aContext); }
// // Native method StartSoftwareUpdate // static JSBool InstallTriggerGlobalStartSoftwareUpdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj); if (!nativeThis) return JS_FALSE; PRBool nativeRet; PRInt32 flags = 0; *rval = JSVAL_FALSE; nsIScriptGlobalObject *globalObject = nsnull; nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) globalObject = scriptContext->GetGlobalObject(); if (!globalObject) return JS_TRUE; // get window.location to construct relative URLs nsCOMPtr<nsIURI> baseURL; JSObject* global = JS_GetGlobalObject(cx); if (global) { jsval v; if (JS_GetProperty(cx,global,"location",&v)) { nsAutoString location; ConvertJSValToStr( location, cx, v ); NS_NewURI(getter_AddRefs(baseURL), location); } } if ( argc >= 1 ) { nsAutoString xpiURL; ConvertJSValToStr(xpiURL, cx, argv[0]); if (baseURL) { nsCAutoString resolvedURL; baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL); xpiURL = NS_ConvertUTF8toUTF16(resolvedURL); } // Make sure caller is allowed to load this url. nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL); if (NS_FAILED(rv)) return JS_FALSE; if (argc >= 2 && !JS_ValueToInt32(cx, argv[1], (int32 *)&flags)) { JS_ReportError(cx, "StartSoftwareUpdate() 2nd parameter must be a number"); return JS_FALSE; } nsCOMPtr<nsIURI> checkuri; rv = nativeThis->GetOriginatingURI(globalObject, getter_AddRefs(checkuri)); if (NS_SUCCEEDED(rv)) { nsAutoPtr<nsXPITriggerInfo> trigger(new nsXPITriggerInfo()); nsAutoPtr<nsXPITriggerItem> item(new nsXPITriggerItem(0, xpiURL.get(), nsnull)); if (trigger && item) { // trigger will free item when complete trigger->Add(item.forget()); nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject)); nsCOMPtr<nsIXPIInstallInfo> installInfo = new nsXPIInstallInfo(win, checkuri, trigger, 0); if (installInfo) { // From here trigger is owned by installInfo until passed on to nsXPInstallManager trigger.forget(); PRBool enabled = PR_FALSE; nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled); if (!enabled) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(installInfo, "xpinstall-install-blocked", nsnull); } else { nativeThis->StartInstall(installInfo, &nativeRet); *rval = BOOLEAN_TO_JSVAL(nativeRet); } } } } } else { JS_ReportError(cx, "Function StartSoftwareUpdate requires 1 parameters"); return JS_FALSE; } return JS_TRUE; }
nsresult nsDOMStorage::SetDBValue(const nsAString& aKey, const nsAString& aValue, PRBool aSecure) { #ifdef MOZ_STORAGE if (!UseDB()) return NS_OK; nsresult rv = InitDB(); NS_ENSURE_SUCCESS(rv, rv); // Get the current domain for quota enforcement nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager(); if (!ssm) return NS_ERROR_FAILURE; nsCOMPtr<nsIPrincipal> subjectPrincipal; ssm->GetSubjectPrincipal(getter_AddRefs(subjectPrincipal)); nsCAutoString currentDomain; if (subjectPrincipal) { nsCOMPtr<nsIURI> unused; rv = GetPrincipalURIAndHost(subjectPrincipal, getter_AddRefs(unused), currentDomain); // Don't bail out on NS_ERROR_DOM_SECURITY_ERR, since we want to allow // trusted file:// URIs below. if (NS_FAILED(rv) && rv != NS_ERROR_DOM_SECURITY_ERR) { return rv; } if (currentDomain.IsEmpty()) { // allow chrome urls and trusted file urls to write using // the storage's domain if (nsContentUtils::IsCallerTrustedForWrite()) currentDomain = mDomain; else return NS_ERROR_DOM_SECURITY_ERR; } } else { currentDomain = mDomain; } PRInt32 quota; PRInt32 warnQuota; GetQuota(currentDomain, "a, &warnQuota); PRInt32 usage; rv = gStorageDB->SetKey(this, aKey, aValue, aSecure, quota, &usage); NS_ENSURE_SUCCESS(rv, rv); mItemsCached = PR_FALSE; if (warnQuota >= 0 && usage > warnQuota) { // try to include the window that exceeded the warn quota nsCOMPtr<nsIDOMWindow> window; JSContext *cx; nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) { nsCOMPtr<nsIScriptContext> scriptContext; scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) { window = do_QueryInterface(scriptContext->GetGlobalObject()); } } nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1"); os->NotifyObservers(window, "dom-storage-warn-quota-exceeded", NS_ConvertUTF8toUTF16(currentDomain).get()); } BroadcastChangeNotification(); #endif return NS_OK; }
// // Native method Install // static JSBool InstallTriggerGlobalInstall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { nsIDOMInstallTriggerGlobal *nativeThis = getTriggerNative(cx, obj); if (!nativeThis) return JS_FALSE; *rval = JSVAL_FALSE; // make sure XPInstall is enabled, return false if not nsIScriptGlobalObject *globalObject = nsnull; nsIScriptContext *scriptContext = GetScriptContextFromJSContext(cx); if (scriptContext) globalObject = scriptContext->GetGlobalObject(); if (!globalObject) return JS_TRUE; nsCOMPtr<nsIScriptSecurityManager> secman(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID)); if (!secman) { JS_ReportError(cx, "Could not the script security manager service."); return JS_FALSE; } // get the principal. if it doesn't exist, die. nsCOMPtr<nsIPrincipal> principal; secman->GetSubjectPrincipal(getter_AddRefs(principal)); if (!principal) { JS_ReportError(cx, "Could not get the Subject Principal during InstallTrigger.Install()"); return JS_FALSE; } // get window.location to construct relative URLs nsCOMPtr<nsIURI> baseURL; JSObject* global = JS_GetGlobalObject(cx); if (global) { jsval v; if (JS_GetProperty(cx,global,"location",&v)) { nsAutoString location; ConvertJSValToStr( location, cx, v ); NS_NewURI(getter_AddRefs(baseURL), location); } } PRBool abortLoad = PR_FALSE; // parse associative array of installs if ( argc >= 1 && JSVAL_IS_OBJECT(argv[0]) && JSVAL_TO_OBJECT(argv[0]) ) { nsXPITriggerInfo *trigger = new nsXPITriggerInfo(); if (!trigger) return JS_FALSE; trigger->SetPrincipal(principal); JSIdArray *ida = JS_Enumerate( cx, JSVAL_TO_OBJECT(argv[0]) ); if ( ida ) { jsval v; const PRUnichar *name, *URL; const PRUnichar *iconURL = nsnull; for (int i = 0; i < ida->length && !abortLoad; i++ ) { JS_IdToValue( cx, ida->vector[i], &v ); JSString * str = JS_ValueToString( cx, v ); if (!str) { abortLoad = PR_TRUE; break; } name = reinterpret_cast<const PRUnichar*>(JS_GetStringChars( str )); URL = iconURL = nsnull; JSAutoByteString hash; JS_GetUCProperty( cx, JSVAL_TO_OBJECT(argv[0]), reinterpret_cast<const jschar*>(name), nsCRT::strlen(name), &v ); if ( JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) ) { jsval v2; if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "URL", &v2 ) && !JSVAL_IS_VOID(v2)) { JSString *str = JS_ValueToString(cx, v2); if (!str) { abortLoad = PR_TRUE; break; } URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); } if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "IconURL", &v2 ) && !JSVAL_IS_VOID(v2)) { JSString *str = JS_ValueToString(cx, v2); if (!str) { abortLoad = PR_TRUE; break; } iconURL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); } if (JS_GetProperty( cx, JSVAL_TO_OBJECT(v), "Hash", &v2) && !JSVAL_IS_VOID(v2)) { JSString *str = JS_ValueToString(cx, v2); if (!str || !hash.encode(cx, str)) { abortLoad = PR_TRUE; break; } } } else { JSString *str = JS_ValueToString(cx, v); if (!str) { abortLoad = PR_TRUE; break; } URL = reinterpret_cast<const PRUnichar*>(JS_GetStringChars(str)); } if ( URL ) { // Get relative URL to load nsAutoString xpiURL(URL); if (baseURL) { nsCAutoString resolvedURL; baseURL->Resolve(NS_ConvertUTF16toUTF8(xpiURL), resolvedURL); xpiURL = NS_ConvertUTF8toUTF16(resolvedURL); } nsAutoString icon(iconURL); if (iconURL && baseURL) { nsCAutoString resolvedIcon; baseURL->Resolve(NS_ConvertUTF16toUTF8(icon), resolvedIcon); icon = NS_ConvertUTF8toUTF16(resolvedIcon); } // Make sure we're allowed to load this URL and the icon URL nsresult rv = InstallTriggerCheckLoadURIFromScript(cx, xpiURL); if (NS_FAILED(rv)) abortLoad = PR_TRUE; if (!abortLoad && iconURL) { rv = InstallTriggerCheckLoadURIFromScript(cx, icon); if (NS_FAILED(rv)) abortLoad = PR_TRUE; } if (!abortLoad) { // Add the install item to the trigger collection nsXPITriggerItem *item = new nsXPITriggerItem( name, xpiURL.get(), icon.get(), hash ); if ( item ) { trigger->Add( item ); } else abortLoad = PR_TRUE; } } else abortLoad = PR_TRUE; } JS_DestroyIdArray( cx, ida ); } // pass on only if good stuff found if (!abortLoad && trigger->Size() > 0) { nsCOMPtr<nsIURI> checkuri; nsresult rv = nativeThis->GetOriginatingURI(globalObject, getter_AddRefs(checkuri)); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(globalObject)); nsCOMPtr<nsIXPIInstallInfo> installInfo = new nsXPIInstallInfo(win, checkuri, trigger, 0); if (installInfo) { // installInfo now owns triggers PRBool enabled = PR_FALSE; nativeThis->UpdateEnabled(checkuri, XPI_WHITELIST, &enabled); if (!enabled) { nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(installInfo, "xpinstall-install-blocked", nsnull); } else { // save callback function if any (ignore bad args for now) if ( argc >= 2 && JS_TypeOfValue(cx,argv[1]) == JSTYPE_FUNCTION ) { trigger->SaveCallback( cx, argv[1] ); } PRBool result; nativeThis->StartInstall(installInfo, &result); *rval = BOOLEAN_TO_JSVAL(result); } return JS_TRUE; } } } // didn't pass it on so we must delete trigger delete trigger; } JS_ReportError(cx, "Incorrect arguments to InstallTrigger.Install()"); return JS_FALSE; }
nsresult nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent) { nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mTarget); if (!target || !mContext || !mHandler) return NS_ERROR_FAILURE; nsresult rv; nsCOMPtr<nsIMutableArray> iargv; bool handledScriptError = false; if (mEventName == nsGkAtoms::onerror) { nsCOMPtr<nsIPrivateDOMEvent> priv(do_QueryInterface(aEvent)); NS_ENSURE_TRUE(priv, NS_ERROR_UNEXPECTED); nsEvent *event = priv->GetInternalNSEvent(); if (event->message == NS_LOAD_ERROR && event->eventStructType == NS_SCRIPT_ERROR_EVENT) { nsScriptErrorEvent *scriptEvent = static_cast<nsScriptErrorEvent*>(event); // Create a temp argv for the error event. iargv = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; // Append the event args. nsCOMPtr<nsIWritableVariant> var(do_CreateInstance(NS_VARIANT_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, rv); rv = var->SetAsWString(scriptEvent->errorMsg); NS_ENSURE_SUCCESS(rv, rv); rv = iargv->AppendElement(var, false); NS_ENSURE_SUCCESS(rv, rv); // filename var = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = var->SetAsWString(scriptEvent->fileName); NS_ENSURE_SUCCESS(rv, rv); rv = iargv->AppendElement(var, false); NS_ENSURE_SUCCESS(rv, rv); // line number var = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = var->SetAsUint32(scriptEvent->lineNr); NS_ENSURE_SUCCESS(rv, rv); rv = iargv->AppendElement(var, false); NS_ENSURE_SUCCESS(rv, rv); handledScriptError = true; } } if (!handledScriptError) { iargv = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; NS_ENSURE_TRUE(iargv != nsnull, NS_ERROR_OUT_OF_MEMORY); rv = iargv->AppendElement(aEvent, false); NS_ENSURE_SUCCESS(rv, rv); } // mContext is the same context which event listener manager pushes // to JS context stack. #ifdef NS_DEBUG JSContext* cx = nsnull; nsCOMPtr<nsIJSContextStack> stack = do_GetService("@mozilla.org/js/xpc/ContextStack;1"); NS_ASSERTION(stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx && GetScriptContextFromJSContext(cx) == mContext, "JSEventListener has wrong script context?"); #endif nsCOMPtr<nsIVariant> vrv; xpc_UnmarkGrayObject(mScopeObject); xpc_UnmarkGrayObject(mHandler); rv = mContext->CallEventHandler(mTarget, mScopeObject, mHandler, iargv, getter_AddRefs(vrv)); if (NS_SUCCEEDED(rv)) { PRUint16 dataType = nsIDataType::VTYPE_VOID; if (vrv) vrv->GetDataType(&dataType); if (mEventName == nsGkAtoms::onbeforeunload) { nsCOMPtr<nsIDOMBeforeUnloadEvent> beforeUnload = do_QueryInterface(aEvent); NS_ENSURE_STATE(beforeUnload); if (dataType != nsIDataType::VTYPE_VOID) { aEvent->PreventDefault(); nsAutoString text; beforeUnload->GetReturnValue(text); // Set the text in the beforeUnload event as long as it wasn't // already set (through event.returnValue, which takes // precedence over a value returned from a JS function in IE) if ((dataType == nsIDataType::VTYPE_DOMSTRING || dataType == nsIDataType::VTYPE_CHAR_STR || dataType == nsIDataType::VTYPE_WCHAR_STR || dataType == nsIDataType::VTYPE_STRING_SIZE_IS || dataType == nsIDataType::VTYPE_WSTRING_SIZE_IS || dataType == nsIDataType::VTYPE_CSTRING || dataType == nsIDataType::VTYPE_ASTRING) && text.IsEmpty()) { vrv->GetAsDOMString(text); beforeUnload->SetReturnValue(text); } } } else if (dataType == nsIDataType::VTYPE_BOOL) { // If the handler returned false and its sense is not reversed, // or the handler returned true and its sense is reversed from // the usual (false means cancel), then prevent default. bool brv; if (NS_SUCCEEDED(vrv->GetAsBool(&brv)) && brv == (mEventName == nsGkAtoms::onerror || mEventName == nsGkAtoms::onmouseover)) { aEvent->PreventDefault(); } } } return rv; }