forked from boostorg/regex
When a {} repeat sequence is invalid or incomplete, and the language is Perl, then backtrack and treat the sequence as a literal, not a repeat operator.
Fixes #8569. [SVN r84371]
This commit is contained in:
@ -1070,26 +1070,46 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
|
|||||||
// skip whitespace:
|
// skip whitespace:
|
||||||
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
|
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
|
||||||
++m_position;
|
++m_position;
|
||||||
// fail if at end:
|
|
||||||
if(this->m_position == this->m_end)
|
if(this->m_position == this->m_end)
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
|
||||||
return false;
|
{
|
||||||
|
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
// get min:
|
// get min:
|
||||||
v = this->m_traits.toi(m_position, m_end, 10);
|
v = this->m_traits.toi(m_position, m_end, 10);
|
||||||
// skip whitespace:
|
// skip whitespace:
|
||||||
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
|
|
||||||
++m_position;
|
|
||||||
if(v < 0)
|
if(v < 0)
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_badbrace, this->m_position - this->m_base);
|
if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
|
||||||
return false;
|
{
|
||||||
|
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
else if(this->m_position == this->m_end)
|
while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
|
||||||
|
++m_position;
|
||||||
|
if(this->m_position == this->m_end)
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
|
||||||
return false;
|
{
|
||||||
|
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
min = v;
|
min = v;
|
||||||
// see if we have a comma:
|
// see if we have a comma:
|
||||||
@ -1102,8 +1122,15 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
|
|||||||
++m_position;
|
++m_position;
|
||||||
if(this->m_position == this->m_end)
|
if(this->m_position == this->m_end)
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
|
||||||
return false;
|
{
|
||||||
|
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
// get the value if any:
|
// get the value if any:
|
||||||
v = this->m_traits.toi(m_position, m_end, 10);
|
v = this->m_traits.toi(m_position, m_end, 10);
|
||||||
@ -1120,8 +1147,15 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
|
|||||||
// OK now check trailing }:
|
// OK now check trailing }:
|
||||||
if(this->m_position == this->m_end)
|
if(this->m_position == this->m_end)
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
|
||||||
return false;
|
{
|
||||||
|
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
if(isbasic)
|
if(isbasic)
|
||||||
{
|
{
|
||||||
@ -1144,8 +1178,10 @@ bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
|
|||||||
++m_position;
|
++m_position;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
|
// Treat the opening '{' as a literal character, rewind to start of error:
|
||||||
return false;
|
--m_position;
|
||||||
|
while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
|
||||||
|
return parse_literal();
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// finally go and add the repeat, unless error:
|
// finally go and add the repeat, unless error:
|
||||||
|
@ -179,21 +179,20 @@ void test_simple_repeats2()
|
|||||||
{
|
{
|
||||||
using namespace boost::regex_constants;
|
using namespace boost::regex_constants;
|
||||||
|
|
||||||
TEST_INVALID_REGEX("a{}", perl);
|
TEST_REGEX_SEARCH("a{}", basic, "a{}", match_default, make_array(0, 3, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{", perl);
|
TEST_REGEX_SEARCH("a{", basic, "a{", match_default, make_array(0, 2, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1", perl);
|
TEST_REGEX_SEARCH("a{1", basic, "a{1", match_default, make_array(0, 3, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1,", perl);
|
TEST_REGEX_SEARCH("a{1,", basic, "a{1,", match_default, make_array(0, 4, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1,2", perl);
|
TEST_REGEX_SEARCH("a{1,2", basic, "a{1,2", match_default, make_array(0, 5, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{ 1 , 2 ", perl);
|
TEST_REGEX_SEARCH("a{ 1 , 2", basic, "a{ 1 , 2", match_default, make_array(0, 8, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{ }", perl);
|
TEST_REGEX_SEARCH("a{ }", basic, "a{ }", match_default, make_array(0, 4, -2, -2));
|
||||||
TEST_INVALID_REGEX("a}", perl);
|
TEST_REGEX_SEARCH("a}", basic, "a}", match_default, make_array(0, 2, -2, -2));
|
||||||
TEST_INVALID_REGEX("{1}", perl);
|
TEST_INVALID_REGEX("{1}", perl);
|
||||||
TEST_INVALID_REGEX("a{b}", perl);
|
TEST_REGEX_SEARCH("a{b}", basic, "a{b}", match_default, make_array(0, 4, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1b}", perl);
|
TEST_REGEX_SEARCH("a{1b", basic, "a{1b", match_default, make_array(0, 4, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1,b}", perl);
|
TEST_REGEX_SEARCH("a{1,b}", basic, "a{1,b}", match_default, make_array(0, 6, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{1,2v}", perl);
|
TEST_REGEX_SEARCH("a{1,2v}", basic, "a{1,2v}", match_default, make_array(0, 7, -2, -2));
|
||||||
TEST_INVALID_REGEX("a{2,1}", perl);
|
TEST_INVALID_REGEX("a{2,1}", perl);
|
||||||
|
|
||||||
// now try operator \\{\\} for POSIX basic regexes
|
// now try operator \\{\\} for POSIX basic regexes
|
||||||
TEST_REGEX_SEARCH("a\\{2\\}", basic, "a", match_default, make_array(-2, -2));
|
TEST_REGEX_SEARCH("a\\{2\\}", basic, "a", match_default, make_array(-2, -2));
|
||||||
TEST_REGEX_SEARCH("a\\{2\\}", basic|no_intervals, "a{2}", match_default, make_array(0, 4, -2, -2));
|
TEST_REGEX_SEARCH("a\\{2\\}", basic|no_intervals, "a{2}", match_default, make_array(0, 4, -2, -2));
|
||||||
|
Reference in New Issue
Block a user