From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 5B8EE3850858; Wed, 7 Sep 2022 17:49:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B8EE3850858 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1662572976; bh=rsB3dQlMIWQAgTYCtEgmKS/2/dX/kCQuP2n6PMYGa0s=; h=From:To:Subject:Date:From; b=EDonJrHNDfqJm+Neu3mmrg0LILtG/28jdaYxxmePDA5hmqfEn0bc98y4a1L1yJfCe zjX+zmb1LxsSKVcoCLl5+2UIOVBbya3uQB4lOGTo5WZDeutIom6ntdEVpSH7SRY4VN cfmZ8BiQey4q4U5YC9pYREXaRnkNM8QBRd4PU6ro= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r11-10243] libstdc++: Check for overflow in regex back-reference [PR106607] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: da67352690c8ed7f3045487e6e1ea391aeab7fc8 X-Git-Newrev: d023d805d9e20c3f46654dc7ea96c9228d650ddb Message-Id: <20220907174936.5B8EE3850858@sourceware.org> Date: Wed, 7 Sep 2022 17:49:36 +0000 (GMT) List-Id: https://gcc.gnu.org/g:d023d805d9e20c3f46654dc7ea96c9228d650ddb commit r11-10243-gd023d805d9e20c3f46654dc7ea96c9228d650ddb Author: Jonathan Wakely Date: Mon Aug 22 15:16:16 2022 +0100 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. (cherry picked from commit 1b09eea33f2bf9d1eae73b25cc25efb05ea1dc3f) Diff: --- libstdc++-v3/include/bits/regex_compiler.tcc | 10 +++++---- .../testsuite/28_regex/basic_regex/106607.cc | 25 ++++++++++++++++++++++ 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 9000aec8e25..6f42f2aed65 100644 --- a/libstdc++-v3/include/bits/regex_compiler.tcc +++ b/libstdc++-v3/include/bits/regex_compiler.tcc @@ -588,10 +588,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 00000000000..f8e7fb2364d --- /dev/null +++ b/libstdc++-v3/testsuite/28_regex/basic_regex/106607.cc @@ -0,0 +1,25 @@ +// { dg-do run { target c++11 } } + +#include +#include +#include +#include + +// 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 ); + } +}