From ab940869ea83c4734ab516d5b39237828db72585 Mon Sep 17 00:00:00 2001
From: Paolo Carlini <pcarlini@suse.de>
Date: Fri, 21 Oct 2005 08:34:06 +0000
Subject: [PATCH] re PR libstdc++/24450 (Exception safety problem in
 messages/__timepunct)

2005-10-21  Paolo Carlini  <pcarlini@suse.de>

	PR libstdc++/24450
	* config/locale/generic/time_members.h (__timepunct<>::
	__timepunct(__c_locale, const char*, size_t)): Avoid leaking
	memory if new throws inside _M_initialize_timepunct.
	* config/locale/gnu/time_members.h (__timepunct<>::
	__timepunct(__c_locale, const char*, size_t)): Likewise.
	* config/locale/gnu/message_members.h (messages<>::
	messages(__c_locale, const char*, size_t)): Rearrange to
	avoid memory leaks.

From-SVN: r105729
---
 libstdc++-v3/ChangeLog                        | 12 ++++++++++
 .../config/locale/generic/time_members.h      | 16 ++++++++++----
 .../config/locale/gnu/messages_members.h      | 15 ++++++++-----
 libstdc++-v3/config/locale/gnu/time_members.h | 22 +++++++++++++------
 4 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 902f5f27dafd..0bc4a95e8b43 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,15 @@
+2005-10-21  Paolo Carlini  <pcarlini@suse.de>
+
+	PR libstdc++/24450
+	* config/locale/generic/time_members.h (__timepunct<>::
+	__timepunct(__c_locale, const char*, size_t)): Avoid leaking
+	memory if new throws inside _M_initialize_timepunct.
+	* config/locale/gnu/time_members.h (__timepunct<>::
+	__timepunct(__c_locale, const char*, size_t)): Likewise.
+	* config/locale/gnu/message_members.h (messages<>::
+	messages(__c_locale, const char*, size_t)): Rearrange to
+	avoid memory leaks.
+
 2005-10-19  Paolo Carlini  <pcarlini@suse.de>
 
 	* include/ext/sso_string_base.h (_M_swap): Rewrite.
diff --git a/libstdc++-v3/config/locale/generic/time_members.h b/libstdc++-v3/config/locale/generic/time_members.h
index deea0c8feddb..b3112dc4e37d 100644
--- a/libstdc++-v3/config/locale/generic/time_members.h
+++ b/libstdc++-v3/config/locale/generic/time_members.h
@@ -1,6 +1,6 @@
 // std::time_get, std::time_put implementation, generic version -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -55,10 +55,18 @@
 				     size_t __refs) 
     : facet(__refs), _M_data(NULL)
     { 
-      char* __tmp = new char[std::strlen(__s) + 1];
-      std::strcpy(__tmp, __s);
+      const size_t __len = std::strlen(__s) + 1;
+      char* __tmp = new char[__len];
+      std::memcpy(__tmp, __s, __len);
       _M_name_timepunct = __tmp;
-      _M_initialize_timepunct(__cloc); 
+
+      try
+	{ _M_initialize_timepunct(__cloc); }
+      catch(...)
+	{ 
+	  delete [] _M_name_timepunct;
+	  __throw_exception_again;
+	}
     }
 
   template<typename _CharT>
diff --git a/libstdc++-v3/config/locale/gnu/messages_members.h b/libstdc++-v3/config/locale/gnu/messages_members.h
index 92081e3e376e..5fb7a999da01 100644
--- a/libstdc++-v3/config/locale/gnu/messages_members.h
+++ b/libstdc++-v3/config/locale/gnu/messages_members.h
@@ -1,6 +1,6 @@
 // std::messages implementation details, GNU version -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -37,18 +37,21 @@
   template<typename _CharT>
      messages<_CharT>::messages(size_t __refs)
      : facet(__refs), _M_c_locale_messages(_S_get_c_locale()), 
-     _M_name_messages(_S_get_c_name())
+       _M_name_messages(_S_get_c_name())
      { }
 
   template<typename _CharT>
      messages<_CharT>::messages(__c_locale __cloc, const char* __s, 
 				size_t __refs) 
-     : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
-     _M_name_messages(__s)
+     : facet(__refs), _M_c_locale_messages(NULL), _M_name_messages(NULL)
      {
-       char* __tmp = new char[std::strlen(__s) + 1];
-       std::strcpy(__tmp, __s);
+       const size_t __len = std::strlen(__s) + 1;
+       char* __tmp = new char[__len];
+       std::memcpy(__tmp, __s, __len);
        _M_name_messages = __tmp;
+
+       // Last to avoid leaking memory if new throws.
+       _M_c_locale_messages = _S_clone_c_locale(__cloc);
      }
 
   template<typename _CharT>
diff --git a/libstdc++-v3/config/locale/gnu/time_members.h b/libstdc++-v3/config/locale/gnu/time_members.h
index 37a01ef4793c..7014630731e4 100644
--- a/libstdc++-v3/config/locale/gnu/time_members.h
+++ b/libstdc++-v3/config/locale/gnu/time_members.h
@@ -1,6 +1,6 @@
 // std::time_get, std::time_put implementation, GNU version -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -37,25 +37,33 @@
   template<typename _CharT>
     __timepunct<_CharT>::__timepunct(size_t __refs) 
     : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), 
-    _M_name_timepunct(_S_get_c_name())
+      _M_name_timepunct(_S_get_c_name())
     { _M_initialize_timepunct(); }
 
   template<typename _CharT>
     __timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs) 
     : facet(__refs), _M_data(__cache), _M_c_locale_timepunct(NULL), 
-    _M_name_timepunct(_S_get_c_name())
+      _M_name_timepunct(_S_get_c_name())
     { _M_initialize_timepunct(); }
 
   template<typename _CharT>
     __timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
 				     size_t __refs) 
     : facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL), 
-    _M_name_timepunct(__s)
+      _M_name_timepunct(NULL)
     { 
-      char* __tmp = new char[std::strlen(__s) + 1];
-      std::strcpy(__tmp, __s);
+      const size_t __len = std::strlen(__s) + 1;
+      char* __tmp = new char[__len];
+      std::memcpy(__tmp, __s, __len);
       _M_name_timepunct = __tmp;
-      _M_initialize_timepunct(__cloc); 
+
+      try
+	{ _M_initialize_timepunct(__cloc); }
+      catch(...)
+	{
+	  delete [] _M_name_timepunct;
+	  __throw_exception_again;
+	}
     }
 
   template<typename _CharT>
-- 
GitLab