aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2022-08-22 15:16:16 +0100
committerJonathan Wakely <jwakely@redhat.com>2022-08-22 22:52:24 +0100
commit1b09eea33f2bf9d1eae73b25cc25efb05ea1dc3f (patch)
tree13ab4879e18170f3920e84ce931e44a006f38e84 /libstdc++-v3
parent990124c35cd60cd23e0b70fc84cfb75311e80276 (diff)
downloadgcc-1b09eea33f2bf9d1eae73b25cc25efb05ea1dc3f.zip
gcc-1b09eea33f2bf9d1eae73b25cc25efb05ea1dc3f.tar.gz
gcc-1b09eea33f2bf9d1eae73b25cc25efb05ea1dc3f.tar.bz2
libstdc++: Check for overflow in regex back-reference [PR106607]
Currently we fail to notice integer overflow when parsing a back-reference expression, or when converting the parsed result from long to int. This changes the result to be int, so no conversion is needed, and uses the overflow-checking built-ins to detect an out-of-range back-reference. libstdc++-v3/ChangeLog: PR libstdc++/106607 * include/bits/regex_compiler.tcc (_Compiler::_M_cur_int_value): Use built-ins to check for integer overflow in back-reference number. * testsuite/28_regex/basic_regex/106607.cc: New test.
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.tcc10
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc25
2 files changed, 31 insertions, 4 deletions
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
index c12f750..9f3ca63 100644
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -583,10 +583,12 @@ namespace __detail
_Compiler<_TraitsT>::
_M_cur_int_value(int __radix)
{
- long __v = 0;
- for (typename _StringT::size_type __i = 0;
- __i < _M_value.length(); ++__i)
- __v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
+ int __v = 0;
+ for (_CharT __c : _M_value)
+ if (__builtin_mul_overflow(__v, __radix, &__v)
+ || __builtin_add_overflow(__v, _M_traits.value(__c, __radix), &__v))
+ std::__throw_regex_error(regex_constants::error_backref,
+ "invalid back reference");
return __v;
}
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc
new file mode 100644
index 0000000..f8e7fb2
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc
@@ -0,0 +1,25 @@
+// { dg-do run { target c++11 } }
+
+#include <regex>
+#include <string>
+#include <climits>
+#include <testsuite_hooks.h>
+
+// PR libstdc++/106607 - Regex integer overflow on large backreference value
+
+int main()
+{
+ std::regex r("(.)\\1"); // OK
+
+ try
+ {
+ long long n = (unsigned)-1 + 2LL; // 4294967297 for 32-bit int
+ VERIFY( (int)n == 1 ); // 4294967297 % 2^32 == 1
+ std::regex r("(.)\\" + std::to_string(n)); // Invalid back reference.
+ VERIFY(false);
+ }
+ catch (const std::regex_error& e)
+ {
+ VERIFY( e.code() == std::regex_constants::error_backref );
+ }
+}