* RegexTest.cs (PrimeRegex): New backtracking torture test using
authorRaja R Harinath <harinath@hurrynot.org>
Wed, 4 Apr 2007 14:33:46 +0000 (14:33 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Wed, 4 Apr 2007 14:33:46 +0000 (14:33 -0000)
a regex that recognizes composite numbers represented in unary.

svn path=/trunk/mcs/; revision=75388

mcs/class/System/Test/System.Text.RegularExpressions/ChangeLog
mcs/class/System/Test/System.Text.RegularExpressions/RegexTest.cs

index 0104b541351f7a96b10e51419cfd88130f66a0fb..b246d7e93b41d0c46db716dfceaf5452024421a1 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-04  Raja R Harinath  <rharinath@novell.com>
+
+       * RegexTest.cs (PrimeRegex): New backtracking torture test using
+       a regex that recognizes composite numbers represented in unary.
+
 2007-01-02  Raja R Harinath  <rharinath@novell.com>
 
        * RegexBugs.cs (GroupNumbers): New test based on #79472.
index 892ad9266905d421e29807ae3916a3a668ef6855..293d0baf8fa46b5034f6dd776d7e0c2bf60ef000 100644 (file)
 using System;
 using System.Text.RegularExpressions;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 using NUnit.Framework;
 
 namespace MonoTests.System.Text.RegularExpressions {
@@ -195,6 +199,63 @@ namespace MonoTests.System.Text.RegularExpressions {
                {
                        Regex.CacheSize = Int32.MinValue;
                }
+
+               static IEnumerable<uint> Primes (uint m)
+               {
+                       if (m < 2)
+                               yield break;
+
+                       yield return 2;
+
+                       Dictionary<uint, uint> w = new Dictionary<uint, uint> ();
+                       uint p2, n1;
+
+                       for (uint n = 3; n < m; n += 2) {
+                               if (w.TryGetValue (n, out p2)) {
+                                       w.Remove (n);
+                                       n1 = n + p2;
+                               } else {
+                                       yield return n;
+                                       n1 = n * n;
+                                       p2 = n + n;
+
+                                       // if there's an overflow, don't bother
+                                       if (n1 / n != n || n1 >= m)
+                                               continue;
+                               }
+
+                               while (w.ContainsKey (n1))
+                                       n1 += p2;
+                               w [n1] = p2;
+                       }
+               }
+
+               [Test]
+               public void PrimeRegex ()
+               {
+                       // Perl regex oneliner by: abigail@fnx.com (Abigail)
+                       // from: http://www.mit.edu:8008/bloom-picayune.mit.edu/perl/10138
+                       // perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'
+
+                       // This is a backtracking torture test
+
+                       Regex composite = new Regex (@"^1?$|^(11+?)\1+$");
+
+                       uint i = 0;
+                       string x = "";
+
+                       foreach (uint p in Primes (3333)) {
+                               while (i < p) {
+                                       Assert.IsTrue (composite.IsMatch (x));
+                                       ++i;
+                                       x += "1";
+                               }
+                               // i == p
+                               Assert.IsFalse (composite.IsMatch (x));
+                               ++i;
+                               x += "1";
+                       }
+               }
 #endif
        }
 }