tor-browser

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

commit b388347c051b0140a2526dc95a1e066617126823
parent 8a1b1970b7bd4743b2a5c4f5f2333a4d31b7c4e9
Author: Adam Vandolder <avandolder@mozilla.com>
Date:   Tue, 21 Oct 2025 15:54:56 +0000

Bug 1995397 - Treat document.open'd documents as still initial about:blank for Navigation::HasEntriesAndEventsDisabled. r=jjaschke,smaug,dom-core

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

Diffstat:
Mdom/base/Document.cpp | 25++++++++++++++++++-------
Mdom/base/Document.h | 37++++++++++++++++++++++++-------------
Mdom/navigation/Navigation.cpp | 5+++--
3 files changed, 45 insertions(+), 22 deletions(-)

diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp @@ -1371,6 +1371,7 @@ Document::Document(const char* aContentType, #ifdef DEBUG mStyledLinksCleared(false), #endif + mInitialStatus(Document::InitialStatus::NeverInitial), mCachedStateObjectValid(false), mBlockAllMixedContent(false), mBlockAllMixedContentPreloads(false), @@ -1381,8 +1382,6 @@ Document::Document(const char* aContentType, mRenderingSuppressedForViewTransitions(false), mBidiEnabled(false), mMayNeedFontPrefsUpdate(true), - mIsInitialDocumentInWindow(false), - mIsEverInitialDocumentInWindow(false), mIgnoreDocGroupMismatches(false), mAddedToMemoryReportingAsDataDocument(false), mMayStartLayout(true), @@ -10479,7 +10478,9 @@ Document* Document::Open(const Optional<nsAString>& /* unused */, // URL may be changing away from about:blank here, we really want to unset // this flag no matter what, since only about:blank can be an initial // document. - SetIsInitialDocument(false); + if (IsInitialDocument()) { + SetInitialStatus(Document::InitialStatus::IsInitialButExplicitlyOpened); + } // And let our docloader know that it will need to track our load event. nsDocShell::Cast(shell)->SetDocumentOpenedButNotLoaded(); @@ -20383,10 +20384,10 @@ nsIPrincipal* Document::GetPrincipalForPrefBasedHacks() const { } void Document::SetIsInitialDocument(bool aIsInitialDocument) { - mIsInitialDocumentInWindow = aIsInitialDocument; - - if (aIsInitialDocument && !mIsEverInitialDocumentInWindow) { - mIsEverInitialDocumentInWindow = aIsInitialDocument; + if (aIsInitialDocument) { + mInitialStatus = InitialStatus::IsInitial; + } else if (mInitialStatus != InitialStatus::NeverInitial) { + mInitialStatus = InitialStatus::WasInitial; } // Asynchronously tell the parent process that we are, or are no longer, the @@ -20396,6 +20397,16 @@ void Document::SetIsInitialDocument(bool aIsInitialDocument) { } } +void Document::SetInitialStatus(InitialStatus aStatus) { + mInitialStatus = aStatus; + + // Asynchronously tell the parent process that we are, or are no longer, the + // initial document. This happens async. + if (auto* wgc = GetWindowGlobalChild()) { + wgc->SendSetIsInitialDocument(aStatus == InitialStatus::IsInitial); + } +} + // static void Document::AddToplevelLoadingDocument(Document* aDoc) { MOZ_ASSERT(aDoc && aDoc->IsTopLevelContentDocument()); diff --git a/dom/base/Document.h b/dom/base/Document.h @@ -1016,16 +1016,27 @@ class Document : public nsINode, */ void SetBidiEnabled() { mBidiEnabled = true; } + enum class InitialStatus : uint8_t { + IsInitial, + IsInitialButExplicitlyOpened, + WasInitial, + NeverInitial, + }; + /** * Ask this document whether it's the initial document in its window. */ - bool IsInitialDocument() const { return mIsInitialDocumentInWindow; } + bool IsInitialDocument() const { + return mInitialStatus == InitialStatus::IsInitial; + } /** * Ask this document whether it has ever been a initial document in its * window. */ - bool IsEverInitialDocument() const { return mIsEverInitialDocumentInWindow; } + bool IsEverInitialDocument() const { + return mInitialStatus != InitialStatus::NeverInitial; + } /** * Tell this document that it's the initial document in its window. See @@ -1033,6 +1044,10 @@ class Document : public nsINode, */ void SetIsInitialDocument(bool aIsInitialDocument); + InitialStatus GetInitialStatus() const { return mInitialStatus; } + + void SetInitialStatus(Document::InitialStatus aStatus); + void SetLoadedAsData(bool aLoadedAsData, bool aConsiderForMemoryReporting); TimeStamp GetLoadingOrRestoredFromBFCacheTimeStamp() const { @@ -4835,6 +4850,13 @@ class Document : public nsINode, // GetPermissionDelegateHandler RefPtr<PermissionDelegateHandler> mPermissionDelegateHandler; + // https://html.spec.whatwg.org/#is-initial-about:blank + // Track the initial about:blank status of this document. + // We track both whether the document was previously initial, + // and whether it is an initial about:blank which has had document.open called + // on it (see bug 1995397). + InitialStatus mInitialStatus; + bool mCachedStateObjectValid : 1; bool mBlockAllMixedContent : 1; bool mBlockAllMixedContentPreloads : 1; @@ -4854,17 +4876,6 @@ class Document : public nsINode, // True if we may need to recompute the language prefs for this document. bool mMayNeedFontPrefsUpdate : 1; - // True if this document is the initial document for a window. This should - // basically be true only for documents that exist in newly-opened windows or - // documents created to satisfy a GetDocument() on a window when there's no - // document in it. - bool mIsInitialDocumentInWindow : 1; - - // True if this document has ever been the initial document for a window. This - // is useful to determine if a document that was the initial document at one - // point, and became non-initial later. - bool mIsEverInitialDocumentInWindow : 1; - bool mIgnoreDocGroupMismatches : 1; // True if the document is considered for memory reporting as a diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp @@ -288,8 +288,9 @@ NavigationActivation* Navigation::GetActivation() const { return mActivation; } bool Navigation::HasEntriesAndEventsDisabled() const { Document* doc = GetAssociatedDocument(); return !doc || !doc->IsCurrentActiveDocument() || - (NS_IsAboutBlankAllowQueryAndFragment(doc->GetDocumentURI()) && - doc->IsInitialDocument()) || + doc->GetInitialStatus() == Document::InitialStatus::IsInitial || + doc->GetInitialStatus() == + Document::InitialStatus::IsInitialButExplicitlyOpened || doc->GetPrincipal()->GetIsNullPrincipal(); }