commit 16d14c6570b6456b21e8116ccdc2fa7c818e9519
parent 6764982edefb6be1c65e5a28d2be6ff6c1a45123
Author: Andreas Farre <farre@mozilla.com>
Date: Fri, 24 Oct 2025 13:32:22 +0000
Bug 1996220 - Disable Navigation API when document is loaded using `multipart/x-mixed-replace`. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D269943
Diffstat:
2 files changed, 13 insertions(+), 42 deletions(-)
diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp
@@ -5628,40 +5628,10 @@ static bool IsFollowupPartOfMultipart(nsIRequest* aRequest) {
!firstPart;
}
-static void GetPreviousContiguousEntries(
- nsIDocumentViewer* aDocumentViewer,
- nsTArray<SessionHistoryInfo>& aContiguousEntries) {
- if (!aDocumentViewer || !aDocumentViewer->GetDocument() ||
- !aDocumentViewer->GetDocument()->GetWindow() ||
- !aDocumentViewer->GetDocument()->GetWindow()->GetCurrentInnerWindow() ||
- !aDocumentViewer->GetDocument()
- ->GetWindow()
- ->GetCurrentInnerWindow()
- ->Navigation()) {
- return;
- }
-
- nsTArray<RefPtr<NavigationHistoryEntry>> entries;
- RefPtr navigation = aDocumentViewer->GetDocument()
- ->GetWindow()
- ->GetCurrentInnerWindow()
- ->Navigation();
- navigation->Entries(entries);
- for (const auto& entry : entries) {
- aContiguousEntries.AppendElement(*entry->SessionHistoryInfo());
- }
-}
-
nsresult nsDocShell::Embed(nsIDocumentViewer* aDocumentViewer,
WindowGlobalChild* aWindowActor,
bool aIsTransientAboutBlank, nsIRequest* aRequest,
nsIURI* aPreviousURI) {
- nsTArray<SessionHistoryInfo> oldContiguousEntries;
- if (mozilla::SessionHistoryInParent() &&
- IsFollowupPartOfMultipart(aRequest)) {
- GetPreviousContiguousEntries(mDocumentViewer, oldContiguousEntries);
- }
-
// Save the LayoutHistoryState of the previous document, before
// setting up new document
PersistLayoutHistoryState();
@@ -5713,13 +5683,6 @@ nsresult nsDocShell::Embed(nsIDocumentViewer* aDocumentViewer,
MOZ_LOG(gSHLog, LogLevel::Debug, ("document %p Embed", this));
MoveLoadingToActiveEntry(expired, cacheKey, aPreviousURI);
- } else if (mozilla::SessionHistoryInParent() &&
- IsFollowupPartOfMultipart(aRequest)) {
- if (RefPtr navigation =
- GetWindow()->GetCurrentInnerWindow()->Navigation()) {
- navigation->InitializeHistoryEntries(oldContiguousEntries,
- mActiveEntry.get());
- }
}
bool updateHistory = true;
diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp
@@ -34,6 +34,7 @@
#include "nsCycleCollectionParticipant.h"
#include "nsDocShell.h"
#include "nsGlobalWindowInner.h"
+#include "nsIMultiPartChannel.h"
#include "nsIPrincipal.h"
#include "nsISHistory.h"
#include "nsIScriptChannel.h"
@@ -282,6 +283,12 @@ NavigationTransition* Navigation::GetTransition() const { return mTransition; }
NavigationActivation* Navigation::GetActivation() const { return mActivation; }
+template <typename I>
+bool SupportsInterface(nsISupports* aSupports) {
+ nsCOMPtr<I> ptr = do_QueryInterface(aSupports);
+ return ptr;
+}
+
// https://html.spec.whatwg.org/#has-entries-and-events-disabled
bool Navigation::HasEntriesAndEventsDisabled() const {
Document* doc = GetAssociatedDocument();
@@ -289,11 +296,12 @@ bool Navigation::HasEntriesAndEventsDisabled() const {
doc->GetInitialStatus() == Document::InitialStatus::IsInitial ||
doc->GetInitialStatus() ==
Document::InitialStatus::IsInitialButExplicitlyOpened ||
- doc->GetPrincipal()->GetIsNullPrincipal() || [&doc]() {
- nsCOMPtr<nsIScriptChannel> channel =
- do_QueryInterface(doc->GetChannel());
- return channel;
- }();
+ doc->GetPrincipal()->GetIsNullPrincipal() ||
+ // We explicitly disallow documents loaded through multipart and script
+ // channels from having events or entries. See bug 1996218 and bug
+ // 1996221
+ SupportsInterface<nsIMultiPartChannel>(doc->GetChannel()) ||
+ SupportsInterface<nsIScriptChannel>(doc->GetChannel());
}
// https://html.spec.whatwg.org/#initialize-the-navigation-api-entries-for-a-new-document