Forráskód Böngészése

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.
Tim Ledbetter 1 éve
szülő
commit
c6f070d29e

+ 1 - 0
Tests/LibWeb/Text/expected/fetch-timed-out-request.txt

@@ -0,0 +1 @@
+PASS (didn't crash)

+ 12 - 0
Tests/LibWeb/Text/input/fetch-timed-out-request.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script src="include.js"></script>
+<script>
+    asyncTest(async done => {
+        try {
+            await fetch("about:srcdoc", { signal: AbortSignal.timeout(0) });
+        } finally {
+            println("PASS (didn't crash)");
+            done();
+        }
+    });
+</script>

+ 3 - 0
Userland/Libraries/LibWeb/Fetch/FetchMethod.cpp

@@ -142,6 +142,9 @@ JS::NonnullGCPtr<JS::Promise> 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());
     });