diff options
Diffstat (limited to 'dom')
-rw-r--r-- | dom/base/ResizeObserverController.cpp | 22 | ||||
-rw-r--r-- | dom/base/ResizeObserverController.h | 5 | ||||
-rw-r--r-- | dom/base/nsDocument.cpp | 6 | ||||
-rw-r--r-- | dom/base/nsImageLoadingContent.cpp | 6 | ||||
-rw-r--r-- | dom/fetch/FetchDriver.cpp | 24 | ||||
-rw-r--r-- | dom/smil/nsSMILCSSProperty.cpp | 1 |
6 files changed, 50 insertions, 14 deletions
diff --git a/dom/base/ResizeObserverController.cpp b/dom/base/ResizeObserverController.cpp index d4166155e..edf73fc73 100644 --- a/dom/base/ResizeObserverController.cpp +++ b/dom/base/ResizeObserverController.cpp @@ -16,7 +16,7 @@ namespace dom { void ResizeObserverNotificationHelper::WillRefresh(TimeStamp aTime) { - MOZ_ASSERT(mOwner, "Why is mOwner already dead when this RefreshObserver is still registered?"); + MOZ_DIAGNOSTIC_ASSERT(mOwner, "RefreshObserver should have been de-registered on time, but isn't."); if (mOwner) { mOwner->Notify(); } @@ -70,10 +70,8 @@ ResizeObserverNotificationHelper::Unregister() } nsRefreshDriver* refreshDriver = GetRefreshDriver(); - if (!refreshDriver) { - // We can't access RefreshDriver now. Just abort the Unregister(). - return; - } + MOZ_RELEASE_ASSERT(refreshDriver, + "We should not leave a dangling reference to the observer around"); refreshDriver->RemoveRefreshObserver(this, Flush_Display); mRegistered = false; @@ -82,9 +80,8 @@ ResizeObserverNotificationHelper::Unregister() void ResizeObserverNotificationHelper::Disconnect() { - Unregister(); - // Our owner is dying. Clear our pointer to it, in case we outlive it. - mOwner = nullptr; + MOZ_RELEASE_ASSERT(!mRegistered, "How can we die when registered?"); + MOZ_RELEASE_ASSERT(!mOwner, "Forgot to clear weak pointer?"); } ResizeObserverNotificationHelper::~ResizeObserverNotificationHelper() @@ -112,6 +109,10 @@ ResizeObserverController::AddResizeObserver(ResizeObserver* aObserver) mResizeObservers.AppendElement(aObserver); } +void ResizeObserverController::DetachFromDocument() { + mResizeObserverNotificationHelper->Unregister(); +} + void ResizeObserverController::Notify() { @@ -241,7 +242,10 @@ ResizeObserverController::GetShell() const ResizeObserverController::~ResizeObserverController() { - mResizeObserverNotificationHelper->Disconnect(); + MOZ_RELEASE_ASSERT( + !mResizeObserverNotificationHelper->IsRegistered(), + "Nothing else should keep a reference to our notification helper when we go away"); + mResizeObserverNotificationHelper->DetachFromOwner(); } } // namespace dom diff --git a/dom/base/ResizeObserverController.h b/dom/base/ResizeObserverController.h index a77511587..2ddfc958c 100644 --- a/dom/base/ResizeObserverController.h +++ b/dom/base/ResizeObserverController.h @@ -42,6 +42,10 @@ public: void Disconnect(); + bool IsRegistered() const { return mRegistered; }
+
+ void DetachFromOwner() { mOwner = nullptr; }
+ protected: virtual ~ResizeObserverNotificationHelper(); @@ -69,6 +73,7 @@ public: void Traverse(nsCycleCollectionTraversalCallback& aCb); void Unlink(); + void DetachFromDocument(); void AddResizeObserver(ResizeObserver* aObserver); /* diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 0b07ef4ec..144f048eb 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -3689,6 +3689,12 @@ nsDocument::DeleteShell() // objects for @font-face rules that came from the style set. RebuildUserFontSet(); + if (mResizeObserverController) { + // If the shell is going away, we need to remove any links to this document + // from the observer. + mResizeObserverController->DetachFromDocument(); + } + nsIPresShell* oldShell = mPresShell; mPresShell = nullptr; UpdateFrameRequestCallbackSchedulingState(oldShell); diff --git a/dom/base/nsImageLoadingContent.cpp b/dom/base/nsImageLoadingContent.cpp index 4aad55941..07bdb6967 100644 --- a/dom/base/nsImageLoadingContent.cpp +++ b/dom/base/nsImageLoadingContent.cpp @@ -933,8 +933,12 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI, MOZ_ASSERT(!req, "Shouldn't have non-null request here"); // If we don't have a current URI, we might as well store this URI so people // know what we tried (and failed) to load. - if (!mCurrentRequest) + if (!mCurrentRequest) { mCurrentURI = aNewURI; + if (mImageBlockingStatus == nsIContentPolicy::ACCEPT) { + mImageBlockingStatus = nsIContentPolicy::REJECT_REQUEST; + } + } FireEvent(NS_LITERAL_STRING("error")); FireEvent(NS_LITERAL_STRING("loadend")); diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index fd1e99a2b..14c000121 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -709,10 +709,12 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, // about races. if (mObserver) { + // Need to keep mObserver alive. + RefPtr<FetchDriverObserver> observer = mObserver; if (NS_IsMainThread()) { - mObserver->OnDataAvailable(); + observer->OnDataAvailable(); } else { - RefPtr<Runnable> runnable = new DataAvailableRunnable(mObserver); + RefPtr<Runnable> runnable = new DataAvailableRunnable(observer); nsresult rv = NS_DispatchToMainThread(runnable); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; @@ -720,12 +722,15 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, } } - uint32_t aRead; + // Explicitly initialized to 0 because in some cases nsStringInputStream may + // not write to aRead. + uint32_t aRead = 0; MOZ_ASSERT(mResponse); MOZ_ASSERT(mPipeOutputStream); // From "Main Fetch" step 17: SRI-part2. - if (mResponse->Type() != ResponseType::Error && + if (mResponse && + mResponse->Type() != ResponseType::Error && !mRequest->GetIntegrity().IsEmpty()) { MOZ_ASSERT(mSRIDataVerifier); @@ -767,6 +772,17 @@ FetchDriver::OnDataAvailable(nsIRequest* aRequest, nsresult rv = aInputStream->ReadSegments(NS_CopySegmentToStream, mPipeOutputStream, aCount, &aRead); + + // If no data was read, it's possible the output stream is closed but the + // ReadSegments call followed its contract of returning NS_OK despite write + // errors. Unfortunately, nsIOutputStream has an ill-conceived contract when + // taken together with ReadSegments' contract, because the pipe will just + // NS_OK if we try and invoke its Write* functions ourselves with a 0 count. + // So we must just assume the pipe is broken. + if (aRead == 0 && aCount != 0) { + return NS_BASE_STREAM_CLOSED; + } + return rv; } diff --git a/dom/smil/nsSMILCSSProperty.cpp b/dom/smil/nsSMILCSSProperty.cpp index 14e428c05..070f3489e 100644 --- a/dom/smil/nsSMILCSSProperty.cpp +++ b/dom/smil/nsSMILCSSProperty.cpp @@ -195,6 +195,7 @@ nsSMILCSSProperty::IsPropertyAnimatable(nsCSSPropertyID aPropID) // writing-mode switch (aPropID) { + case eCSSProperty_caret_color: case eCSSProperty_clip: case eCSSProperty_clip_rule: case eCSSProperty_clip_path: |