From c6f070d29e4e1be6a7554a1edfb1cb2a54590243 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Sun, 14 Apr 2024 00:00:50 +0100 Subject: [PATCH] LibWeb/Fetch: Don't crash when a fetch request times out Previously, calling fetch with a signal object provided by `AbortSignal.timeout()` would cause a crash when the signal timed out. We now push a `TemporaryExecutionContext` to the stack when we invoke the signal's abort steps, as an execution context is required when calling native functions. --- .../LibWeb/Text/expected/fetch-timed-out-request.txt | 1 + Tests/LibWeb/Text/input/fetch-timed-out-request.html | 12 ++++++++++++ Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp | 3 +++ 3 files changed, 16 insertions(+) create mode 100644 Tests/LibWeb/Text/expected/fetch-timed-out-request.txt create mode 100644 Tests/LibWeb/Text/input/fetch-timed-out-request.html diff --git a/Tests/LibWeb/Text/expected/fetch-timed-out-request.txt b/Tests/LibWeb/Text/expected/fetch-timed-out-request.txt new file mode 100644 index 00000000000..aaecaf93c4a --- /dev/null +++ b/Tests/LibWeb/Text/expected/fetch-timed-out-request.txt @@ -0,0 +1 @@ +PASS (didn't crash) diff --git a/Tests/LibWeb/Text/input/fetch-timed-out-request.html b/Tests/LibWeb/Text/input/fetch-timed-out-request.html new file mode 100644 index 00000000000..f48693e6520 --- /dev/null +++ b/Tests/LibWeb/Text/input/fetch-timed-out-request.html @@ -0,0 +1,12 @@ + + + diff --git a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp index 553d11bf022..70eb6be1fc9 100644 --- a/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp +++ b/Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp @@ -142,6 +142,9 @@ JS::NonnullGCPtr fetch(JS::VM& vm, RequestInfo const& input, Reques // 3. Abort controller with requestObject’s signal’s abort reason. controller->abort(relevant_realm, request_object->signal()->reason()); + // AD-HOC: An execution context is required for Promise functions. + HTML::TemporaryExecutionContext execution_context { Bindings::host_defined_environment_settings_object(relevant_realm) }; + // 4. Abort the fetch() call with p, request, responseObject, and requestObject’s signal’s abort reason. abort_fetch(relevant_realm, *promise_capability, request, response_object, request_object->signal()->reason()); });