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)...
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)
{
}
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;
}
)
{
// 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;
// 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;
{
while((m_position != m_end)
&& (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
- {}
+ {}
return true;
}
//
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: