From 352a432171a48c36b3e73dfb906a132bc10cde0b Mon Sep 17 00:00:00 2001 From: "Ignacio R. Morelle" Date: Mon, 31 Aug 2015 21:50:19 -0300 Subject: [PATCH] i18n: Skip and warn about textdomain names with a slash (bug #23839) boost::locale::generator::add_messages_domain() interprets the slash specially, interpreting everything after it as an encoding name. It's not clear to me why providing a textdomain with an erroneous name like this causes Boost.Locale to throw a boost::locale::conv exception (invalid_charset_error, apparently) when handling t_strings bound to completely different textdomain, but if we can avoid the issue altogether then that's good enough. Made the legacy implementation skip and warn about these names too even if bindtextdomain(3) says nothing about slashes having a meaning. --- changelog | 2 ++ players_changelog | 2 ++ src/gettext.cpp | 8 ++++++++ src/gettext_boost.cpp | 12 ++++++++++++ 4 files changed, 24 insertions(+) diff --git a/changelog b/changelog index c8c9ef7136ef..293f6ceb0f90 100644 --- a/changelog +++ b/changelog @@ -7,6 +7,8 @@ Version 1.12.4+dev: (units misssing fron carryover, units appering twice on map...) * Language and i18n: * Updated translations: French, Japanese, Latvian + * Fixed crashes during start-up on Windows resulting from add-ons containing + erroneous textdomain declarations (bug #23839). * Multiplayer: * Era names no longer support formatting markup in the game setup screen. * Made MP lobby filter option filter on eras and mods too (bug #22987). diff --git a/players_changelog b/players_changelog index f7d179253f82..2738bd7b96bf 100644 --- a/players_changelog +++ b/players_changelog @@ -5,6 +5,8 @@ changelog: https://github.com/wesnoth/wesnoth/blob/1.12/changelog Version 1.12.4+dev: * Language and i18n: * Updated translations: French, Japanese, Latvian. + * Fixed crashes during start-up on Windows resulting from add-ons containing + erroneous textdomain declarations (bug #23839). * User interface: * Force uniform font rendering settings across X11 and Apple OS X, avoiding diff --git a/src/gettext.cpp b/src/gettext.cpp index d736f52d585c..5addd5f49a5c 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -108,6 +108,14 @@ std::string dsngettext (const char * domainname, const char *singular, const cha void bind_textdomain(const char* domain, const char* directory, const char* encoding) { + if(domain != NULL && strchr(domain, '/') != NULL) { + // For compatibility with Boost.Locale implementation, which interprets + // slashes in domain names in a special fashion. + ERR_G << "illegal textdomain name '" << domain + << "', skipping textdomain\n"; + return; + } + if(directory != NULL) bindtextdomain(domain, directory); if(encoding != NULL) diff --git a/src/gettext_boost.cpp b/src/gettext_boost.cpp index 6be880c36466..a36c51e41193 100644 --- a/src/gettext_boost.cpp +++ b/src/gettext_boost.cpp @@ -96,6 +96,18 @@ namespace { return; } + + if(domain.find('/') != std::string::npos) + { + // Forward slash has a specific meaning in Boost.Locale domain + // names, specifying the encoding. We use UTF-8 for everything + // so we can't possibly support that, and odds are it's a user + // mistake (as in bug #23839). + ERR_G << "illegal textdomain name '" << domain + << "', skipping textdomain\n"; + return; + } + generator_.add_messages_domain(domain); loaded_domains_.insert(domain); }