commit 18e0b75d6d28c3026f224ff43b2504de9917f9da
parent dd4460727998a53e9fa7372afba2a93a9546cec3
Author: Andreas Farre <farre@mozilla.com>
Date: Fri, 28 Nov 2025 15:11:12 +0000
Bug 2003012 - Make sure to reject all method tracker promises. r=dom-core,jjaschke
Differential Revision: https://phabricator.services.mozilla.com/D274430
Diffstat:
3 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/dom/navigation/Navigation.cpp b/dom/navigation/Navigation.cpp
@@ -686,44 +686,55 @@ void Navigation::PerformNavigationTraversal(JSContext* aCx, const nsID& aKey,
// 12. Append the following session history traversal steps to traversable:
auto* childSHistory = traversable->GetChildSessionHistory();
- auto performNavigationTraversalSteps =
- [finished =
- RefPtr(apiMethodTracker->FinishedPromise())](nsresult aResult) {
- switch (aResult) {
- case NS_ERROR_DOM_INVALID_STATE_ERR:
- // 12.2 Let targetSHE be the session history entry in navigableSHEs
- // whose navigation API key is key. If no such entry exists,
- // then:
- finished->MaybeRejectWithInvalidStateError(
- "No such entry with key found");
- break;
- case NS_ERROR_DOM_ABORT_ERR:
- // 12.5 If result is "canceled-by-beforeunload", then queue a global
- // task on the navigation and traversal task source given
- // navigation's relevant global object to reject the finished
- // promise for apiMethodTracker with a new "AbortError" DOMException
- // created in navigation's relevant realm.
- finished->MaybeRejectWithAbortError("Navigation was canceled");
- break;
- case NS_ERROR_DOM_SECURITY_ERR:
- // 12.6 If result is "initiator-disallowed", then queue a global
- // task on the
- // navigation and traversal task source given navigation's
- // relevant global object to reject the finished promise for
- // apiMethodTracker with a new "SecurityError" DOMException
- // created in navigation's relevant realm.
- finished->MaybeRejectWithSecurityError(
- "Navigation was not allowed");
- break;
- case NS_OK:
- // 12.3 If targetSHE is navigable's active session history entry,
- // then abort these steps.
- break;
- default:
- MOZ_DIAGNOSTIC_ASSERT(false, "Unexpected result");
- break;
- }
- };
+ auto performNavigationTraversalSteps = [apiMethodTracker](nsresult aResult) {
+ // 12.3 If targetSHE is navigable's active session history entry,
+ // then abort these steps.
+ if (NS_SUCCEEDED(aResult)) {
+ return;
+ }
+
+ AutoJSAPI jsapi;
+ if (NS_WARN_IF(!jsapi.Init(
+ apiMethodTracker->mNavigationObject->GetParentObject()))) {
+ return;
+ }
+
+ ErrorResult rv;
+
+ switch (aResult) {
+ case NS_ERROR_DOM_INVALID_STATE_ERR:
+ // 12.2 Let targetSHE be the session history entry in navigableSHEs
+ // whose navigation API key is key. If no such entry exists,
+ // then:
+ rv.ThrowInvalidStateError("No such entry with key found");
+ break;
+ case NS_ERROR_DOM_ABORT_ERR:
+ // 12.5 If result is "canceled-by-beforeunload", then queue a global
+ // task on the navigation and traversal task source given
+ // navigation's relevant global object to reject the finished
+ // promise for apiMethodTracker with a new "AbortError"
+ // DOMException
+ // created in navigation's relevant realm.
+ rv.ThrowAbortError("Navigation was canceled");
+ break;
+ case NS_ERROR_DOM_SECURITY_ERR:
+ // 12.6 If result is "initiator-disallowed", then queue a global task on
+ // the navigation and traversal task source given navigation's
+ // relevant global object to reject the finished promise for
+ // apiMethodTracker with a new "SecurityError" DOMException
+ // created in navigation's relevant realm.
+ rv.ThrowSecurityError("Navigation was not allowed");
+ break;
+ default:
+ MOZ_DIAGNOSTIC_ASSERT(false, "Unexpected result");
+ rv.ThrowInvalidStateError("Unexpected result");
+ break;
+ }
+ JS::Rooted<JS::Value> rootedExceptionValue(jsapi.cx());
+ MOZ_ALWAYS_TRUE(
+ ToJSValue(jsapi.cx(), std::move(rv), &rootedExceptionValue));
+ apiMethodTracker->RejectFinishedPromise(rootedExceptionValue);
+ };
// 12.4 Let result be the result of applying the traverse history step given
// by targetSHE's step to traversable, given sourceSnapshotParams,
diff --git a/testing/web-platform/meta/navigation-api/navigate-event/navigate-destination-dynamic-index.html.ini b/testing/web-platform/meta/navigation-api/navigate-event/navigate-destination-dynamic-index.html.ini
@@ -1,4 +1,3 @@
[navigate-destination-dynamic-index.html]
- expected: TIMEOUT
[navigate event destination.index should be dynamic]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/testing/web-platform/meta/navigation-api/navigation-methods/forward-to-pruned-entry.html.ini b/testing/web-platform/meta/navigation-api/navigation-methods/forward-to-pruned-entry.html.ini
@@ -1,5 +1,3 @@
[forward-to-pruned-entry.html]
- expected:
- TIMEOUT
[If forward pruning clobbers the target of a traverse, abort]
- expected: TIMEOUT
+ expected: FAIL