void MediaRecorder::NotifyError(nsresult aRv) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return; } nsString errorMsg; switch (aRv) { case NS_ERROR_DOM_SECURITY_ERR: errorMsg = NS_LITERAL_STRING("SecurityError"); break; case NS_ERROR_OUT_OF_MEMORY: errorMsg = NS_LITERAL_STRING("OutOfMemoryError"); break; default: errorMsg = NS_LITERAL_STRING("GenericError"); } nsCOMPtr<nsIDOMEvent> event; rv = NS_NewDOMRecordErrorEvent(getter_AddRefs(event), this, nullptr, nullptr); nsCOMPtr<nsIDOMRecordErrorEvent> errorEvent = do_QueryInterface(event); rv = errorEvent->InitRecordErrorEvent(NS_LITERAL_STRING("error"), false, false, errorMsg); event->SetTrusted(true); rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr); if (NS_FAILED(rv)) { NS_ERROR("Failed to dispatch the error event!!!"); return; } return; }
void MediaRecorder::DispatchSimpleEvent(const nsAString & aStr) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return; } nsCOMPtr<nsIDOMEvent> event; rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr); if (NS_FAILED(rv)) { NS_WARNING("Failed to create the error event!!!"); return; } rv = event->InitEvent(aStr, false, false); if (NS_FAILED(rv)) { NS_WARNING("Failed to init the error event!!!"); return; } event->SetTrusted(true); rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr); if (NS_FAILED(rv)) { NS_ERROR("Failed to dispatch the event!!!"); return; } }
nsPIDOMWindowInner* DOMEventTargetHelper::GetWindowIfCurrent() const { if (NS_FAILED(CheckInnerWindowCorrectness())) { return nullptr; } return GetOwner(); }
nsIScriptContext* nsDOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv) { *aRv = CheckInnerWindowCorrectness(); if (NS_FAILED(*aRv)) { return nsnull; } return mScriptContext; }
void IDBRequest::SetResultCallback(ResultCallback* aCallback) { AssertIsOnOwningThread(); MOZ_ASSERT(aCallback); MOZ_ASSERT(!mHaveResultOrErrorCode); MOZ_ASSERT(mResultVal.isUndefined()); MOZ_ASSERT(!mError); // See if our window is still valid. if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) { SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return; } AutoJSAPI autoJS; Maybe<JSAutoCompartment> ac; if (GetScriptOwner()) { // If we have a script owner we want the SafeJSContext and then to enter the // script owner's compartment. autoJS.Init(); JS::ExposeObjectToActiveJS(GetScriptOwner()); ac.emplace(autoJS.cx(), GetScriptOwner()); } else { // Otherwise our owner is a window and we use that to initialize. MOZ_ASSERT(GetOwner()); if (!autoJS.Init(GetOwner())) { IDB_WARNING("Failed to initialize AutoJSAPI!"); SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return; } } JSContext* cx = autoJS.cx(); AssertIsRooted(); JS::Rooted<JS::Value> result(cx); nsresult rv = aCallback->GetResult(cx, &result); if (NS_WARN_IF(NS_FAILED(rv))) { // This can only fail if the structured clone contains a mutable file // and the child is not in the main thread and main process. // In that case CreateAndWrapMutableFile() returns false which shows up // as NS_ERROR_DOM_DATA_CLONE_ERR here. MOZ_ASSERT(rv == NS_ERROR_DOM_DATA_CLONE_ERR); // We are not setting a result or an error object here since we want to // throw an exception when the 'result' property is being touched. return; } mError = nullptr; mResultVal = result; mHaveResultOrErrorCode = true; }
nsresult IDBRequest::NotifyHelperCompleted(HelperBase* aHelper) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); mHaveResultOrErrorCode = true; nsresult rv = aHelper->GetResultCode(); // If the request failed then set the error code and return. if (NS_FAILED(rv)) { SetError(rv); return NS_OK; } // See if our window is still valid. If not then we're going to pretend that // we never completed. if (NS_FAILED(CheckInnerWindowCorrectness())) { return NS_OK; } // Otherwise we need to get the result from the helper. AutoPushJSContext cx(GetJSContext()); if (!cx) { NS_WARNING("Failed to get safe JSContext!"); rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; SetError(rv); return rv; } JS::Rooted<JSObject*> global(cx, GetParentObject()); NS_ASSERTION(global, "This should never be null!"); JSAutoRequest ar(cx); JSAutoCompartment ac(cx, global); AssertIsRooted(); rv = aHelper->GetSuccessResult(cx, &mResultVal); if (NS_FAILED(rv)) { NS_WARNING("GetSuccessResult failed!"); } if (NS_SUCCEEDED(rv)) { mError = nullptr; } else { SetError(rv); mResultVal = JSVAL_VOID; } return rv; }
nsresult DOMEventTargetHelper::WantsUntrusted(bool* aRetVal) { nsresult rv = CheckInnerWindowCorrectness(); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIDocument> doc = GetDocumentIfCurrent(); // We can let listeners on workers to always handle all the events. *aRetVal = (doc && !nsContentUtils::IsChromeDoc(doc)) || !NS_IsMainThread(); return rv; }
nsIScriptContext* DOMEventTargetHelper::GetContextForEventHandlers(nsresult* aRv) { *aRv = CheckInnerWindowCorrectness(); if (NS_FAILED(*aRv)) { return nullptr; } nsPIDOMWindowInner* owner = GetOwner(); return owner ? nsGlobalWindow::Cast(owner)->GetContextInternal() : nullptr; }
void DesktopNotification::HandleAlertServiceNotification(const char *aTopic) { if (NS_FAILED(CheckInnerWindowCorrectness())) { return; } if (!strcmp("alertclickcallback", aTopic)) { DispatchNotificationEvent(NS_LITERAL_STRING("click")); } else if (!strcmp("alertfinished", aTopic)) { DispatchNotificationEvent(NS_LITERAL_STRING("close")); } }
void IDBRequest::SetResultCallback(ResultCallback* aCallback) { AssertIsOnOwningThread(); MOZ_ASSERT(aCallback); MOZ_ASSERT(!mHaveResultOrErrorCode); MOZ_ASSERT(mResultVal.isUndefined()); MOZ_ASSERT(!mError); // See if our window is still valid. if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) { IDB_REPORT_INTERNAL_ERR(); SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return; } AutoJSAPI autoJS; Maybe<JSAutoCompartment> ac; if (GetScriptOwner()) { // If we have a script owner we want the SafeJSContext and then to enter the // script owner's compartment. autoJS.Init(); ac.emplace(autoJS.cx(), GetScriptOwner()); } else { // Otherwise our owner is a window and we use that to initialize. MOZ_ASSERT(GetOwner()); if (!autoJS.InitWithLegacyErrorReporting(GetOwner())) { IDB_WARNING("Failed to initialize AutoJSAPI!"); SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return; } } JSContext* cx = autoJS.cx(); AssertIsRooted(); JS::Rooted<JS::Value> result(cx); nsresult rv = aCallback->GetResult(cx, &result); if (NS_WARN_IF(NS_FAILED(rv))) { SetError(rv); mResultVal.setUndefined(); } else { mError = nullptr; mResultVal = result; } mHaveResultOrErrorCode = true; }
NS_IMETHODIMP EventSource::AsyncOnChannelRedirect(nsIChannel *aOldChannel, nsIChannel *aNewChannel, uint32_t aFlags, nsIAsyncVerifyRedirectCallback *aCallback) { nsCOMPtr<nsIRequest> aOldRequest = do_QueryInterface(aOldChannel); NS_PRECONDITION(aOldRequest, "Redirect from a null request?"); nsresult rv = CheckHealthOfRequestCallback(aOldRequest); NS_ENSURE_SUCCESS(rv, rv); NS_PRECONDITION(aNewChannel, "Redirect without a channel?"); nsCOMPtr<nsIURI> newURI; rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI)); NS_ENSURE_SUCCESS(rv, rv); bool isValidScheme = (NS_SUCCEEDED(newURI->SchemeIs("http", &isValidScheme)) && isValidScheme) || (NS_SUCCEEDED(newURI->SchemeIs("https", &isValidScheme)) && isValidScheme); rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv) || !isValidScheme) { DispatchFailConnection(); return NS_ERROR_DOM_SECURITY_ERR; } // update our channel mHttpChannel = do_QueryInterface(aNewChannel); NS_ENSURE_STATE(mHttpChannel); rv = SetupHttpChannel(); NS_ENSURE_SUCCESS(rv, rv); if ((aFlags & nsIChannelEventSink::REDIRECT_PERMANENT) != 0) { rv = NS_GetFinalChannelURI(mHttpChannel, getter_AddRefs(mSrc)); NS_ENSURE_SUCCESS(rv, rv); } aCallback->OnRedirectVerifyCallback(NS_OK); return NS_OK; }
void UDPSocket::HandleReceivedData(const nsACString& aRemoteAddress, const uint16_t& aRemotePort, const uint8_t* aData, const uint32_t& aDataLength) { if (mReadyState != SocketReadyState::Open) { return; } if (NS_FAILED(CheckInnerWindowCorrectness())) { return; } if (NS_FAILED(DispatchReceivedData(aRemoteAddress, aRemotePort, aData, aDataLength))) { CloseWithReason(NS_ERROR_TYPE_ERR); } }
void DesktopNotification::DispatchNotificationEvent(const nsString& aName) { if (NS_FAILED(CheckInnerWindowCorrectness())) { return; } nsCOMPtr<nsIDOMEvent> event; nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr); if (NS_SUCCEEDED(rv)) { // it doesn't bubble, and it isn't cancelable rv = event->InitEvent(aName, false, false); if (NS_SUCCEEDED(rv)) { event->SetTrusted(true); DispatchDOMEvent(nullptr, event, nullptr, nullptr); } } }
void IDBRequest::NotifyHelperSentResultsToChildProcess(nsresult aRv) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); // See if our window is still valid. If not then we're going to pretend that // we never completed. if (NS_FAILED(CheckInnerWindowCorrectness())) { return; } mHaveResultOrErrorCode = true; if (NS_FAILED(aRv)) { SetError(aRv); } }
NS_IMETHODIMP WebSocket::OnStart(nsISupports* aContext) { NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread"); // This is the only function that sets OPEN, and should be called only once MOZ_ASSERT(mReadyState != WebSocket::OPEN, "readyState already OPEN! OnStart called twice?"); // Nothing to do if we've already closed/closing if (mReadyState != WebSocket::CONNECTING) { return NS_OK; } // Attempt to kill "ghost" websocket: but usually too early for check to fail nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY); return rv; } if (!mRequestedProtocolList.IsEmpty()) { mChannel->GetProtocol(mEstablishedProtocol); } mChannel->GetExtensions(mEstablishedExtensions); UpdateURI(); mReadyState = WebSocket::OPEN; // Call 'onopen' rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open")); if (NS_FAILED(rv)) { NS_WARNING("Failed to dispatch the open event"); } UpdateMustKeepAlive(); return NS_OK; }
void FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal) { if (NS_FAILED(CheckInnerWindowCorrectness())) { return; } nsCOMPtr<nsIDOMEvent> event; nsresult rv = NS_NewDOMProgressEvent(getter_AddRefs(event), nullptr, nullptr); if (NS_FAILED(rv)) { return; } nsCOMPtr<nsIDOMProgressEvent> progress = do_QueryInterface(event); MOZ_ASSERT(progress); rv = progress->InitProgressEvent(NS_LITERAL_STRING("progress"), false, false, false, aLoaded, aTotal); if (NS_FAILED(rv)) { return; } DispatchTrustedEvent(event); }
void EventSource::ReestablishConnection() { if (mReadyState == CLOSED) { return; } nsresult rv = ResetConnection(); if (NS_FAILED(rv)) { NS_WARNING("Failed to reset the connection!!!"); return; } rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return; } RefPtr<Event> event = NS_NewDOMEvent(this, nullptr, nullptr); // it doesn't bubble, and it isn't cancelable event->InitEvent(NS_LITERAL_STRING("error"), false, false); event->SetTrusted(true); rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr); if (NS_FAILED(rv)) { NS_WARNING("Failed to dispatch the error event!!!"); return; } rv = SetReconnectionTimeout(); if (NS_FAILED(rv)) { NS_WARNING("Failed to set the timeout for reestablishing the connection!!!"); return; } }
void EventSource::DispatchAllMessageEvents() { if (mReadyState == CLOSED || mFrozen) { return; } mGoingToDispatchAllMessages = false; nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv)) { return; } AutoJSAPI jsapi; if (NS_WARN_IF(!jsapi.Init(GetOwner()))) { return; } JSContext* cx = jsapi.cx(); while (mMessagesToDispatch.GetSize() > 0) { nsAutoPtr<Message> message(static_cast<Message*>(mMessagesToDispatch.PopFront())); // Now we can turn our string into a jsval JS::Rooted<JS::Value> jsData(cx); { JSString* jsString; jsString = JS_NewUCStringCopyN(cx, message->mData.get(), message->mData.Length()); NS_ENSURE_TRUE_VOID(jsString); jsData.setString(jsString); } // create an event that uses the MessageEvent interface, // which does not bubble, is not cancelable, and has no default action RefPtr<MessageEvent> event = NS_NewDOMMessageEvent(this, nullptr, nullptr); rv = event->InitMessageEvent(message->mEventName, false, false, jsData, mOrigin, message->mLastEventID, nullptr); if (NS_FAILED(rv)) { NS_WARNING("Failed to init the message event!!!"); return; } event->SetTrusted(true); rv = DispatchDOMEvent(nullptr, static_cast<Event*>(event), nullptr, nullptr); if (NS_FAILED(rv)) { NS_WARNING("Failed to dispatch the message event!!!"); return; } mLastEventID.Assign(message->mLastEventID); } }
nsresult IDBRequest::SetDone(AsyncConnectionHelper* aHelper) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(!mHaveResultOrErrorCode, "Already called!"); NS_ASSERTION(!mResultValRooted, "Already rooted?!"); NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!"); // See if our window is still valid. If not then we're going to pretend that // we never completed. if (NS_FAILED(CheckInnerWindowCorrectness())) { return NS_OK; } mHaveResultOrErrorCode = true; nsresult rv = aHelper->GetResultCode(); // If the request failed then set the error code and return. if (NS_FAILED(rv)) { mErrorCode = NS_ERROR_GET_CODE(rv); return NS_OK; } // Otherwise we need to get the result from the helper. JSContext* cx = static_cast<JSContext*>(mScriptContext->GetNativeContext()); NS_ASSERTION(cx, "Failed to get a context!"); JSObject* global = static_cast<JSObject*>(mScriptContext->GetNativeGlobal()); NS_ASSERTION(global, "Failed to get global object!"); JSAutoRequest ar(cx); JSAutoEnterCompartment ac; if (!ac.enter(cx, global)) { rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } else { RootResultVal(); rv = aHelper->GetSuccessResult(cx, &mResultVal); if (NS_SUCCEEDED(rv)) { // Unroot if we don't really need to be rooted. if (!JSVAL_IS_GCTHING(mResultVal)) { UnrootResultVal(); } } else { NS_WARNING("GetSuccessResult failed!"); } } if (NS_SUCCEEDED(rv)) { mErrorCode = 0; } else { mErrorCode = NS_ERROR_GET_CODE(rv); mResultVal = JSVAL_VOID; } return rv; }
nsresult EventSource::InitChannelAndRequestEventSource() { if (mReadyState == CLOSED) { return NS_ERROR_ABORT; } bool isValidScheme = (NS_SUCCEEDED(mSrc->SchemeIs("http", &isValidScheme)) && isValidScheme) || (NS_SUCCEEDED(mSrc->SchemeIs("https", &isValidScheme)) && isValidScheme); nsresult rv = CheckInnerWindowCorrectness(); if (NS_FAILED(rv) || !isValidScheme) { DispatchFailConnection(); return NS_ERROR_DOM_SECURITY_ERR; } nsLoadFlags loadFlags; loadFlags = nsIRequest::LOAD_BACKGROUND | nsIRequest::LOAD_BYPASS_CACHE; nsIScriptContext* sc = GetContextForEventHandlers(&rv); nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromScriptContext(sc); nsSecurityFlags securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS; if (mWithCredentials) { securityFlags |= nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS; } nsCOMPtr<nsIChannel> channel; // If we have the document, use it if (doc) { rv = NS_NewChannel(getter_AddRefs(channel), mSrc, doc, securityFlags, nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE, mLoadGroup, // loadGroup nullptr, // aCallbacks loadFlags); // aLoadFlags } else { // otherwise use the principal rv = NS_NewChannel(getter_AddRefs(channel), mSrc, mPrincipal, securityFlags, nsIContentPolicy::TYPE_INTERNAL_EVENTSOURCE, mLoadGroup, // loadGroup nullptr, // aCallbacks loadFlags); // aLoadFlags } NS_ENSURE_SUCCESS(rv, rv); mHttpChannel = do_QueryInterface(channel); NS_ENSURE_TRUE(mHttpChannel, NS_ERROR_NO_INTERFACE); rv = SetupHttpChannel(); NS_ENSURE_SUCCESS(rv, rv); #ifdef DEBUG { nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks; mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks)); MOZ_ASSERT(!notificationCallbacks); } #endif mHttpChannel->SetNotificationCallbacks(this); // Start reading from the channel rv = mHttpChannel->AsyncOpen2(this); if (NS_FAILED(rv)) { DispatchFailConnection(); return rv; } mWaitingForOnStopRequest = true; return rv; }