Skip to content

Commit ed1dc6b

Browse files
committed
Fix resolve async promise timeout issue in Jint from 4.1.0 to 4.4.1
1 parent 1453767 commit ed1dc6b

6 files changed

Lines changed: 41 additions & 2 deletions

File tree

backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/Internal/JsonMapper.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public static JsonValue Map(JsValue? value)
109109
return number;
110110
}
111111

112+
if (value.IsPromise())
113+
{
114+
return Map(value.UnwrapIfPromise());
115+
}
116+
112117
if (value is JsArray a)
113118
{
114119
var result = new JsonArray((int)a.Length);

backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptEngine.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public sealed class JintScriptEngine(IMemoryCache cache, IOptions<JintScriptOpti
2929
private readonly CacheParser parser = new CacheParser(cache);
3030
private readonly TimeSpan timeoutScript = options.Value.TimeoutScript;
3131
private readonly TimeSpan timeoutExecution = options.Value.TimeoutExecution;
32+
private readonly TimeSpan timeoutPromise = options.Value.TimeoutPromise;
3233

3334
public async Task<JsonValue> ExecuteAsync(ScriptVars vars, string script, ScriptOptions options = default,
3435
CancellationToken ct = default)
@@ -150,6 +151,7 @@ private ScriptExecutionContext<T> CreateEngine<T>(ScriptOptions options, Cancell
150151

151152
if (!Debugger.IsAttached)
152153
{
154+
engineOptions.Constraints.PromiseTimeout = timeoutPromise;
153155
engineOptions.TimeoutInterval(timeoutScript);
154156
engineOptions.CancellationToken(ct);
155157
}

backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/JintScriptOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ public sealed class JintScriptOptions
1212
public TimeSpan TimeoutScript { get; set; } = TimeSpan.FromMilliseconds(200);
1313

1414
public TimeSpan TimeoutExecution { get; set; } = TimeSpan.FromMilliseconds(4000);
15+
16+
public TimeSpan TimeoutPromise { get; set; } = TimeSpan.FromMilliseconds(4000);
1517
}

backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
<ItemGroup>
2121
<PackageReference Include="Fluid.Core" Version="2.12.0" />
2222
<PackageReference Include="GeoJSON.Net" Version="1.4.1" />
23-
<PackageReference Include="Jint" Version="4.1.0" />
23+
<PackageReference Include="Jint" Version="4.4.1" />
2424
<PackageReference Include="Meziantou.Analyzer" Version="2.0.179">
2525
<PrivateAssets>all</PrivateAssets>
2626
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

backend/src/Squidex/appsettings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@
126126
"timeoutExecution": "00:00:04",
127127

128128
// The timeout for the synchronous part of the script.
129-
"timeoutScript": "00:00:00.200"
129+
"timeoutScript": "00:00:00.200",
130+
131+
// The timeout for the asynchronous promise of the script.
132+
"timeoutPromise": "00:00:04"
130133
},
131134

132135
"languages": {

backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/JintScriptEngineTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public JintScriptEngineTests()
5959
{
6060
TimeoutScript = TimeSpan.FromSeconds(2),
6161
TimeoutExecution = TimeSpan.FromSeconds(10),
62+
TimeoutPromise = TimeSpan.FromSeconds(8),
6263
}),
6364
extensions);
6465
}
@@ -723,4 +724,30 @@ function asyncMethod() {
723724

724725
Assert.Equal(42.0, result.Value);
725726
}
727+
728+
[Fact]
729+
public async Task Should_run_with_blocking_timeout_promises()
730+
{
731+
const string script = @"
732+
function promiseMethod() {
733+
return new Promise((resolve, reject) => {
734+
setTimeout(() => {
735+
resolve();
736+
}, 1000)
737+
});
738+
}
739+
740+
// Jint 4.1.0 blocking (if you remove 'async', the timeout will not occur.)
741+
async function asyncMethod() {
742+
return promiseMethod();
743+
}
744+
745+
(async () => {
746+
await asyncMethod();
747+
complete()
748+
})()
749+
";
750+
751+
await Assert.ThrowsAsync<ValidationException>(() => sut.ExecuteAsync(new ScriptVars(), script));
752+
}
726753
}

0 commit comments

Comments
 (0)