Fix an unsigned integer overflow in regex that lead to a bad memory access. Found by OSS-Fuzz
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@316191 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -4327,8 +4327,12 @@ basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first,
|
|||||||
unsigned __v = *__first - '0';
|
unsigned __v = *__first - '0';
|
||||||
for (++__first;
|
for (++__first;
|
||||||
__first != __last && '0' <= *__first && *__first <= '9'; ++__first)
|
__first != __last && '0' <= *__first && *__first <= '9'; ++__first)
|
||||||
|
{
|
||||||
|
if (__v >= std::numeric_limits<unsigned>::max() / 10)
|
||||||
|
__throw_regex_error<regex_constants::error_backref>();
|
||||||
__v = 10 * __v + *__first - '0';
|
__v = 10 * __v + *__first - '0';
|
||||||
if (__v > mark_count())
|
}
|
||||||
|
if (__v == 0 || __v > mark_count())
|
||||||
__throw_regex_error<regex_constants::error_backref>();
|
__throw_regex_error<regex_constants::error_backref>();
|
||||||
__push_back_ref(__v);
|
__push_back_ref(__v);
|
||||||
}
|
}
|
||||||
@@ -5455,15 +5459,17 @@ match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output,
|
|||||||
if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')
|
if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')
|
||||||
{
|
{
|
||||||
++__fmt_first;
|
++__fmt_first;
|
||||||
size_t __i = *__fmt_first - '0';
|
size_t __idx = *__fmt_first - '0';
|
||||||
if (__fmt_first + 1 != __fmt_last &&
|
if (__fmt_first + 1 != __fmt_last &&
|
||||||
'0' <= __fmt_first[1] && __fmt_first[1] <= '9')
|
'0' <= __fmt_first[1] && __fmt_first[1] <= '9')
|
||||||
{
|
{
|
||||||
++__fmt_first;
|
++__fmt_first;
|
||||||
__i = 10 * __i + *__fmt_first - '0';
|
if (__idx >= std::numeric_limits<size_t>::max() / 10)
|
||||||
|
__throw_regex_error<regex_constants::error_escape>();
|
||||||
|
__idx = 10 * __idx + *__fmt_first - '0';
|
||||||
}
|
}
|
||||||
__output = _VSTD::copy((*this)[__i].first,
|
__output = _VSTD::copy((*this)[__idx].first,
|
||||||
(*this)[__i].second, __output);
|
(*this)[__idx].second, __output);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ int main()
|
|||||||
{
|
{
|
||||||
assert(error_badbackref_thrown("\\1abc")); // no references
|
assert(error_badbackref_thrown("\\1abc")); // no references
|
||||||
assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference
|
assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference
|
||||||
|
assert(error_badbackref_thrown("\\800000000000000000000000000000")); // overflows
|
||||||
|
|
||||||
// this should NOT throw, because we only should look at the '1'
|
// this should NOT throw, because we only should look at the '1'
|
||||||
// See https://bugs.llvm.org/show_bug.cgi?id=31387
|
// See https://bugs.llvm.org/show_bug.cgi?id=31387
|
||||||
|
|||||||
Reference in New Issue
Block a user