[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: setlocale() and gettext() (Re: CVS dpkg flaws)



Previously Fumitoshi UKAI wrote:
> Because AFAIK gettext() converts message's encoding as locale configurations.
> If it fails, it'll output the characters as `?'.

Oh bugger,  so gettext has overloaded the meaning of LC_CTYPE to make
it also the indicater for the output character set. From the setlocale
manpage:

       LC_CTYPE
              for  regular expression matching, character classi
              fication,  conversion,  case-sensitive  comparison,
              and wide character functions.

I would consider this a very nasty bug in gettext

Can you try the (untested) patch below? That tries to work around this
problem by setting and resetting LC_CTYPE in the version comparison
routines.

Wichert.

diff -wur ../dpkg/ChangeLog dpkg/ChangeLog
--- ../dpkg/ChangeLog	Mon Dec 31 15:29:56 2001
+++ dpkg/ChangeLog	Mon Dec 31 15:48:16 2001
@@ -1,3 +1,10 @@
+Mon Dec 31 15:47:13 CET 2001 Wichert Akkerman <wakkerma@debian.org>
+
+  * lib/vercmp.c: Set and restore LC_CTYPE locale
+  * main/main.c, main/query.c, dselect/main.cc: do not force LC_CTYPE to
+    C since that breaks gettext (aargh), but trust the version comparison
+    routines to do the right thing instead.
+
 Mon Dec 31 15:25:46 CET 2001  Wichert Akkerman <wakkerma@debian.org>
 
   * scripts/dpkg-architecture.pl: fix syntax error
diff -wur ../dpkg/dselect/main.cc dpkg/dselect/main.cc
--- ../dpkg/dselect/main.cc	Tue Jul 31 12:34:08 2001
+++ dpkg/dselect/main.cc	Mon Dec 31 15:47:02 2001
@@ -470,7 +470,6 @@
   char *home, *homerc;
 
   setlocale(LC_ALL, "");
-  setlocale(LC_CTYPE, "C");
   bindtextdomain(PACKAGE, LOCALEDIR);
   textdomain(PACKAGE);
 
diff -wur ../dpkg/lib/vercmp.c dpkg/lib/vercmp.c
--- ../dpkg/lib/vercmp.c	Tue Jul 17 00:10:21 2001
+++ dpkg/lib/vercmp.c	Mon Dec 31 15:46:38 2001
@@ -115,19 +115,46 @@
                       const struct versionrevision *ref,
                       enum depverrel verrel) {
   int r;
-  if (verrel == dvr_none) return 1;
+  int ret;
+  char* pl;
+
+  pl=setlocale(LC_CTYPE, "C"); /* TODO: check for errors */
+  if (verrel == dvr_none) 
+    ret= 1;
+  else {
   r= versioncompare(it,ref);
   switch (verrel) {
-  case dvr_earlierequal:   return r <= 0;
-  case dvr_laterequal:     return r >= 0;
-  case dvr_earlierstrict:  return r < 0;
-  case dvr_laterstrict:    return r > 0;
-  case dvr_exact:          return r == 0;
-  default:                 internerr("unknown verrel");
+    case dvr_earlierequal:
+      ret= r <= 0;
+      break;
+    case dvr_laterequal:
+      ret= r >= 0;
+      break;
+    case dvr_earlierstrict:
+      ret= r < 0;
+      break;
+    case dvr_laterstrict:
+      ret= r > 0;
+      break;
+    case dvr_exact:
+      ret= r == 0;
+      break;
+    default:
+      internerr("unknown verrel");
+    }
   }
-  return 0;
+
+  setlocale(LC_CTYPE, pl); /* TODO: check for errors */
+  return ret;
 }
 
 int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
-  return versionsatisfied3(&it->version,&against->version,against->verrel);
+  int ret;
+  char* pl;
+
+  pl=setlocale(LC_CTYPE, "C"); /* TODO: check for errors */
+  ret= versionsatisfied3(&it->version,&against->version,against->verrel);
+  setlocale(LC_CTYPE, pl); /* TODO: check for errors */
+
+  return ret;
 }
diff -wur ../dpkg/main/main.c dpkg/main/main.c
--- ../dpkg/main/main.c	Sun Oct 21 23:55:23 2001
+++ dpkg/main/main.c	Mon Dec 31 15:46:48 2001
@@ -550,7 +550,6 @@
   char *home, *homerc;
 
   setlocale(LC_ALL, "");
-  setlocale(LC_CTYPE, "C");
   bindtextdomain(PACKAGE, LOCALEDIR);
   textdomain(PACKAGE);
 
diff -wur ../dpkg/main/query.c dpkg/main/query.c
--- ../dpkg/main/query.c	Wed Sep 12 16:54:41 2001
+++ dpkg/main/query.c	Mon Dec 31 15:47:04 2001
@@ -534,7 +534,6 @@
   static void (*actionfunction)(const char *const *argv);
 
   setlocale(LC_ALL, "");
-  setlocale(LC_CTYPE, "C");
   bindtextdomain(PACKAGE, LOCALEDIR);
   textdomain(PACKAGE);
 
-- 
  _________________________________________________________________
 /wichert@wiggy.net         This space intentionally left occupied \
| wichert@deephackmode.org            http://www.liacs.nl/~wichert/ |
| 1024D/2FA3BC2D 576E 100B 518D 2F16 36B0  2805 3CB8 9250 2FA3 BC2D |



Reply to: