LC_CTYPE-Locale auf eine UTF-8-Locale setzen
authorMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 26 Nov 2018 14:20:47 +0000 (15:20 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Mon, 26 Nov 2018 14:20:47 +0000 (15:20 +0100)
Beim Starten des Perl-Interpreters wird die Locale anhand von
Umgebungsvariablen wie `LC_CTYPE`, `LC_ALL` und `LANG`
gesetzt. Unter (F)CGI sind diese normalerweise leer, wodurch als
Locale die POSIX-Locale (`C`) gewählt wird — und die hat nur ASCII als
Zeichensatz.

Die iconv-Funktion scheint nun nicht transliterieren zu können, wenn
ASCII als Zeichensatz ausgewählt ist. Sie macht dann z.B. aus `ć` ein
`?` anstelle von `c`.

Beim Start der Programme wird nun `LC_CTYPE` auf eine sinnvoller
Locale gesetzt. Dies ist `de_DE.UTF-8` oder `en_US.UTF-8`, falls
erstere nicht verfügbar ist. Die Sprache ist hierbei irrelevant, da
nur `LC_CTYPE` gesetzt wird und und nicht z.B. auch `LC_MESSAGES` oder
`LC_TIME`.

Dies ist Voraussetzung dafür, das #348 gefixt werden kann.

SL/Dispatcher.pm
scripts/task_server.pl

index 6b7cf63..abc5ec8 100644 (file)
@@ -18,6 +18,7 @@ use File::Basename;
 use IO::File;
 use List::MoreUtils qw(all);
 use List::Util qw(first);
+use POSIX qw(setlocale);
 use SL::ArchiveZipFixes;
 use SL::Auth;
 use SL::Dispatcher::AuthHandler;
@@ -51,6 +52,11 @@ sub new {
 
   SL::ArchiveZipFixes->apply_fixes;
 
+  # Initialize character type locale to be UTF-8 instead of C:
+  foreach my $locale (qw(de_DE.UTF-8 en_US.UTF-8)) {
+    last if setlocale('LC_CTYPE', $locale);
+  }
+
   return $self;
 }
 
index 07cc53e..fcdef49 100755 (executable)
@@ -21,7 +21,7 @@ use English qw(-no_match_vars);
 use File::Spec;
 use List::MoreUtils qw(any);
 use List::Util qw(first);
-use POSIX qw(setuid setgid);
+use POSIX qw(setlocale setuid setgid);
 use SL::Auth;
 use SL::DBUpgrade2;
 use SL::DB::AuthClient;
@@ -186,6 +186,11 @@ sub notify_on_failure {
 sub gd_preconfig {
   my $self = shift;
 
+  # Initialize character type locale to be UTF-8 instead of C:
+  foreach my $locale (qw(de_DE.UTF-8 en_US.UTF-8)) {
+    last if setlocale('LC_CTYPE', $locale);
+  }
+
   SL::LxOfficeConf->read($self->{configfile});
 
   die "Missing section [task_server] in config file" unless $lx_office_conf{task_server};