mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 23:25:24 +02:00
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
25
libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc
Normal file
25
libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc
Normal file
@@ -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 );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user