From 856709e667814402aeba251e5d7b882df92478f4 Mon Sep 17 00:00:00 2001 From: Noah Date: Sat, 30 Aug 2025 19:32:03 +0900 Subject: [PATCH] Fix resolve async promise timeout issue in Jint from 4.1.0 to 4.4.1 (#1250) --- .../Scripting/Internal/JsonMapper.cs | 5 ++++ .../Scripting/JintScriptEngine.cs | 2 ++ .../Scripting/JintScriptOptions.cs | 2 ++ ...Squidex.Domain.Apps.Core.Operations.csproj | 2 +- backend/src/Squidex/appsettings.json | 5 +++- .../Scripting/JintScriptEngineTests.cs | 27 +++++++++++++++++++ 6 files changed, 41 insertions(+), 2 deletions(-) diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs index b1555e0ee..4fd3efdf8 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs @@ -109,6 +109,11 @@ public static class JsonMapper return number; } + if (value.IsPromise()) + { + return Map(value.UnwrapIfPromise()); + } + if (value is JsArray a) { var result = new JsonArray((int)a.Length); diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs index fe1b6a385..7feb363c7 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs @@ -29,6 +29,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions ExecuteAsync(ScriptVars vars, string script, ScriptOptions options = default, CancellationToken ct = default) @@ -150,6 +151,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index 3bd3afc32..cfbed3ac0 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -126,7 +126,10 @@ "timeoutExecution": "00:00:04", // The timeout for the synchronous part of the script. - "timeoutScript": "00:00:00.200" + "timeoutScript": "00:00:00.200", + + // The timeout for the asynchronous promise of the script. + "timeoutPromise": "00:00:04" }, "languages": { diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs index f28efc1b9..427ed1175 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs @@ -59,6 +59,7 @@ public class JintScriptEngineTests : IClassFixture { TimeoutScript = TimeSpan.FromSeconds(2), TimeoutExecution = TimeSpan.FromSeconds(10), + TimeoutPromise = TimeSpan.FromSeconds(8), }), extensions); } @@ -723,4 +724,30 @@ public class JintScriptEngineTests : IClassFixture Assert.Equal(42.0, result.Value); } + + [Fact] + public async Task Should_run_with_blocking_timeout_promises() + { + const string script = @" + function promiseMethod() { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + }, 1000) + }); + } + + // Jint 4.1.0 blocking (if you remove 'async', the timeout will not occur.) + async function asyncMethod() { + return promiseMethod(); + } + + (async () => { + await asyncMethod(); + complete() + })() + "; + + await Assert.ThrowsAsync(() => sut.ExecuteAsync(new ScriptVars(), script)); + } }