Browse Source

Array.sort should obey execution constraints (#1026)

Marko Lahma 3 years ago
parent
commit
d84af69871
2 changed files with 26 additions and 5 deletions
  1. 16 0
      Jint.Tests/Runtime/ArrayTests.cs
  2. 10 5
      Jint/Native/Array/ArrayPrototype.cs

+ 16 - 0
Jint.Tests/Runtime/ArrayTests.cs

@@ -115,6 +115,22 @@ namespace Jint.Tests.Runtime
             _engine.Execute(code);
         }
 
+#if !NETCOREAPP
+        // this test case only triggers on older full framework where the is no checks for infinite comparisons
+        [Fact]
+        public void ArraySortShouldObeyExecutionConstraints()
+        {
+            const string script = @"
+                let cases = [5,5];
+                let latestCase = cases.sort((c1, c2) => c1 > c2 ? -1: 1);";
+
+            var engine = new Engine(options => options
+                .TimeoutInterval(TimeSpan.FromSeconds(1))
+            );
+            Assert.Throws<TimeoutException>(() => engine.Evaluate(script));
+        }
+#endif
+
         [Fact]
         public void ExtendingArrayAndInstanceOf()
         {

+ 10 - 5
Jint/Native/Array/ArrayPrototype.cs

@@ -959,7 +959,7 @@ namespace Jint.Native.Array
             // don't eat inner exceptions
             try
             {
-                var array = obj.OrderBy(x => x, ArrayComparer.WithFunction(compareFn)).ToArray();
+                var array = obj.OrderBy(x => x, ArrayComparer.WithFunction(_engine, compareFn)).ToArray();
 
                 for (uint i = 0; i < (uint) array.Length; ++i)
                 {
@@ -1399,22 +1399,25 @@ namespace Jint.Native.Array
             /// <summary>
             /// Default instance without any compare function.
             /// </summary>
-            public static ArrayComparer Default = new ArrayComparer(null);
-            public static ArrayComparer WithFunction(ICallable compare)
+            public static readonly ArrayComparer Default = new(null, null);
+
+            public static ArrayComparer WithFunction(Engine engine, ICallable compare)
             {
                 if (compare == null)
                 {
                     return Default;
                 }
 
-                return new ArrayComparer(compare);
+                return new ArrayComparer(engine, compare);
             }
 
+            private readonly Engine _engine;
             private readonly ICallable _compare;
             private readonly JsValue[] _comparableArray = new JsValue[2];
 
-            private ArrayComparer(ICallable compare)
+            private ArrayComparer(Engine engine, ICallable compare)
             {
+                _engine = engine;
                 _compare = compare;
             }
 
@@ -1459,6 +1462,8 @@ namespace Jint.Native.Array
 
                 if (_compare != null)
                 {
+                    _engine.RunBeforeExecuteStatementChecks(null);
+
                     _comparableArray[0] = x;
                     _comparableArray[1] = y;