From: Vadim Zeitlin Date: Wed, 6 Apr 2011 14:37:27 +0000 (+0000) Subject: Fix incorrect use of setlocale() in wxLocale::IsAvailable(). X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/fd1c361c33b5fc259d9c62e7c816e753cc1b1dd3 Fix incorrect use of setlocale() in wxLocale::IsAvailable(). The return value of setlocale() was used incorrectly in this code: it represents the newly set locale and not the previously active one so we didn't actually restore the original locale before. Fix the code and check that we do actually restore the locale in a new unit test for it. See #13117. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67405 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 575900d041..9b38ffbf14 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1045,16 +1045,21 @@ bool wxLocale::IsAvailable(int lang) #elif defined(__UNIX__) // Test if setting the locale works, then set it back. - const char *oldLocale = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName); - if ( !oldLocale ) - { - // Some C libraries don't like xx_YY form and require xx only - oldLocale = wxSetlocaleTryUTF8(LC_ALL, ExtractLang(info->CanonicalName)); - if ( !oldLocale ) - return false; - } + char * const oldLocale = wxStrdupA(setlocale(LC_ALL, NULL)); + + // Some platforms don't like xx_YY form and require xx only so test for + // it too. + const bool + available = wxSetlocaleTryUTF8(LC_ALL, info->CanonicalName) || + wxSetlocaleTryUTF8(LC_ALL, ExtractLang(info->CanonicalName)); + // restore the original locale wxSetlocale(LC_ALL, oldLocale); + + free(oldLocale); + + if ( !available ) + return false; #endif return true; diff --git a/tests/intl/intltest.cpp b/tests/intl/intltest.cpp index 02b98472ed..3308e4e210 100644 --- a/tests/intl/intltest.cpp +++ b/tests/intl/intltest.cpp @@ -43,12 +43,14 @@ private: CPPUNIT_TEST( Headers ); CPPUNIT_TEST( DateTimeFmtFrench ); CPPUNIT_TEST( DateTimeFmtC ); + CPPUNIT_TEST( IsAvailable ); CPPUNIT_TEST_SUITE_END(); void Domain(); void Headers(); void DateTimeFmtFrench(); void DateTimeFmtC(); + void IsAvailable(); wxLocale *m_locale; @@ -204,4 +206,14 @@ void IntlTestCase::DateTimeFmtC() m_locale->GetInfo(wxLOCALE_TIME_FMT) ); } +void IntlTestCase::IsAvailable() +{ + const wxString origLocale(setlocale(LC_ALL, NULL)); + + // Calling IsAvailable() shouldn't change the locale. + wxLocale::IsAvailable(wxLANGUAGE_ENGLISH); + + CPPUNIT_ASSERT_EQUAL( origLocale, setlocale(LC_ALL, NULL) ); +} + #endif // wxUSE_INTL