tor-browser

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

commit 8c29484ca9cd1072ce8b4bca539ea4c75d9f3b09
parent 8b732c4b790bfb729475ddba1dc36a4fd235a5ba
Author: Jan-Niklas Jaeschke <jjaschke@mozilla.com>
Date:   Tue, 28 Oct 2025 17:18:26 +0000

Bug 1970123, part 9 - Navigation API: Only run `AbortController()->Abort()` in certain conditions. r=dom-core,smaug

The spec runs currently this step unconditionally (step 2 in #abort-a-navigateevent).
However, according to tests and Chromium's implementation,
this step must only be run if
- #abort-a-navigateevent is not called from #process-navigate-event-handler-failure
- or the event's interception state is `Intercepted`.

Spec issue: https://github.com/whatwg/html/issues/11831

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

Diffstat:
Mdom/navigation/Navigation.cpp | 19++++++++++++++-----
Mdom/navigation/Navigation.h | 3++-
2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp @@ -1225,7 +1225,9 @@ struct NavigationWaitForAllScope final : public nsISupports, // 5. Abort event given reason. if (AutoJSAPI jsapi; !NS_WARN_IF(!jsapi.Init(mEvent->GetParentObject()))) { RefPtr navigation = mNavigation; - navigation->AbortNavigateEvent(jsapi.cx(), event, aRejectionReason); + navigation->AbortNavigateEvent( + jsapi.cx(), event, aRejectionReason, + /*aIsCalledFromNavigateFiringFailureSteps=*/true); } } // https://html.spec.whatwg.org/#commit-a-navigate-event @@ -1807,17 +1809,24 @@ void Navigation::AbortOngoingNavigation(JSContext* aCx, } // Step 7 - AbortNavigateEvent(aCx, event, error); + AbortNavigateEvent(aCx, event, error, + /*aIsCalledFromNavigateFiringFailureSteps=*/false); } // https://html.spec.whatwg.org/#abort-a-navigateevent -void Navigation::AbortNavigateEvent(JSContext* aCx, NavigateEvent* aEvent, - JS::Handle<JS::Value> aReason) { +void Navigation::AbortNavigateEvent( + JSContext* aCx, NavigateEvent* aEvent, JS::Handle<JS::Value> aReason, + bool aIsCalledFromNavigateFiringFailureSteps) { // 1. Let navigation be event's relevant global object's navigation API. // Omitted since this is called from a Navigation object. // 2. Signal abort on event's abort controller given reason. - aEvent->AbortController()->Abort(aCx, aReason); + if (!aIsCalledFromNavigateFiringFailureSteps || + aEvent->InterceptionState() == + NavigateEvent::InterceptionState::Intercepted) { + // https://github.com/whatwg/html/issues/11831 + aEvent->AbortController()->Abort(aCx, aReason); + } // 3. Let errorInfo be the result of extracting error information from reason. RootedDictionary<ErrorEventInit> init(aCx); diff --git a/dom/navigation/Navigation.h b/dom/navigation/Navigation.h @@ -186,7 +186,8 @@ class Navigation final : public DOMEventTargetHelper { MOZ_CAN_RUN_SCRIPT void AbortNavigateEvent(JSContext* aCx, NavigateEvent* aEvent, - JS::Handle<JS::Value> aReason); + JS::Handle<JS::Value> aReason, + bool aIsCalledFromNavigateFiringFailureSteps); MOZ_CAN_RUN_SCRIPT void InformAboutChildNavigableDestruction(JSContext* aCx);