Regex: Repeating a repeat is not allowed, even if there is a comment block in between the two.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3479#c2
This commit is contained in:
jzmaddock
2017-10-24 17:56:02 +01:00
parent 544e20a339
commit 50453e319a
2 changed files with 39 additions and 15 deletions

View File

@ -1077,21 +1077,40 @@ 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 :-(
//
if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
bool contin = false;
do
{
// whitespace skip:
while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
++m_position;
}
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;
}
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;
} while (contin);
}
re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
pb->index = -3;

View File

@ -205,6 +205,11 @@ void test_options()
TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a bcde", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "a bcde f", match_default, make_array(0, 8, 0, 8, -2, -2));
TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "abcdef", match_default, make_array(-2, -2));
TEST_INVALID_REGEX("a++(?#abc)+", perl);
TEST_INVALID_REGEX("a++(?#abc)?", perl);
TEST_INVALID_REGEX("a++(?#abc)*", perl);
TEST_INVALID_REGEX("a++(?#abc){2}", perl);
}
void test_options2()