فهرست منبع

fix uninitialized memory in regex expression parsing and correct problems with allowed character lists

Kolja Strohm 11 ماه پیش
والد
کامیت
513cba4c3d
3فایلهای تغییر یافته به همراه69 افزوده شده و 18 حذف شده
  1. 58 9
      Framework Tests/Regex.cpp
  2. 4 4
      Regex.cpp
  3. 7 5
      Regex.h

+ 58 - 9
Framework Tests/Regex.cpp

@@ -73,13 +73,13 @@ namespace FrameworkTests
         TEST_METHOD (MatchTest3)
         {
             auto parser = Framework::Regex::parse("(?:abc)*");
-            auto result = parser->match("_aabcabcc", (int)strlen(" aabcabcc")); 
+            auto result = parser->match("_aabcabcc", (int)strlen(" aabcabcc"));
             Assert::IsTrue(result->getEintragAnzahl() == 5,
                 L"Invalid result count while matching '_aabcabcc' against "
                 L"'(?:abc)*'");
-            auto* first = result->z(0); 
-            auto* second = result->z(1); 
-            auto* third = result->z(2); 
+            auto* first = result->z(0);
+            auto* second = result->z(1);
+            auto* third = result->z(2);
             auto* forth = result->z(3);
             auto* fifth = result->z(4);
             Assert::IsTrue(first->getStart() == 0 && first->getEnd() == 0,
@@ -127,8 +127,8 @@ namespace FrameworkTests
             auto result = parser->match("_aabcabcc", (int)strlen(" aabcabcc"));
             Assert::IsTrue(result->getEintragAnzahl() == 8,
                 L"Invalid result count while matching '_aabcabcc' against "
-                L"'(?:abc)*?'"); 
-            auto* _0 = result->z(0); 
+                L"'(?:abc)*?'");
+            auto* _0 = result->z(0);
             auto* _1 = result->z(1);
             auto* _2 = result->z(2);
             auto* _3 = result->z(3);
@@ -199,7 +199,8 @@ namespace FrameworkTests
         TEST_METHOD (MatchTest5)
         {
             auto parser = Framework::Regex::parse("(a|b)+");
-            auto result = parser->match("cabaccccbab", (int)strlen("cabaccccbab"));
+            auto result
+                = parser->match("cabaccccbab", (int)strlen("cabaccccbab"));
             Assert::IsTrue(result->getEintragAnzahl() == 2,
                 L"Invalid result count while matching 'cabaccccbab' against "
                 L"'a|b'");
@@ -236,8 +237,7 @@ namespace FrameworkTests
         TEST_METHOD (MatchTest6)
         {
             auto parser = Framework::Regex::parse("(?:^|c)ab");
-            auto result
-                = parser->match("abcabcasd", (int)strlen("abcabcasd"));
+            auto result = parser->match("abcabcasd", (int)strlen("abcabcasd"));
             Assert::IsTrue(result->getEintragAnzahl() == 2,
                 L"Invalid result count while matching 'abcabcasd' against "
                 L"'(?:^|c)ab'");
@@ -286,5 +286,54 @@ namespace FrameworkTests
             result->release();
             parser->release();
         }
+
+        TEST_METHOD (TestNumber0)
+        {
+            auto parser = Framework::Regex::parse("^[0-9]+$");
+            auto* results = parser->match("0", 1);
+            bool ok = results->getEintragAnzahl() == 1;
+            results->release();
+            parser->release();
+            Assert::IsTrue(
+                ok, L"no result found while matcging '0' against '^[0-9]+$'");
+        }
+
+        TEST_METHOD (TestNumber1)
+        {
+            auto parser = Framework::Regex::parse("^[0-9]+(\\.[0-9]+)?$");
+            auto* results = parser->match("0", 1);
+            bool ok = results->getEintragAnzahl() == 1;
+            results->release();
+            parser->release();
+            Assert::IsTrue(ok,
+                L"no result found while matcging '0' against "
+                L"'^[0-9]+(\\.[0-9]+)?$'");
+        }
+
+        TEST_METHOD (TestNumber2)
+        {
+            auto parser = Framework::Regex::parse(
+                "^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$");
+            auto* results = parser->match("0", 1);
+            bool ok = results->getEintragAnzahl() == 1;
+            results->release();
+            parser->release();
+            Assert::IsTrue(ok,
+                L"no result found while matcging '0' against "
+                L"'^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$'");
+        }
+
+        TEST_METHOD (TestNumber3)
+        {
+            auto parser = Framework::Regex::parse(
+                "^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$");
+            auto* results = parser->match("1e-3", 1);
+            bool ok = results->getEintragAnzahl() == 1;
+            results->release();
+            parser->release();
+            Assert::IsTrue(ok,
+                L"no result found while matcging '1e-3' against "
+                L"'^[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$'");
+        }
     };
 } // namespace FrameworkTests

+ 4 - 4
Regex.cpp

@@ -57,13 +57,13 @@ Automata<char>* parseCharacterList(Text* regex, RegexConfig& config)
         case '-':
             if (escaped || !minusValid)
             {
-                characterList += '-';
+                characterList += "-";
             }
             else if (minusValid)
             {
                 if (i == length - 1)
                 {
-                    characterList += '-';
+                    characterList += "-";
                 }
                 else
                 {
@@ -80,12 +80,12 @@ Automata<char>* parseCharacterList(Text* regex, RegexConfig& config)
                     }
                     for (unsigned char c = before; c <= after; c++)
                     {
-                        characterList += c;
+                        characterList.append((char)c);
                     }
                     i++;
                 }
-                break;
             }
+            break;
         default:
             {
                 if (escaped)

+ 7 - 5
Regex.h

@@ -28,7 +28,8 @@ namespace Framework
         public:
             Transition()
                 : conditionFunction(0),
-                  zTarget(0)
+                  zTarget(0),
+                  requiredFlags(0)
             {}
 
             Transition(std::function<bool(Data, int)> conditionFunction,
@@ -41,7 +42,8 @@ namespace Framework
 
             Transition(const Transition& other)
                 : conditionFunction(other.conditionFunction),
-                  zTarget(other.zTarget)
+                  zTarget(other.zTarget),
+                  requiredFlags(other.requiredFlags)
             {}
 
             bool test(Data value, int flags) const
@@ -326,12 +328,12 @@ namespace Framework
                 while (currentFrame)
                 {
                     if (currentFrame->getStrIndex() >= length)
-					{
-						flags |= Flags::END;
+                    {
+                        flags |= Flags::END;
                     }
                     else
                     {
-						flags &= ~Flags::END;
+                        flags &= ~Flags::END;
                     }
                     if (currentFrame->getStrIndex() == 0)
                     {