X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=3rdparty%2Fboost%2Fboost%2Fregex%2Fv4%2Fbasic_regex_parser.hpp;h=7c2852fa510693b404003896cae2a7b4aff66d13;hb=c40d23deacc277e4a862db803c565ff04e6031f1;hp=4ab1670e1fbba1ff7afde6d52a4b1b113365714c;hpb=2dc84b69d5a040e6343e21606f1c16a7c0957383;p=features.git diff --git a/3rdparty/boost/boost/regex/v4/basic_regex_parser.hpp b/3rdparty/boost/boost/regex/v4/basic_regex_parser.hpp index 4ab1670e1f..7c2852fa51 100644 --- a/3rdparty/boost/boost/regex/v4/basic_regex_parser.hpp +++ b/3rdparty/boost/boost/regex/v4/basic_regex_parser.hpp @@ -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 basic_regex_parser::basic_regex_parser(regex_data* data) - : basic_regex_creator(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(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::fail(regex_constants::error_type error_c template bool basic_regex_parser::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::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::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(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace))); pb->index = -3; @@ -1991,7 +2031,7 @@ bool basic_regex_parser::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::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: