diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 519d8a6eacbd..aea09c9e2938 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -10581,6 +10581,10 @@ void Document::Destroy() { // leak-fixing if we fix nsDocumentViewer to do cycle-collection, but // tearing down all those frame trees right now is the right thing to do. mExternalResourceMap.Shutdown(); + + // Manually break cycles via promise's global object pointer. + mReadyForIdle = nullptr; + mOrientationPendingPromise = nullptr; } void Document::RemovedFromDocShell() { @@ -12615,6 +12619,11 @@ already_AddRefed Document::GetMozDocumentURIIfNotForErrorPages() { } Promise* Document::GetDocumentReadyForIdle(ErrorResult& aRv) { + if (mIsGoingAway) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return nullptr; + } + if (!mReadyForIdle) { nsIGlobalObject* global = GetScopeObject(); if (!global) { @@ -13815,8 +13824,17 @@ bool Document::FullscreenEnabled(CallerType aCallerType) { return !GetFullscreenError(this, aCallerType); } -void Document::SetOrientationPendingPromise(Promise* aPromise) { +void Document::ClearOrientationPendingPromise() { + mOrientationPendingPromise = nullptr; +} + +bool Document::SetOrientationPendingPromise(Promise* aPromise) { + if (mIsGoingAway) { + return false; + } + mOrientationPendingPromise = aPromise; + return true; } static void DispatchPointerLockChange(Document* aTarget) { diff --git a/dom/base/Document.h b/dom/base/Document.h index 73859f3d83ef..70df00374d80 100644 --- a/dom/base/Document.h +++ b/dom/base/Document.h @@ -2263,7 +2263,8 @@ class Document : public nsINode, OrientationType CurrentOrientationType() const { return mCurrentOrientationType; } - void SetOrientationPendingPromise(Promise* aPromise); + void ClearOrientationPendingPromise(); + bool SetOrientationPendingPromise(Promise* aPromise); Promise* GetOrientationPendingPromise() const { return mOrientationPendingPromise; } diff --git a/dom/base/ScreenOrientation.cpp b/dom/base/ScreenOrientation.cpp index 2b521645f1f6..9524b1ab2222 100644 --- a/dom/base/ScreenOrientation.cpp +++ b/dom/base/ScreenOrientation.cpp @@ -170,14 +170,14 @@ ScreenOrientation::LockOrientationTask::Run() { if (mDocument->Hidden()) { // Active orientation lock is not the document's orientation lock. mPromise->MaybeResolveWithUndefined(); - mDocument->SetOrientationPendingPromise(nullptr); + mDocument->ClearOrientationPendingPromise(); return NS_OK; } if (mOrientationLock == hal::eScreenOrientation_None) { mScreenOrientation->UnlockDeviceOrientation(); mPromise->MaybeResolveWithUndefined(); - mDocument->SetOrientationPendingPromise(nullptr); + mDocument->ClearOrientationPendingPromise(); return NS_OK; } @@ -190,7 +190,7 @@ ScreenOrientation::LockOrientationTask::Run() { if (NS_WARN_IF(!result)) { mPromise->MaybeReject(NS_ERROR_UNEXPECTED); - mDocument->SetOrientationPendingPromise(nullptr); + mDocument->ClearOrientationPendingPromise(); return NS_OK; } @@ -199,7 +199,7 @@ ScreenOrientation::LockOrientationTask::Run() { mDocument->CurrentOrientationAngle() == 0)) { // Orientation lock will not cause an orientation change. mPromise->MaybeResolveWithUndefined(); - mDocument->SetOrientationPendingPromise(nullptr); + mDocument->ClearOrientationPendingPromise(); } return NS_OK; @@ -256,7 +256,7 @@ static inline void AbortOrientationPromises(nsIDocShell* aDocShell) { Promise* promise = doc->GetOrientationPendingPromise(); if (promise) { promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR); - doc->SetOrientationPendingPromise(nullptr); + doc->ClearOrientationPendingPromise(); } } @@ -325,7 +325,10 @@ already_AddRefed ScreenOrientation::LockInternal( rootShell->SetOrientationLock(aOrientation); AbortOrientationPromises(rootShell); - doc->SetOrientationPendingPromise(p); + if (!doc->SetOrientationPendingPromise(p)) { + p->MaybeReject(NS_ERROR_DOM_SECURITY_ERR); + return p.forget(); + } nsCOMPtr lockOrientationTask = new LockOrientationTask( this, p, aOrientation, doc, perm == FULLSCREEN_LOCK_ALLOWED); @@ -553,7 +556,7 @@ ScreenOrientation::DispatchChangeEventAndResolvePromise() { Promise* pendingPromise = doc->GetOrientationPendingPromise(); if (pendingPromise) { pendingPromise->MaybeResolveWithUndefined(); - doc->SetOrientationPendingPromise(nullptr); + doc->ClearOrientationPendingPromise(); } } });