Forráskód Böngészése

Fixing RegExp multiline support

Sebastien Ros 9 éve
szülő
commit
2d35385bc4

+ 28 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -1648,5 +1648,33 @@ namespace Jint.Tests.Runtime
                 assert(result === 'Quick Brown Fox Jumps');
             ");
         }
+
+        [Fact]
+        public void RegExpSupportsMultiline()
+        {
+            RunTest(@"
+                var rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg;
+                var headersString = 'X-AspNetMvc-Version: 4.0\r\nX-Powered-By: ASP.NET\r\n\r\n';
+                match = rheaders.exec(headersString);
+                assert('X-AspNetMvc-Version' === match[1]);
+                assert('4.0' === match[2]);
+            ");
+
+            RunTest(@"
+                var rheaders = /^(.*?):[ \t]*(.*?)$/mg;
+                var headersString = 'X-AspNetMvc-Version: 4.0\r\nX-Powered-By: ASP.NET\r\n\r\n';
+                match = rheaders.exec(headersString);
+                assert('X-AspNetMvc-Version' === match[1]);
+                assert('4.0' === match[2]);
+            ");
+
+            RunTest(@"
+                var rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg;
+                var headersString = 'X-AspNetMvc-Version: 4.0\nX-Powered-By: ASP.NET\n\n';
+                match = rheaders.exec(headersString);
+                assert('X-AspNetMvc-Version' === match[1]);
+                assert('4.0' === match[2]);
+            ");
+        }
     }
 }

+ 23 - 1
Jint/Native/RegExp/RegExpConstructor.cs

@@ -138,7 +138,29 @@ namespace Jint.Native.RegExp
             var options = ParseOptions(r, flags);
             try
             {
-                r.Value = new Regex(pattern, options);
+                if((RegexOptions.Multiline & options) == RegexOptions.Multiline)
+                {
+                    // Replace all non-escaped $ occurences by \r?$
+                    // c.f. http://programmaticallyspeaking.com/regular-expression-multiline-mode-whats-a-newline.html
+
+                    int index = 0;
+                    var newPattern = pattern;
+                    while((index = newPattern.IndexOf("$", index)) != -1)
+                    {
+                        if(index > 0 && newPattern[index - 1] != '\\')
+                        {
+                            newPattern = newPattern.Substring(0, index) + @"\r?" + newPattern.Substring(index);
+                            index += 4;
+                        }
+                    }
+
+                    r.Value = new Regex(newPattern, options);
+                }
+                else
+                {
+                    r.Value = new Regex(pattern, options);
+                }
+                
             }
             catch (Exception e)
             {