]> git.lyx.org Git - features.git/blobdiff - 3rdparty/boost/boost/regex/v4/basic_regex_parser.hpp
Update to boost 1.68
[features.git] / 3rdparty / boost / boost / regex / v4 / basic_regex_parser.hpp
index 4ab1670e1fbba1ff7afde6d52a4b1b113365714c..7c2852fa510693b404003896cae2a7b4aff66d13 100644 (file)
@@ -105,6 +105,7 @@ private:
    std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).
    std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative
    bool                       m_has_case_change; // true if somewhere in the current block the case has changed
+   unsigned                   m_recursion_count; // How many times we've called parse_all.
 #if defined(BOOST_MSVC) && defined(_M_IX86)
    // This is an ugly warning suppression workaround (for warnings *inside* std::vector
    // that can not otherwise be suppressed)...
@@ -120,7 +121,7 @@ private:
 
 template <class charT, class traits>
 basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
-   : basic_regex_creator<charT, traits>(data), m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false)
+   : basic_regex_creator<charT, traits>(data), m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0)
 {
 }
 
@@ -245,11 +246,17 @@ void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_c
 template <class charT, class traits>
 bool basic_regex_parser<charT, traits>::parse_all()
 {
+   if (++m_recursion_count > 400)
+   {
+      // exceeded internal limits
+      fail(boost::regex_constants::error_complexity, m_position - m_base, "Exceeded nested brace limit.");
+   }
    bool result = true;
    while(result && (m_position != m_end))
    {
       result = (this->*m_parser_proc)();
    }
+   --m_recursion_count;
    return result;
 }
 
@@ -971,7 +978,13 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_
       )
    {
       // OK we have a perl or emacs regex, check for a '?':
-      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
+      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
+      {
+         // whitespace skip:
+         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+            ++m_position;
+      }
+      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))
       {
          greedy = false;
          ++m_position;
@@ -1064,15 +1077,42 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_
          // Check for illegal following quantifier, we have to do this here, because
          // the extra states we insert below circumvents our usual error checking :-(
          //
-         switch(this->m_traits.syntax_type(*m_position))
+         bool contin = false;
+         do
          {
-         case regex_constants::syntax_star:
-         case regex_constants::syntax_plus:
-         case regex_constants::syntax_question:
-         case regex_constants::syntax_open_brace:
-            fail(regex_constants::error_badrepeat, m_position - m_base);
-            return false;
-         }
+            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
+            {
+               // whitespace skip:
+               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
+                  ++m_position;
+            }
+            if (m_position != m_end)
+            {
+               switch (this->m_traits.syntax_type(*m_position))
+               {
+               case regex_constants::syntax_star:
+               case regex_constants::syntax_plus:
+               case regex_constants::syntax_question:
+               case regex_constants::syntax_open_brace:
+                  fail(regex_constants::error_badrepeat, m_position - m_base);
+                  return false;
+               case regex_constants::syntax_open_mark:
+                  // Do we have a comment?  If so we need to skip it here...
+                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question
+                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)
+                  {
+                     while ((m_position != m_end)
+                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {
+                     }
+                     contin = true;
+                  }
+                  else
+                     contin = false;
+               }
+            }
+            else
+               contin = false;
+         } while (contin);
       }
       re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
       pb->index = -3;
@@ -1991,7 +2031,7 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
    {
       while((m_position != m_end) 
          && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
-      {}      
+      {}
       return true;
    }
    //
@@ -2070,6 +2110,11 @@ insert_recursion:
          fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
          return false;
       }
+      if ((std::numeric_limits<boost::intmax_t>::max)() - m_mark_count < v)
+      {
+         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
+         return false;
+      }
       v += m_mark_count;
       goto insert_recursion;
    case regex_constants::syntax_dash: