Fix T88877: 2.93: Crash on recent OSX with a non-English locale.

Looks like OSX changed the default format of its locale, which is not
valid anymore for gettext/boost::locale.

Solution based on investigations and patch by Kieun Mun (@kieuns), with
some further tweaks by Ankit Meel (@ankitm), many thanks.

Also add an exception catcher on `std::runtime_error` in
`bl_locale_set()`, since in OSX catching the ancestor `std::exception`
does not work with `boost::locale::conv::conversion_error` and the like
for some reasons.

Reviewed By: #platform_macos, brecht

Maniphest Tasks: T88877

Differential Revision: https://developer.blender.org/D13019
This commit is contained in:
Ankit Meel 2021-10-29 10:11:04 +02:00 committed by Philipp Oeser
parent 77104bf318
commit 8e237d83f2
Notes: blender-bot 2023-02-14 08:28:46 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93
Referenced by issue #88449, Blender LTS: Maintenance Task 2.93
Referenced by issue #88877, 2.93: Crash on system with a non-English locale
2 changed files with 18 additions and 1 deletions

View File

@ -117,6 +117,13 @@ void bl_locale_set(const char *locale)
#undef LOCALE_INFO
}
// Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
// like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
// not caught by their ancestor `std::exception`. See
// https://developer.blender.org/T88877#1177108 .
catch (std::runtime_error const &e) {
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
}
catch (std::exception const &e) {
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
}

View File

@ -14,7 +14,17 @@ const char *osx_user_locale()
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
NSLocale *myNSLocale = (NSLocale *)myCFLocale;
[myNSLocale autorelease];
NSString *nsIdentifier = [myNSLocale localeIdentifier];
// This produces gettext-invalid locale in recent macOS versions (11.4),
// like `ko-Kore_KR` instead of `ko_KR`. See T88877.
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
const NSString *nsIdentifier = [myNSLocale languageCode];
const NSString *const nsIdentifier_country = [myNSLocale countryCode];
if ([nsIdentifier length] != 0 && [nsIdentifier_country length] != 0) {
nsIdentifier = [NSString stringWithFormat:@"%@_%@", nsIdentifier, nsIdentifier_country];
}
user_locale = ::strdup([nsIdentifier UTF8String]);
[pool drain];