re PR libstdc++/63497 (std::regex can't handle [^class] correctly and cause runtime crash)

PR libstdc++/63497
	include/bits/regex_executor.h (_Executor::_M_word_boundary): Remove
	unused parameter.
	include/bits/regex_executor.tcc (_Executor::_M_dfs,
	_Executor::_M_word_boundary): Avoid dereferecing _M_current at _M_end
	or other invalid position.

From-SVN: r216572
This commit is contained in:
Tim Shen 2014-10-23 03:15:52 +00:00 committed by Tim Shen
parent a3317c9247
commit 4d8384337f
3 changed files with 31 additions and 19 deletions

View File

@ -1,3 +1,12 @@
2014-10-23 Tim Shen <timshen@google.com>
PR libstdc++/63497
include/bits/regex_executor.h (_Executor::_M_word_boundary): Remove
unused parameter.
include/bits/regex_executor.tcc (_Executor::_M_dfs,
_Executor::_M_word_boundary): Avoid dereferecing _M_current at _M_end
or other invalid position.
2014-10-21 Joern Rennecke <joern.rennecke@embecosm.com>
* testsuite/util/io/prog_bar.cc: Qualify size_t.

View File

@ -145,7 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
bool
_M_word_boundary(_State<_TraitsT> __state) const;
_M_word_boundary() const;
bool
_M_lookahead(_State<_TraitsT> __state);

View File

@ -274,7 +274,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_dfs(__match_mode, __state._M_next);
break;
case _S_opcode_word_boundary:
if (_M_word_boundary(__state) == !__state._M_neg)
if (_M_word_boundary() == !__state._M_neg)
_M_dfs(__match_mode, __state._M_next);
break;
// Here __state._M_alt offers a single start node for a sub-NFA.
@ -284,9 +284,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_dfs(__match_mode, __state._M_next);
break;
case _S_opcode_match:
if (_M_current == _M_end)
break;
if (__dfs_mode)
{
if (_M_current != _M_end && __state._M_matches(*_M_current))
if (__state._M_matches(*_M_current))
{
++_M_current;
_M_dfs(__match_mode, __state._M_next);
@ -407,25 +409,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _BiIter, typename _Alloc, typename _TraitsT,
bool __dfs_mode>
bool _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
_M_word_boundary(_State<_TraitsT>) const
_M_word_boundary() const
{
// By definition.
bool __ans = false;
auto __pre = _M_current;
--__pre;
if (!(_M_at_begin() && _M_at_end()))
bool __left_is_word = false;
if (_M_current != _M_begin
|| (_M_flags & regex_constants::match_prev_avail))
{
if (_M_at_begin())
__ans = _M_is_word(*_M_current)
&& !(_M_flags & regex_constants::match_not_bow);
else if (_M_at_end())
__ans = _M_is_word(*__pre)
&& !(_M_flags & regex_constants::match_not_eow);
else
__ans = _M_is_word(*_M_current)
!= _M_is_word(*__pre);
auto __prev = _M_current;
if (_M_is_word(*std::prev(__prev)))
__left_is_word = true;
}
return __ans;
bool __right_is_word =
_M_current != _M_end && _M_is_word(*_M_current);
if (__left_is_word == __right_is_word)
return false;
if (__left_is_word && !(_M_flags & regex_constants::match_not_eow))
return true;
if (__right_is_word && !(_M_flags & regex_constants::match_not_bow))
return true;
return false;
}
_GLIBCXX_END_NAMESPACE_VERSION