1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- #if !NETFRAMEWORK
- using System.Text;
- using Jint.Runtime;
- namespace Jint.Tests.Runtime;
- public class EngineLimitTests
- {
- #if RELEASE
- const int FunctionNestingCount = 990;
- #else
- const int FunctionNestingCount = 495;
- #endif
- [Fact]
- public void ShouldAllowReasonableCallStackDepth()
- {
- if (OperatingSystem.IsMacOS())
- {
- // stack limit differ quite a lot
- return;
- }
- var script = GenerateCallTree(FunctionNestingCount);
- var engine = new Engine();
- engine.Execute(script);
- Assert.Equal(123, engine.Evaluate("func1(123);").AsNumber());
- Assert.Equal(FunctionNestingCount, engine.Evaluate("x").AsNumber());
- }
- [Fact]
- public void ShouldNotStackoverflowWhenStackGuardEnable()
- {
- // Can be more than actual dotnet stacktrace count, It does not hit stackoverflow anymore.
- int functionNestingCount = FunctionNestingCount * 2;
- var script = GenerateCallTree(functionNestingCount);
- var engine = new Engine(option => option.Constraints.MaxExecutionStackCount = functionNestingCount);
- engine.Execute(script);
- Assert.Equal(123, engine.Evaluate("func1(123);").AsNumber());
- Assert.Equal(functionNestingCount, engine.Evaluate("x").AsNumber());
- }
- [Fact]
- public void ShouldThrowJavascriptExceptionWhenStackGuardExceed()
- {
- // Can be more than actual dotnet stacktrace count, It does not hit stackoverflow anymore.
- int functionNestingCount = FunctionNestingCount * 2;
- var script = GenerateCallTree(functionNestingCount);
- var engine = new Engine(option => option.Constraints.MaxExecutionStackCount = 500);
- try
- {
- engine.Execute(script);
- engine.Evaluate("func1(123);");
- }
- catch (JavaScriptException jsException)
- {
- Assert.Equal("Maximum call stack size exceeded", jsException.Message);
- }
- }
- private string GenerateCallTree(int functionNestingCount)
- {
- var sb = new StringBuilder();
- sb.AppendLine("var x = 1;");
- sb.AppendLine();
- for (var i = 1; i <= functionNestingCount; ++i)
- {
- sb.Append("function func").Append(i).Append("(func").Append(i).AppendLine("Param) {");
- sb.Append(" ");
- if (i != functionNestingCount)
- {
- // just to create a bit more nesting add some constructs
- sb.Append("return x++ >= 1 ? func").Append(i + 1).Append("(func").Append(i).AppendLine("Param): undefined;");
- }
- else
- {
- // use known CLR function to add breakpoint
- sb.Append("return Math.max(0, func").Append(i).AppendLine("Param);");
- }
- sb.AppendLine("}");
- sb.AppendLine();
- }
- return sb.ToString();
- }
- }
- #endif
|