about summary refs log tree commit diff
path: root/intl
diff options
context:
space:
mode:
authorArjun Shankar <arjun@redhat.com>2020-09-25 14:47:06 +0200
committerArjun Shankar <arjun@redhat.com>2020-09-25 14:47:06 +0200
commit7d4ec75e111291851620c6aa2c4460647b7fd50d (patch)
tree1692804299aa1634e52cd2cf021ab4dbce2b01c6 /intl
parent06e95b93f0bb5943363ad3dcf0cd0fb9d8613b61 (diff)
downloadglibc-7d4ec75e111291851620c6aa2c4460647b7fd50d.tar.gz
glibc-7d4ec75e111291851620c6aa2c4460647b7fd50d.tar.xz
glibc-7d4ec75e111291851620c6aa2c4460647b7fd50d.zip
intl: Handle translation output codesets with suffixes [BZ #26383]
Commit 91927b7c7643 (Rewrite iconv option parsing [BZ #19519]) did not
handle cases where the output codeset for translations (via the `gettext'
family of functions) might have a caller specified encoding suffix such as
TRANSLIT or IGNORE.  This led to a regression where translations did not
work when the codeset had a suffix.

This commit fixes the above issue by parsing any suffixes passed to
__dcigettext and adds two new test-cases to intl/tst-codeset.c to
verify correct behaviour.  The iconv-internal function __gconv_create_spec
and the static iconv-internal function gconv_destroy_spec are now visible
internally within glibc and used in intl/dcigettext.c.
Diffstat (limited to 'intl')
-rw-r--r--intl/dcigettext.c17
-rw-r--r--intl/tst-codeset.c34
2 files changed, 24 insertions, 27 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c
index 2e7c662bc7..bd332e71da 100644
--- a/intl/dcigettext.c
+++ b/intl/dcigettext.c
@@ -1120,15 +1120,18 @@ _nl_find_msg (struct loaded_l10nfile *domain_file,
 
 # ifdef _LIBC
 
-		      struct gconv_spec conv_spec
-		        = { .fromcode = norm_add_slashes (charset, ""),
-		            .tocode = norm_add_slashes (outcharset, ""),
-		            /* We always want to use transliteration.  */
-		            .translit = true,
-		            .ignore = false
-		          };
+		      struct gconv_spec conv_spec;
+
+                      __gconv_create_spec (&conv_spec, charset, outcharset);
+
+		      /* We always want to use transliteration.  */
+                      conv_spec.translit = true;
+
 		      int r = __gconv_open (&conv_spec, &convd->conv,
 		                            GCONV_AVOID_NOCONV);
+
+                      __gconv_destroy_spec (&conv_spec);
+
 		      if (__builtin_expect (r != __GCONV_OK, 0))
 			{
 			  /* If the output encoding is the same there is
diff --git a/intl/tst-codeset.c b/intl/tst-codeset.c
index fd70432eca..e9f6e5e09f 100644
--- a/intl/tst-codeset.c
+++ b/intl/tst-codeset.c
@@ -22,13 +22,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <support/check.h>
 
 static int
 do_test (void)
 {
-  char *s;
-  int result = 0;
-
   unsetenv ("LANGUAGE");
   unsetenv ("OUTPUT_CHARSET");
   setlocale (LC_ALL, "de_DE.ISO-8859-1");
@@ -36,25 +34,21 @@ do_test (void)
   bindtextdomain ("codeset", OBJPFX "domaindir");
 
   /* Here we expect output in ISO-8859-1.  */
-  s = gettext ("cheese");
-  if (strcmp (s, "K\344se"))
-    {
-      printf ("call 1 returned: %s\n", s);
-      result = 1;
-    }
+  TEST_COMPARE_STRING (gettext ("cheese"), "K\344se");
 
+  /* Here we expect output in UTF-8.  */
   bind_textdomain_codeset ("codeset", "UTF-8");
+  TEST_COMPARE_STRING (gettext ("cheese"), "K\303\244se");
 
-  /* Here we expect output in UTF-8.  */
-  s = gettext ("cheese");
-  if (strcmp (s, "K\303\244se"))
-    {
-      printf ("call 2 returned: %s\n", s);
-      result = 1;
-    }
-
-  return result;
+  /* `a with umlaut' is transliterated to `ae'.  */
+  bind_textdomain_codeset ("codeset", "ASCII//TRANSLIT");
+  TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
+
+  /* Transliteration also works by default even if not set.  */
+  bind_textdomain_codeset ("codeset", "ASCII");
+  TEST_COMPARE_STRING (gettext ("cheese"), "Kaese");
+
+  return 0;
 }
 
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
+#include <support/test-driver.c>