From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 633AF389201F for ; Tue, 10 Nov 2020 23:50:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 633AF389201F Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-136-X2st74yrNCGehPRSLztP3Q-1; Tue, 10 Nov 2020 18:50:26 -0500 X-MC-Unique: X2st74yrNCGehPRSLztP3Q-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B1ED61017DC3; Tue, 10 Nov 2020 23:50:25 +0000 (UTC) Received: from localhost (unknown [10.33.36.62]) by smtp.corp.redhat.com (Postfix) with ESMTP id 61C8D55761; Tue, 10 Nov 2020 23:50:25 +0000 (UTC) Date: Tue, 10 Nov 2020 23:50:24 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Avoid bad_alloc exceptions when changing locales Message-ID: <20201110235024.GA4798@redhat.com> MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="W/nzBZO5zC0uMSeA" Content-Disposition: inline X-Spam-Status: No, score=-14.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 Nov 2020 23:50:32 -0000 --W/nzBZO5zC0uMSeA Content-Type: text/plain; charset=us-ascii Content-Disposition: inline For the --enable-clocale=generic configuration, the current code can fail with a bad_alloc exception. This patch uses the nothrow version of operator new and reports allocation failures by setting failbit in the iostate variable. * config/locale/generic/c_locale.cc (__set_C_locale()): New function to set the "C" locale and return the name of the previous locale. (__convert_to_v, __convert_to_v) (__convert_to_v): Use __set_C_locale and set failbit on error. Tested sparc-sun-solaris2.11. Committed to trunk. --W/nzBZO5zC0uMSeA Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 5dfbc52264fc64db22e75f385be9efae3d0eba46 Author: Jonathan Wakely Date: Tue Nov 10 19:23:15 2020 libstdc++: Avoid bad_alloc exceptions when changing locales For the --enable-clocale=generic configuration, the current code can fail with a bad_alloc exception. This patch uses the nothrow version of operator new and reports allocation failures by setting failbit in the iostate variable. * config/locale/generic/c_locale.cc (__set_C_locale()): New function to set the "C" locale and return the name of the previous locale. (__convert_to_v, __convert_to_v) (__convert_to_v): Use __set_C_locale and set failbit on error. diff --git a/libstdc++-v3/config/locale/generic/c_locale.cc b/libstdc++-v3/config/locale/generic/c_locale.cc index 61ead91ec1ed..648b8e182cc7 100644 --- a/libstdc++-v3/config/locale/generic/c_locale.cc +++ b/libstdc++-v3/config/locale/generic/c_locale.cc @@ -52,6 +52,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ~_Save_errno() { if (errno == 0) errno = _M_errno; } int _M_errno; }; + + // calls setlocale(LC_ALL, "C") and returns a string containing the old + // locale name. Caller must delete[] the string. Returns NULL on error. + const char* + __set_C_locale() + { + char* __old = setlocale(LC_ALL, 0); + const size_t __len = strlen(__old) + 1; + char* __sav = new(nothrow) char[__len]; + if (__sav) + { + memcpy(__sav, __old, __len); + setlocale(LC_ALL, "C"); + } + return __sav; + } } template<> @@ -60,11 +76,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const __c_locale&) throw() { // Assumes __s formatted for "C" locale. - char* __old = setlocale(LC_ALL, 0); - const size_t __len = strlen(__old) + 1; - char* __sav = new char[__len]; - memcpy(__sav, __old, __len); - setlocale(LC_ALL, "C"); + const char* __sav = __set_C_locale(); + if (!__sav) + { + __err = ios_base::failbit; + return; + } char* __sanity; bool __overflow = false; @@ -125,11 +142,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const __c_locale&) throw() { // Assumes __s formatted for "C" locale. - char* __old = setlocale(LC_ALL, 0); - const size_t __len = strlen(__old) + 1; - char* __sav = new char[__len]; - memcpy(__sav, __old, __len); - setlocale(LC_ALL, "C"); + const char* __sav = __set_C_locale(); + if (!__sav) + { + __err = ios_base::failbit; + return; + } char* __sanity; #if !__DBL_HAS_INFINITY__ @@ -170,11 +188,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ios_base::iostate& __err, const __c_locale&) throw() { // Assumes __s formatted for "C" locale. - char* __old = setlocale(LC_ALL, 0); - const size_t __len = strlen(__old) + 1; - char* __sav = new char[__len]; - memcpy(__sav, __old, __len); - setlocale(LC_ALL, "C"); + const char* __sav = __set_C_locale(); + if (!__sav) + { + __err = ios_base::failbit; + return; + } #if !__LDBL_HAS_INFINITY__ const _Save_errno __save_errno; --W/nzBZO5zC0uMSeA--