106 lines
3.6 KiB
Diff
106 lines
3.6 KiB
Diff
|
From 45cef8fb80248a6318f90219499ff2dbd953ae8c Mon Sep 17 00:00:00 2001
|
||
|
From: Karl Williamson <khw@cpan.org>
|
||
|
Date: Wed, 27 Nov 2019 19:15:11 -0700
|
||
|
Subject: [PATCH] PATCH: GH #17081: Workaround glibc bug with LC_MESSAGES
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
Please see the ticket for a full explanation. This bug has been
|
||
|
submitted to glibc, without any real action forthcoming so far.
|
||
|
|
||
|
This invalidates the message cache each time the locale of LC_MESSAGES
|
||
|
is changed, as glibc should be doing this when uselocale changes that,
|
||
|
but glibc fails to do so.
|
||
|
|
||
|
This patch is an extension to the one submitted by Niko Tyni++.
|
||
|
|
||
|
I don't know how to test it, since a test would rely on several
|
||
|
different locales in different languages being available, and that
|
||
|
depends on what's installed on the platform. I suppose that one could
|
||
|
go through the available locales, and try to find three with different
|
||
|
wording for the same message. Doing so however would trigger the bug,
|
||
|
and at the end, if we didn't get three that differed, we wouldn't know
|
||
|
we wouldn't know if it is because of the bug, or that they just didn't
|
||
|
exist on the system.
|
||
|
|
||
|
However, below is a perl program that demonstrated the patch worked.
|
||
|
You could adjust it to the available locales. The buggy code shows the
|
||
|
same text for all locales. The fixed shows three different languages.
|
||
|
|
||
|
use strict;
|
||
|
|
||
|
use Locale::gettext;
|
||
|
use POSIX;
|
||
|
|
||
|
$ENV{LANG} = 'C.UTF-8';
|
||
|
|
||
|
for my $lang (qw(fi_FI fr_FR en_US)) {
|
||
|
$ENV{LANGUAGE} = $lang;
|
||
|
setlocale(LC_MESSAGES, '');
|
||
|
my $d = Locale::gettext->domain("bash");
|
||
|
print $d->get('syntax error'), "\n";
|
||
|
}
|
||
|
|
||
|
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||
|
---
|
||
|
locale.c | 21 +++++++++++++++++++++
|
||
|
1 file changed, 21 insertions(+)
|
||
|
|
||
|
diff --git a/locale.c b/locale.c
|
||
|
index cdf125cee5..7ce7b3ed4c 100644
|
||
|
--- a/locale.c
|
||
|
+++ b/locale.c
|
||
|
@@ -402,6 +402,7 @@ S_category_name(const int category)
|
||
|
* known at compile time; "do_setlocale_r", not known until run time */
|
||
|
# define do_setlocale_c(cat, locale) my_setlocale(cat, locale)
|
||
|
# define do_setlocale_r(cat, locale) my_setlocale(cat, locale)
|
||
|
+# define FIX_GLIBC_LC_MESSAGES_BUG(i)
|
||
|
|
||
|
#else /* Below uses POSIX 2008 */
|
||
|
|
||
|
@@ -415,6 +416,22 @@ S_category_name(const int category)
|
||
|
emulate_setlocale(cat, locale, cat ## _INDEX, TRUE)
|
||
|
# define do_setlocale_r(cat, locale) emulate_setlocale(cat, locale, 0, FALSE)
|
||
|
|
||
|
+# if ! defined(__GLIBC__) || ! defined(USE_LOCALE_MESSAGES)
|
||
|
+
|
||
|
+# define FIX_GLIBC_LC_MESSAGES_BUG(i)
|
||
|
+
|
||
|
+# else /* Invalidate glibc cache of loaded translations, see [perl #134264] */
|
||
|
+
|
||
|
+# include <libintl.h>
|
||
|
+# define FIX_GLIBC_LC_MESSAGES_BUG(i) \
|
||
|
+ STMT_START { \
|
||
|
+ if ((i) == LC_MESSAGES_INDEX) { \
|
||
|
+ textdomain(textdomain(NULL)); \
|
||
|
+ } \
|
||
|
+ } STMT_END
|
||
|
+
|
||
|
+# endif
|
||
|
+
|
||
|
/* A third array, parallel to the ones above to map from category to its
|
||
|
* equivalent mask */
|
||
|
const int category_masks[] = {
|
||
|
@@ -1158,6 +1175,8 @@ S_emulate_setlocale(const int category,
|
||
|
Safefree(PL_curlocales[i]);
|
||
|
PL_curlocales[i] = savepv(locale);
|
||
|
}
|
||
|
+
|
||
|
+ FIX_GLIBC_LC_MESSAGES_BUG(LC_MESSAGES_INDEX);
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
@@ -1172,6 +1191,8 @@ S_emulate_setlocale(const int category,
|
||
|
/* Then update the category's record */
|
||
|
Safefree(PL_curlocales[index]);
|
||
|
PL_curlocales[index] = savepv(locale);
|
||
|
+
|
||
|
+ FIX_GLIBC_LC_MESSAGES_BUG(index);
|
||
|
}
|
||
|
|
||
|
# endif
|
||
|
--
|
||
|
2.21.1
|
||
|
|