Control: forwarded -1 https://rt.perl.org/Public/Bug/Display.html?id=134264

On Thu, Jul 04, 2019 at 08:04:52PM +0300, Niko Tyni wrote:

> > Starting with Perl 5.28, Perl uses POSIX 2008 thread-safe locales, so
> > it calls uselocale(3) underneath when the Perl side POSIX::setlocale()
> > function is invoked.
> > 
> > This makes gettext think that a translation for the new locale is already
> > loaded when it really corresponds to the old locale.
> > 
> > While this is a 5.28 regression for Perl, it's not clear to me
> > whether glibc is working correctly here or not.

This is now reported upstream as [perl #134264].

I'm attaching an updated test case in C, which just sets LANG at startup
(as glibc won't look at LANGUAGE if the locale is totally unset / set to
"C".)

I'm also attaching a minimal Perl test case using Locale::gettext that
demonstrates the 5.26 / 5.28 difference.
-- 
Niko
#include <stdio.h>
#include <stdlib.h>

#include <libintl.h>
#include <locale.h>

/* https://bugs.debian.org/931139 */

int main(int argc, char **argv)
{
  locale_t loc;
  int i=0;

  /* The C locale is special cased in glibc to not look at LANGUAGE
     so we set C.UTF-8 as the base locale instead */
  setenv("LANG", "C.UTF-8", 1);

  char *locales[] = { "fi_FI", "fr_FR", "en_US", NULL };

  for (i=0; locales[i] != NULL; i++) {
    setenv("LANGUAGE", locales[i], 1);
    if (argc > 1) {
        /* "Old" behaviour, no bug */
        setlocale(LC_MESSAGES, "");
    } else {
        /* "New" behaviour, first translation stays cached */
        loc = newlocale(LC_MESSAGES_MASK, "", (locale_t) 0);
        if (loc == (locale_t) 0)
            perror("newlocale");
        uselocale(loc);
    }
    printf("%s\n", dgettext("bash", "syntax error"));
  }

  return EXIT_SUCCESS;
}
#!/usr/bin/perl -w
use strict;

use Locale::gettext;
use POSIX;

# The C locale is special cased in glibc to not look at LANGUAGE
# so we set C.UTF-8 as the base locale instead
$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";
}

Reply via email to