mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-26 00:57:30 +09:00
Issue #1990 - Part 2 - Fix crash when incorrectly access EventSourceImpl::mEventSource. - Mozilla Bug 1333099
This commit is contained in:
parent
e27289d569
commit
ee996121aa
1 changed files with 57 additions and 12 deletions
|
|
@ -158,8 +158,8 @@ public:
|
||||||
|
|
||||||
uint16_t ReadyState()
|
uint16_t ReadyState()
|
||||||
{
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
if (mEventSource) {
|
if (mEventSource) {
|
||||||
MutexAutoLock lock(mMutex);
|
|
||||||
return mEventSource->mReadyState;
|
return mEventSource->mReadyState;
|
||||||
}
|
}
|
||||||
// EventSourceImpl keeps EventSource alive. If mEventSource is null, it
|
// EventSourceImpl keeps EventSource alive. If mEventSource is null, it
|
||||||
|
|
@ -169,8 +169,9 @@ public:
|
||||||
|
|
||||||
void SetReadyState(uint16_t aReadyState)
|
void SetReadyState(uint16_t aReadyState)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mEventSource);
|
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(mEventSource);
|
||||||
|
MOZ_ASSERT(!mIsShutDown);
|
||||||
mEventSource->mReadyState = aReadyState;
|
mEventSource->mReadyState = aReadyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,6 +192,19 @@ public:
|
||||||
return ReadyState() == CLOSED;
|
return ReadyState() == CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShutDown()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
MOZ_ASSERT(!mIsShutDown);
|
||||||
|
mIsShutDown = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsShutDown()
|
||||||
|
{
|
||||||
|
MutexAutoLock lock(mMutex);
|
||||||
|
return mIsShutDown;
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<EventSource> mEventSource;
|
RefPtr<EventSource> mEventSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -292,7 +306,7 @@ public:
|
||||||
// Whether the EventSource is run on main thread.
|
// Whether the EventSource is run on main thread.
|
||||||
bool mIsMainThread;
|
bool mIsMainThread;
|
||||||
// Whether the EventSourceImpl is going to be destroyed.
|
// Whether the EventSourceImpl is going to be destroyed.
|
||||||
bool mIsClosing;
|
bool mIsShutDown;
|
||||||
|
|
||||||
// Event Source owner information:
|
// Event Source owner information:
|
||||||
// - the script file name
|
// - the script file name
|
||||||
|
|
@ -341,7 +355,7 @@ EventSourceImpl::EventSourceImpl(EventSource* aEventSource)
|
||||||
, mFrozen(false)
|
, mFrozen(false)
|
||||||
, mGoingToDispatchAllMessages(false)
|
, mGoingToDispatchAllMessages(false)
|
||||||
, mIsMainThread(NS_IsMainThread())
|
, mIsMainThread(NS_IsMainThread())
|
||||||
, mIsClosing(false)
|
, mIsShutDown(false)
|
||||||
, mScriptLine(0)
|
, mScriptLine(0)
|
||||||
, mScriptColumn(0)
|
, mScriptColumn(0)
|
||||||
, mInnerWindowID(0)
|
, mInnerWindowID(0)
|
||||||
|
|
@ -397,14 +411,12 @@ EventSourceImpl::CloseInternal()
|
||||||
{
|
{
|
||||||
AssertIsOnTargetThread();
|
AssertIsOnTargetThread();
|
||||||
MOZ_ASSERT(IsClosed());
|
MOZ_ASSERT(IsClosed());
|
||||||
if (mIsClosing) {
|
if (IsShutDown()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mIsClosing = true;
|
|
||||||
while (mMessagesToDispatch.GetSize() != 0) {
|
|
||||||
delete static_cast<Message*>(mMessagesToDispatch.PopFront());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Invoke CleanupOnMainThread before cleaning any members. It will call
|
||||||
|
// ShutDown, which is supposed to be called before cleaning any members.
|
||||||
if (NS_IsMainThread()) {
|
if (NS_IsMainThread()) {
|
||||||
CleanupOnMainThread();
|
CleanupOnMainThread();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -417,6 +429,9 @@ EventSourceImpl::CloseInternal()
|
||||||
UnregisterWorkerHolder();
|
UnregisterWorkerHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (mMessagesToDispatch.GetSize() != 0) {
|
||||||
|
delete static_cast<Message*>(mMessagesToDispatch.PopFront());
|
||||||
|
}
|
||||||
SetFrozen(false);
|
SetFrozen(false);
|
||||||
ResetDecoder();
|
ResetDecoder();
|
||||||
mUnicodeDecoder = nullptr;
|
mUnicodeDecoder = nullptr;
|
||||||
|
|
@ -428,6 +443,11 @@ EventSourceImpl::CloseInternal()
|
||||||
void EventSourceImpl::CleanupOnMainThread()
|
void EventSourceImpl::CleanupOnMainThread()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(IsClosed());
|
||||||
|
|
||||||
|
// Call ShutDown before cleaning any members.
|
||||||
|
ShutDown();
|
||||||
|
|
||||||
if (mIsMainThread) {
|
if (mIsMainThread) {
|
||||||
RemoveWindowObservers();
|
RemoveWindowObservers();
|
||||||
}
|
}
|
||||||
|
|
@ -489,6 +509,7 @@ nsresult
|
||||||
EventSourceImpl::ParseURL(const nsAString& aURL)
|
EventSourceImpl::ParseURL(const nsAString& aURL)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
// get the src
|
// get the src
|
||||||
nsCOMPtr<nsIURI> baseURI;
|
nsCOMPtr<nsIURI> baseURI;
|
||||||
nsresult rv = GetBaseURI(getter_AddRefs(baseURI));
|
nsresult rv = GetBaseURI(getter_AddRefs(baseURI));
|
||||||
|
|
@ -517,6 +538,7 @@ EventSourceImpl::AddWindowObservers()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
MOZ_ASSERT(mIsMainThread);
|
MOZ_ASSERT(mIsMainThread);
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||||
NS_ENSURE_STATE(os);
|
NS_ENSURE_STATE(os);
|
||||||
|
|
||||||
|
|
@ -534,6 +556,7 @@ EventSourceImpl::RemoveWindowObservers()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
MOZ_ASSERT(mIsMainThread);
|
MOZ_ASSERT(mIsMainThread);
|
||||||
|
MOZ_ASSERT(IsClosed());
|
||||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||||
if (os) {
|
if (os) {
|
||||||
os->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
os->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
||||||
|
|
@ -549,9 +572,7 @@ EventSourceImpl::Init(nsIPrincipal* aPrincipal,
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
MOZ_ASSERT(aPrincipal);
|
MOZ_ASSERT(aPrincipal);
|
||||||
if (IsClosed()) {
|
MOZ_ASSERT(ReadyState() == CONNECTING);
|
||||||
return;
|
|
||||||
}
|
|
||||||
mPrincipal = aPrincipal;
|
mPrincipal = aPrincipal;
|
||||||
aRv = ParseURL(aURL);
|
aRv = ParseURL(aURL);
|
||||||
if (NS_WARN_IF(aRv.Failed())) {
|
if (NS_WARN_IF(aRv.Failed())) {
|
||||||
|
|
@ -693,6 +714,7 @@ EventSourceImpl::StreamReaderFunc(nsIInputStream* aInputStream,
|
||||||
NS_WARNING("EventSource cannot read from stream: no aClosure or aWriteCount");
|
NS_WARNING("EventSource cannot read from stream: no aClosure or aWriteCount");
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(!thisObject->IsShutDown());
|
||||||
thisObject->ParseSegment((const char*)aFromRawSegment, aCount);
|
thisObject->ParseSegment((const char*)aFromRawSegment, aCount);
|
||||||
*aWriteCount = aCount;
|
*aWriteCount = aCount;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
@ -845,6 +867,9 @@ EventSourceImpl::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||||
nsIAsyncVerifyRedirectCallback* aCallback)
|
nsIAsyncVerifyRedirectCallback* aCallback)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
if (IsClosed()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
nsCOMPtr<nsIRequest> aOldRequest = do_QueryInterface(aOldChannel);
|
nsCOMPtr<nsIRequest> aOldRequest = do_QueryInterface(aOldChannel);
|
||||||
NS_PRECONDITION(aOldRequest, "Redirect from a null request?");
|
NS_PRECONDITION(aOldRequest, "Redirect from a null request?");
|
||||||
|
|
||||||
|
|
@ -894,6 +919,11 @@ NS_IMETHODIMP
|
||||||
EventSourceImpl::GetInterface(const nsIID& aIID, void** aResult)
|
EventSourceImpl::GetInterface(const nsIID& aIID, void** aResult)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
|
||||||
|
if (IsClosed()) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
||||||
*aResult = static_cast<nsIChannelEventSink*>(this);
|
*aResult = static_cast<nsIChannelEventSink*>(this);
|
||||||
NS_ADDREF_THIS();
|
NS_ADDREF_THIS();
|
||||||
|
|
@ -934,6 +964,7 @@ nsresult
|
||||||
EventSourceImpl::GetBaseURI(nsIURI** aBaseURI)
|
EventSourceImpl::GetBaseURI(nsIURI** aBaseURI)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
NS_ENSURE_ARG_POINTER(aBaseURI);
|
NS_ENSURE_ARG_POINTER(aBaseURI);
|
||||||
|
|
||||||
*aBaseURI = nullptr;
|
*aBaseURI = nullptr;
|
||||||
|
|
@ -962,6 +993,7 @@ void
|
||||||
EventSourceImpl::SetupHttpChannel()
|
EventSourceImpl::SetupHttpChannel()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
mHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
|
mHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
|
||||||
|
|
||||||
/* set the http request headers */
|
/* set the http request headers */
|
||||||
|
|
@ -981,6 +1013,7 @@ nsresult
|
||||||
EventSourceImpl::SetupReferrerPolicy()
|
EventSourceImpl::SetupReferrerPolicy()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
nsCOMPtr<nsIDocument> doc = mEventSource->GetDocumentIfCurrent();
|
nsCOMPtr<nsIDocument> doc = mEventSource->GetDocumentIfCurrent();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
nsresult rv = mHttpChannel->SetReferrerWithPolicy(doc->GetDocumentURI(),
|
nsresult rv = mHttpChannel->SetReferrerWithPolicy(doc->GetDocumentURI(),
|
||||||
|
|
@ -1151,6 +1184,9 @@ nsresult
|
||||||
EventSourceImpl::RestartConnection()
|
EventSourceImpl::RestartConnection()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
if (IsClosed()) {
|
||||||
|
return NS_ERROR_ABORT;
|
||||||
|
}
|
||||||
nsresult rv = ResetConnection();
|
nsresult rv = ResetConnection();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
rv = SetReconnectionTimeout();
|
rv = SetReconnectionTimeout();
|
||||||
|
|
@ -1223,6 +1259,7 @@ EventSourceImpl::PrintErrorOnConsole(const char* aBundleURI,
|
||||||
uint32_t aFormatStringsLen)
|
uint32_t aFormatStringsLen)
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||||
mozilla::services::GetStringBundleService();
|
mozilla::services::GetStringBundleService();
|
||||||
NS_ENSURE_STATE(bundleService);
|
NS_ENSURE_STATE(bundleService);
|
||||||
|
|
@ -1270,6 +1307,7 @@ nsresult
|
||||||
EventSourceImpl::ConsoleError()
|
EventSourceImpl::ConsoleError()
|
||||||
{
|
{
|
||||||
AssertIsOnMainThread();
|
AssertIsOnMainThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
nsAutoCString targetSpec;
|
nsAutoCString targetSpec;
|
||||||
nsresult rv = mSrc->GetSpec(targetSpec);
|
nsresult rv = mSrc->GetSpec(targetSpec);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
@ -1400,6 +1438,7 @@ nsresult
|
||||||
EventSourceImpl::DispatchCurrentMessageEvent()
|
EventSourceImpl::DispatchCurrentMessageEvent()
|
||||||
{
|
{
|
||||||
AssertIsOnTargetThread();
|
AssertIsOnTargetThread();
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
nsAutoPtr<Message> message(new Message());
|
nsAutoPtr<Message> message(new Message());
|
||||||
*message = mCurrentMessage;
|
*message = mCurrentMessage;
|
||||||
|
|
||||||
|
|
@ -1528,6 +1567,7 @@ EventSourceImpl::ClearFields()
|
||||||
nsresult
|
nsresult
|
||||||
EventSourceImpl::SetFieldAndClear()
|
EventSourceImpl::SetFieldAndClear()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
AssertIsOnTargetThread();
|
AssertIsOnTargetThread();
|
||||||
if (mLastFieldName.IsEmpty()) {
|
if (mLastFieldName.IsEmpty()) {
|
||||||
mLastFieldValue.Truncate();
|
mLastFieldValue.Truncate();
|
||||||
|
|
@ -1855,6 +1895,7 @@ private:
|
||||||
|
|
||||||
bool EventSourceImpl::RegisterWorkerHolder()
|
bool EventSourceImpl::RegisterWorkerHolder()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(!IsShutDown());
|
||||||
MOZ_ASSERT(mWorkerPrivate);
|
MOZ_ASSERT(mWorkerPrivate);
|
||||||
mWorkerPrivate->AssertIsOnWorkerThread();
|
mWorkerPrivate->AssertIsOnWorkerThread();
|
||||||
MOZ_ASSERT(!mWorkerHolder);
|
MOZ_ASSERT(!mWorkerHolder);
|
||||||
|
|
@ -1895,6 +1936,10 @@ EventSourceImpl::Dispatch(already_AddRefed<nsIRunnable> aEvent, uint32_t aFlags)
|
||||||
if (mIsMainThread) {
|
if (mIsMainThread) {
|
||||||
return NS_DispatchToMainThread(event_ref.forget());
|
return NS_DispatchToMainThread(event_ref.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsShutDown()) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
MOZ_ASSERT(mWorkerPrivate);
|
MOZ_ASSERT(mWorkerPrivate);
|
||||||
// If the target is a worker, we have to use a custom WorkerRunnableDispatcher
|
// If the target is a worker, we have to use a custom WorkerRunnableDispatcher
|
||||||
// runnable.
|
// runnable.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue