diff --git a/include/boost/regex/v4/basic_regex_parser.hpp b/include/boost/regex/v4/basic_regex_parser.hpp index 86575c4b..3ba17246 100644 --- a/include/boost/regex/v4/basic_regex_parser.hpp +++ b/include/boost/regex/v4/basic_regex_parser.hpp @@ -1077,21 +1077,40 @@ 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 :-( // - 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(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace))); pb->index = -3; @@ -2010,7 +2029,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; } // diff --git a/test/regress/test_perl_ex.cpp b/test/regress/test_perl_ex.cpp index 73125419..713ee889 100644 --- a/test/regress/test_perl_ex.cpp +++ b/test/regress/test_perl_ex.cpp @@ -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()