Browse Source

Regex can get into infinite loop (#626)

Marko Lahma 6 years ago
parent
commit
63c734750b
2 changed files with 14 additions and 3 deletions
  1. 11 0
      Jint.Tests/Runtime/RegExpTests.cs
  2. 3 3
      Jint/Native/String/StringPrototype.cs

+ 11 - 0
Jint.Tests/Runtime/RegExpTests.cs

@@ -1,5 +1,6 @@
 using System;
 using System;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
+using Jint.Native.Array;
 using Xunit;
 using Xunit;
 
 
 namespace Jint.Tests.Runtime
 namespace Jint.Tests.Runtime
@@ -30,5 +31,15 @@ namespace Jint.Tests.Runtime
                engine.Execute($"'{testedValue}'.match(new RegExp(/{testRegex}/))");
                engine.Execute($"'{testedValue}'.match(new RegExp(/{testRegex}/))");
             });
             });
         }
         }
+
+        [Fact]
+        public void PreventsInfiniteLoop()
+        {
+            var engine = new Engine();
+            var result = (ArrayInstance) engine.Execute("'x'.match(/|/g);").GetCompletionValue();
+            Assert.Equal((uint) 2, result.Length);
+            Assert.Equal("", result[0]);
+            Assert.Equal("", result[1]);
+        }
     }
     }
 }
 }

+ 3 - 3
Jint/Native/String/StringPrototype.cs

@@ -680,7 +680,7 @@ namespace Jint.Native.String
             {
             {
                 rx.Put("lastIndex", 0, false);
                 rx.Put("lastIndex", 0, false);
                 var a = (ArrayInstance) Engine.Array.Construct(Arguments.Empty);
                 var a = (ArrayInstance) Engine.Array.Construct(Arguments.Empty);
-                double previousLastIndex = 0;
+                int previousLastIndex = 0;
                 uint n = 0;
                 uint n = 0;
                 var lastMatch = true;
                 var lastMatch = true;
                 while (lastMatch)
                 while (lastMatch)
@@ -692,11 +692,11 @@ namespace Jint.Native.String
                     }
                     }
                     else
                     else
                     {
                     {
-                        var thisIndex = ((JsNumber) rx.Get("lastIndex"))._value;
+                        var thisIndex = (int) ((JsNumber) rx.Get("lastIndex"))._value;
                         if (thisIndex == previousLastIndex)
                         if (thisIndex == previousLastIndex)
                         {
                         {
                             rx.Put("lastIndex", thisIndex + 1, false);
                             rx.Put("lastIndex", thisIndex + 1, false);
-                            previousLastIndex = thisIndex;
+                            previousLastIndex = thisIndex + 1;
                         }
                         }
 
 
                         var matchStr = result.Get("0");
                         var matchStr = result.Get("0");