Skip to content

Commit 6f9adcb

Browse files
committed
In configuration settings of the Jint JS engine was added one new property - MemoryLimit (default 0)
1 parent 4870ac8 commit 6f9adcb

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

src/JavaScriptEngineSwitcher.Jint/JavaScriptEngineSwitcher.Jint.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
77
<OutputType>Library</OutputType>
88
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
9-
<NoWarn>$(NoWarn);CS1591;NU5125</NoWarn>
9+
<NoWarn>$(NoWarn);CS1591;NU5104;NU5125</NoWarn>
1010
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1111
<DisableDefaultResxToCsConversionTarget>true</DisableDefaultResxToCsConversionTarget>
1212
<Description>JavaScriptEngineSwitcher.Jint contains adapter `JintJsEngine` (wrapper for the Jint JavaScript Engine (http://github.com/sebastienros/jint) version 3.0.0 Beta 1598).</Description>
1313
<PackageIconUrl>https://raw.githubusercontent.com/Taritsyn/JavaScriptEngineSwitcher/master/Icons/JavaScriptEngineSwitcher_Jint_Logo128x128.png</PackageIconUrl>
1414
<PackageTags>JavaScriptEngineSwitcher;JavaScript;ECMAScript;Jint</PackageTags>
1515
<PackageReleaseNotes>1. Jint was updated to version 3.0.0 Beta 1598;
16-
2. No longer supports a .NET Framework 4.0 Client and .NET Standard 1.3.</PackageReleaseNotes>
16+
2. No longer supports a .NET Framework 4.0 Client and .NET Standard 1.3;
17+
3. In configuration settings of the Jint JS engine was added one new property - `MemoryLimit` (default `0`).</PackageReleaseNotes>
1718
</PropertyGroup>
1819

1920
<Import Project="../../build/common.props" />

src/JavaScriptEngineSwitcher.Jint/JintJsEngine.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using IOriginalCallable = Jint.Native.ICallable;
77
using OriginalEngine = Jint.Engine;
88
using OriginalJavaScriptException = Jint.Runtime.JavaScriptException;
9+
using OriginalMemoryLimitExceededException = Jint.Runtime.MemoryLimitExceededException;
910
using OriginalObjectInstance = Jint.Native.Object.ObjectInstance;
1011
using OriginalParser = Esprima.JavaScriptParser;
1112
using OriginalParserException = Esprima.ParserException;
@@ -92,6 +93,7 @@ public JintJsEngine(JintSettings settings)
9293
_jsEngine = new OriginalEngine(c => c
9394
.AllowDebuggerStatement(jintSettings.AllowDebuggerStatement)
9495
.DebugMode(jintSettings.EnableDebugging)
96+
.LimitMemory(jintSettings.MemoryLimit)
9597
.LimitRecursion(jintSettings.MaxRecursionDepth)
9698
.LocalTimeZone(jintSettings.LocalTimeZone ?? TimeZoneInfo.Local)
9799
.MaxStatements(jintSettings.MaxStatements)
@@ -244,6 +246,22 @@ private static WrapperException WrapJavaScriptException(
244246
return wrapperException;
245247
}
246248

249+
private static WrapperRuntimeException WrapMemoryLimitExceededException(
250+
OriginalMemoryLimitExceededException originalMemoryException)
251+
{
252+
string description = originalMemoryException.Message;
253+
string type = JsErrorType.Common;
254+
string message = JsErrorHelpers.GenerateScriptErrorMessage(type, description, string.Empty);
255+
256+
var wrapperRuntimeException = new WrapperRuntimeException(message, EngineName, EngineVersion,
257+
originalMemoryException)
258+
{
259+
Description = description
260+
};
261+
262+
return wrapperRuntimeException;
263+
}
264+
247265
private static WrapperRuntimeException WrapRecursionDepthOverflowException(
248266
OriginalRecursionDepthOverflowException originalRecursionException)
249267
{
@@ -376,6 +394,10 @@ protected override object InnerEvaluate(string expression, string documentName)
376394
{
377395
throw WrapJavaScriptException(e);
378396
}
397+
catch (OriginalMemoryLimitExceededException e)
398+
{
399+
throw WrapMemoryLimitExceededException(e);
400+
}
379401
catch (OriginalRecursionDepthOverflowException e)
380402
{
381403
throw WrapRecursionDepthOverflowException(e);
@@ -431,6 +453,10 @@ protected override void InnerExecute(string code, string documentName)
431453
{
432454
throw WrapJavaScriptException(e);
433455
}
456+
catch (OriginalMemoryLimitExceededException e)
457+
{
458+
throw WrapMemoryLimitExceededException(e);
459+
}
434460
catch (OriginalRecursionDepthOverflowException e)
435461
{
436462
throw WrapRecursionDepthOverflowException(e);
@@ -471,6 +497,10 @@ protected override void InnerExecute(IPrecompiledScript precompiledScript)
471497
{
472498
throw WrapJavaScriptException(e);
473499
}
500+
catch (OriginalMemoryLimitExceededException e)
501+
{
502+
throw WrapMemoryLimitExceededException(e);
503+
}
474504
catch (OriginalRecursionDepthOverflowException e)
475505
{
476506
throw WrapRecursionDepthOverflowException(e);
@@ -531,6 +561,10 @@ protected override object InnerCallFunction(string functionName, params object[]
531561
{
532562
throw WrapJavaScriptException(e);
533563
}
564+
catch (OriginalMemoryLimitExceededException e)
565+
{
566+
throw WrapMemoryLimitExceededException(e);
567+
}
534568
catch (OriginalRecursionDepthOverflowException e)
535569
{
536570
throw WrapRecursionDepthOverflowException(e);

src/JavaScriptEngineSwitcher.Jint/JintSettings.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ public int MaxStatements
5555
set;
5656
}
5757

58+
/// <summary>
59+
/// Gets or sets a current memory limit for a engine in bytes
60+
/// </summary>
61+
public long MemoryLimit
62+
{
63+
get;
64+
set;
65+
}
66+
5867
/// <summary>
5968
/// Gets or sets a flag for whether to allow run the script in strict mode
6069
/// </summary>
@@ -94,6 +103,7 @@ public JintSettings()
94103
LocalTimeZone = TimeZoneInfo.Local;
95104
MaxRecursionDepth = -1;
96105
MaxStatements = 0;
106+
MemoryLimit = 0;
97107
StrictMode = false;
98108
TimeoutInterval = TimeSpan.Zero;
99109
}

src/JavaScriptEngineSwitcher.Jint/readme.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
RELEASE NOTES
1919
=============
2020
1. Jint was updated to version 3.0.0 Beta 1598;
21-
2. No longer supports a .NET Framework 4.0 Client and .NET Standard 1.3.
21+
2. No longer supports a .NET Framework 4.0 Client and .NET Standard 1.3;
22+
3. In configuration settings of the Jint JS engine was added one new property -
23+
`MemoryLimit` (default `0`).
2224

2325
=============
2426
DOCUMENTATION

test/JavaScriptEngineSwitcher.Tests/Jint/CommonTests.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,42 @@ public void MappingRuntimeErrorDuringExecutionOfCodeIsCorrect()
177177
Assert.Empty(exception.CallStack);
178178
}
179179

180+
[Fact]
181+
public void MappingRuntimeErrorDuringOutOfMemoryIsCorrect()
182+
{
183+
// Arrange
184+
const string input = @"var arr = [];
185+
186+
for (var i = 0; i < 10000; i++) {
187+
arr.push('Current date: ' + new Date());
188+
}";
189+
190+
JsRuntimeException exception = null;
191+
192+
// Act
193+
using (IJsEngine jsEngine = new JintJsEngine(
194+
new JintSettings
195+
{
196+
MemoryLimit = 2 * 1024 * 1024
197+
}
198+
))
199+
{
200+
try
201+
{
202+
jsEngine.Execute(input);
203+
}
204+
catch (JsRuntimeException e)
205+
{
206+
exception = e;
207+
}
208+
}
209+
210+
// Assert
211+
Assert.NotNull(exception);
212+
Assert.Equal("Runtime error", exception.Category);
213+
Assert.Matches(@"^Script has allocated \d+ but is limited to 2097152$", exception.Description);
214+
}
215+
180216
[Fact]
181217
public void MappingRuntimeErrorDuringRecursionDepthOverflowIsCorrect()
182218
{

0 commit comments

Comments
 (0)