From 911b9157637653c984ccbbd2c0b990499f5597a0 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 3 Feb 2025 21:41:35 -0500 Subject: [PATCH] LibJS: Handle call stack limit exceptions in NewPromiseReactionJob The promise job's fulfillment / rejection handlers may push an execution context onto the VM, which will throw an internal error if our ad-hoc call stack size limit has been reached. Thus, we cannot blindly VERIFY that the result of invoking these handlers is non-abrupt. This patch will propagate any internal error forward, and retains the condition that any other error type is not thrown. --- Libraries/LibJS/Runtime/PromiseJobs.cpp | 2 +- .../LibJS/Tests/runtime-error-call-stack-size.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Libraries/LibJS/Runtime/PromiseJobs.cpp b/Libraries/LibJS/Runtime/PromiseJobs.cpp index d3c418a8c43..f2d1317fc20 100644 --- a/Libraries/LibJS/Runtime/PromiseJobs.cpp +++ b/Libraries/LibJS/Runtime/PromiseJobs.cpp @@ -58,7 +58,7 @@ static ThrowCompletionOr run_reaction_job(VM& vm, PromiseReaction& reacti // f. If promiseCapability is undefined, then if (promise_capability == nullptr) { // i. Assert: handlerResult is not an abrupt completion. - VERIFY(!handler_result.is_abrupt()); + MUST_OR_THROW_INTERNAL_ERROR(handler_result); // ii. Return empty. dbgln_if(PROMISE_DEBUG, "run_reaction_job: Reaction has no PromiseCapability, returning empty value"); diff --git a/Libraries/LibJS/Tests/runtime-error-call-stack-size.js b/Libraries/LibJS/Tests/runtime-error-call-stack-size.js index ad147abc660..74e05887508 100644 --- a/Libraries/LibJS/Tests/runtime-error-call-stack-size.js +++ b/Libraries/LibJS/Tests/runtime-error-call-stack-size.js @@ -18,4 +18,16 @@ test("infinite recursion", () => { expect(() => { new Proxy({}, { get: (_, __, p) => p.foo }).foo; }).toThrowWithMessage(InternalError, "Call stack size limit exceeded"); + + expect(() => { + function outer() { + async function inner() { + await outer; + } + inner(); + outer(); + } + + outer(); + }).toThrowWithMessage(InternalError, "Call stack size limit exceeded"); });