summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2017-10-19 22:10:41 +0000
committerMarshall Clow <mclow.lists@gmail.com>2017-10-19 22:10:41 +0000
commit24c7353aa92301e772bd8033253f0be874ebfa54 (patch)
tree30f1bf9a4f71b4bc01a3a799db52045522b39a0d
parent278c0ba4a689e669f1ecefa1cfc0709b980bc3ec (diff)
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
-rw-r--r--include/regex16
-rw-r--r--test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp1
2 files changed, 12 insertions, 5 deletions
diff --git a/include/regex b/include/regex
index 80f958e0e..79813529d 100644
--- a/include/regex
+++ b/include/regex
@@ -4327,8 +4327,12 @@ basic_regex<_CharT, _Traits>::__parse_decimal_escape(_ForwardIterator __first,
unsigned __v = *__first - '0';
for (++__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';
- if (__v > mark_count())
+ }
+ if (__v == 0 || __v > mark_count())
__throw_regex_error<regex_constants::error_backref>();
__push_back_ref(__v);
}
@@ -5455,15 +5459,17 @@ match_results<_BidirectionalIterator, _Allocator>::format(_OutputIter __output,
if ('0' <= __fmt_first[1] && __fmt_first[1] <= '9')
{
++__fmt_first;
- size_t __i = *__fmt_first - '0';
+ size_t __idx = *__fmt_first - '0';
if (__fmt_first + 1 != __fmt_last &&
'0' <= __fmt_first[1] && __fmt_first[1] <= '9')
{
++__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,
- (*this)[__i].second, __output);
+ __output = _VSTD::copy((*this)[__idx].first,
+ (*this)[__idx].second, __output);
}
else
{
diff --git a/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp b/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
index e66d3e976..8e886cd8d 100644
--- a/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
+++ b/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp
@@ -34,6 +34,7 @@ int main()
{
assert(error_badbackref_thrown("\\1abc")); // no references
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'
// See https://bugs.llvm.org/show_bug.cgi?id=31387