Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libaegisub/common/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,13 @@ void InitLocale() {
// FIXME: Should the ICU locale also be forced to en_US here?
if (result != std::codecvt_base::ok)
locale = boost::locale::generator().generate("en_US.UTF-8");

// Use the standard library's number parsing and formatting rather than
// Boost.Locale's, which nothing relies on. Boost.Locale's facets fall back
// to std::num_get code inlined from the SDK's libc++ headers, and with
// newer SDKs that code overflows a stack buffer when it calls into an
// older system libc++ (e.g. on macOS 13).
locale = std::locale(locale, std::locale::classic(), std::locale::numeric);
std::locale::global(locale);
}
} // namespace util
Expand Down
10 changes: 10 additions & 0 deletions tests/tests/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

#include <main.h>

#include <locale>
#include <typeinfo>

class lagi_util : public libagi { };

namespace agi {
Expand All @@ -42,4 +45,11 @@ TEST(lagi_util, try_parse_int) {
EXPECT_EQ(1.0, i);
}

TEST(lagi_util, init_locale_uses_std_numeric_facets) {
// Boost.Locale's numeric facets crash on older macOS when built with a
// newer SDK (#733), so InitLocale must not install them
EXPECT_EQ(typeid(std::num_get<char>), typeid(std::use_facet<std::num_get<char>>(std::locale())));
EXPECT_EQ(typeid(std::num_put<char>), typeid(std::use_facet<std::num_put<char>>(std::locale())));
}

}
Loading