[gcc r11-9900] libstdc++: Fix warning in __moneypunct_cache::_M_cache [PR104966]

Jonathan Wakely redi@gcc.gnu.org
Thu Apr 21 12:32:27 GMT 2022


https://gcc.gnu.org/g:3859a3cb9b997fb8d9134180b8cc68f040dd36f5

commit r11-9900-g3859a3cb9b997fb8d9134180b8cc68f040dd36f5
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Mar 17 13:33:07 2022 +0000

    libstdc++: Fix warning in __moneypunct_cache::_M_cache [PR104966]
    
    GCC thinks the following can lead to a buffer overflow when __ns.size()
    equals zero:
    
              const basic_string<_CharT>& __ns = __mp.negative_sign();
              _M_negative_sign_size = __ns.size();
              __negative_sign = new _CharT[_M_negative_sign_size];
              __ns.copy(__negative_sign, _M_negative_sign_size);
    
    This happens because operator new might be replaced with something that
    writes to this->_M_negative_sign_size and so the basic_string::copy call
    could use a non-zero size to write to a zero-length buffer.
    
    The solution suggested by Richi is to cache the size in a local variable
    so that the compiler knows it won't be changed between the allocation
    and the copy.
    
    libstdc++-v3/ChangeLog:
    
            PR middle-end/104966
            * include/bits/locale_facets_nonio.tcc
            (__moneypunct_cache::_M_cache): Store string sizes in local
            variable that doesn't escape.

Diff:
---
 libstdc++-v3/include/bits/locale_facets_nonio.tcc | 27 ++++++++++++-----------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/libstdc++-v3/include/bits/locale_facets_nonio.tcc b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
index 51c23d8003a..4aef5502032 100644
--- a/libstdc++-v3/include/bits/locale_facets_nonio.tcc
+++ b/libstdc++-v3/include/bits/locale_facets_nonio.tcc
@@ -78,32 +78,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       char* __grouping = 0;
       _CharT* __curr_symbol = 0;
       _CharT* __positive_sign = 0;
-      _CharT* __negative_sign = 0;     
+      _CharT* __negative_sign = 0;
+      size_t __sz;
       __try
 	{
 	  const string& __g = __mp.grouping();
-	  _M_grouping_size = __g.size();
-	  __grouping = new char[_M_grouping_size];
-	  __g.copy(__grouping, _M_grouping_size);
+	  __sz = _M_grouping_size = __g.size();
+	  __grouping = new char[__sz];
+	  __g.copy(__grouping, __sz);
 	  _M_use_grouping = (_M_grouping_size
 			     && static_cast<signed char>(__grouping[0]) > 0
 			     && (__grouping[0]
 				 != __gnu_cxx::__numeric_traits<char>::__max));
 
 	  const basic_string<_CharT>& __cs = __mp.curr_symbol();
-	  _M_curr_symbol_size = __cs.size();
-	  __curr_symbol = new _CharT[_M_curr_symbol_size];
-	  __cs.copy(__curr_symbol, _M_curr_symbol_size);
+	  __sz = _M_curr_symbol_size = __cs.size();
+	  __curr_symbol = new _CharT[__sz];
+	  __cs.copy(__curr_symbol, __sz);
 
 	  const basic_string<_CharT>& __ps = __mp.positive_sign();
-	  _M_positive_sign_size = __ps.size();
-	  __positive_sign = new _CharT[_M_positive_sign_size];
-	  __ps.copy(__positive_sign, _M_positive_sign_size);
+	  __sz = _M_positive_sign_size = __ps.size();
+	  __positive_sign = new _CharT[__sz];
+	  __ps.copy(__positive_sign, __sz);
 
 	  const basic_string<_CharT>& __ns = __mp.negative_sign();
-	  _M_negative_sign_size = __ns.size();
-	  __negative_sign = new _CharT[_M_negative_sign_size];
-	  __ns.copy(__negative_sign, _M_negative_sign_size);
+	  __sz = _M_negative_sign_size = __ns.size();
+	  __negative_sign = new _CharT[__sz];
+	  __ns.copy(__negative_sign, __sz);
 
 	  _M_pos_format = __mp.pos_format();
 	  _M_neg_format = __mp.neg_format();


More information about the Libstdc++-cvs mailing list