tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7f84b85eb86a2b4d32e588447b450c720de11bbe
parent 078e258c422cbb641a0b7926a727913b47fb5c54
Author: Henri Sivonen <hsivonen@hsivonen.fi>
Date:   Fri, 12 Dec 2025 10:08:02 +0000

Bug 2004500 - Deal with parser termination during ~nsHtml5AutoFlush. r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D276142

Diffstat:
Mparser/html/nsHtml5TreeOpExecutor.cpp | 11++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/parser/html/nsHtml5TreeOpExecutor.cpp b/parser/html/nsHtml5TreeOpExecutor.cpp @@ -107,6 +107,12 @@ class MOZ_RAII nsHtml5AutoFlush final { "How do we have mParser but the doc update isn't open?"); } mExecutor->EndFlush(); + if (mExecutor->IsComplete()) { + // `mExecutor->EndDocUpdate()` caused a call to `nsIParser::Terminate`, + // so now we should clear the whole op queue in order to be able to + // assert in the destructor of `nsHtml5TreeOpExecutor`. + mOpsToRemove = mExecutor->OpQueueLength(); + } mExecutor->RemoveFromStartOfOpQueue(mOpsToRemove); // We might have missed a speculative load flush due to sync XHR mExecutor->FlushSpeculativeLoads(); @@ -117,7 +123,6 @@ class MOZ_RAII nsHtml5AutoFlush final { "wasn't less than the length of the queue."); mOpsToRemove = aOpsToRemove; } - void RequestRemovalOfAllOps() { mOpsToRemove = mExecutor->OpQueueLength(); } }; static LinkedList<nsHtml5TreeOpExecutor>* gBackgroundFlushList = nullptr; @@ -680,8 +685,6 @@ void nsHtml5TreeOpExecutor::RunFlushLoop() { if (MOZ_UNLIKELY(!mParser)) { // The parse ended during an update pause. - // Undo possible previous `SetNumberOfOpsToRemove` call. - autoFlush.RequestRemovalOfAllOps(); return; } if (streamEnded) { @@ -792,8 +795,6 @@ nsresult nsHtml5TreeOpExecutor::FlushDocumentWrite() { if (MOZ_UNLIKELY(!mParser)) { // The parse ended during an update pause. - // No need to call `autoFlush.RequestRemovalOfAllOps();`, because there is - // no `SetNumberOfOpsToRemove` call. return rv; } if (streamEnded) {