diff options
author | Bruno Haible <bruno@clisp.org> | 2006-07-03 16:12:53 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2009-06-23 12:13:29 +0200 |
commit | 82462ff8776d5d0b497b5eb489dfce173f411a79 (patch) | |
tree | a13004d9b8bcd32d96137c9fd306ab1e6ab2481b | |
parent | d46a21dc557abf3241bac0910f4e1d5a568fbe86 (diff) | |
download | external_gettext-82462ff8776d5d0b497b5eb489dfce173f411a79.zip external_gettext-82462ff8776d5d0b497b5eb489dfce173f411a79.tar.gz external_gettext-82462ff8776d5d0b497b5eb489dfce173f411a79.tar.bz2 |
Never return translations in the wrong encoding. From glibc.
-rw-r--r-- | gettext-runtime/intl/ChangeLog | 8 | ||||
-rw-r--r-- | gettext-runtime/intl/dcigettext.c | 52 |
2 files changed, 46 insertions, 14 deletions
diff --git a/gettext-runtime/intl/ChangeLog b/gettext-runtime/intl/ChangeLog index a620c53..55a6567 100644 --- a/gettext-runtime/intl/ChangeLog +++ b/gettext-runtime/intl/ChangeLog @@ -1,3 +1,11 @@ +2006-06-22 Ulrich Drepper <drepper@redhat.com> + + * dcigettext.c (DCIGETTEXT): If _nl_find_msg returns -1 don't look + further, return original strings. + (_nl_find_msg): Do not return found translation if the conversion + failed. Either signal the string is unusable or that something went + wrong and the original should be used. + 2006-06-23 Bruno Haible <bruno@clisp.org> * l10nflist.c (__argz_count, __argz_stringify, __argz_next): Define diff --git a/gettext-runtime/intl/dcigettext.c b/gettext-runtime/intl/dcigettext.c index 456ff7f..01f9638 100644 --- a/gettext-runtime/intl/dcigettext.c +++ b/gettext-runtime/intl/dcigettext.c @@ -759,6 +759,12 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, } } + /* Returning -1 means that some resource problem exists + (likely memory) and that the strings could not be + converted. Return the original strings. */ + if (__builtin_expect (retval == (char *) -1, 0)) + break; + if (retval != NULL) { /* Found the translation of MSGID1 in domain DOMAIN: @@ -863,6 +869,11 @@ DCIGETTEXT (const char *domainname, const char *msgid1, const char *msgid2, } +/* Look up the translation of msgid within DOMAIN_FILE and DOMAINBINDING. + Return it if found. Return NULL if not found or in case of a conversion + failure (problem in the particular message catalog). Return (char *) -1 + in case of a memory allocation failure during conversion (only if + ENCODING != NULL resp. CONVERT == true). */ char * internal_function #ifdef IN_LIBGLOCALE @@ -1020,15 +1031,18 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, : malloc ((nconversions + 1) * sizeof (struct converted_domain))); if (__builtin_expect (new_conversions == NULL, 0)) - /* Nothing we can do, no more memory. */ - goto converted; + /* Nothing we can do, no more memory. We cannot use the + translation because it might be encoded incorrectly. */ + return (char *) -1; + domain->conversions = new_conversions; /* Copy the 'encoding' string to permanent storage. */ encoding = strdup (encoding); if (__builtin_expect (encoding == NULL, 0)) - /* Nothing we can do, no more memory. */ - goto converted; + /* Nothing we can do, no more memory. We cannot use the + translation because it might be encoded incorrectly. */ + return (char *) -1; convd = &new_conversions[nconversions]; convd->encoding = encoding; @@ -1088,10 +1102,18 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, /* We always want to use transliteration. */ outcharset = norm_add_slashes (outcharset, "TRANSLIT"); charset = norm_add_slashes (charset, ""); - if (__gconv_open (outcharset, charset, &convd->conv, - GCONV_AVOID_NOCONV) - != __GCONV_OK) - convd->conv = (__gconv_t) -1; + int r = __gconv_open (outcharset, charset, &convd->conv, + GCONV_AVOID_NOCONV); + if (__builtin_expect (r != __GCONV_OK, 0)) + { + /* If the output encoding is the same there is + nothing to do. Otherwise do not use the + translation at all. */ + if (__builtin_expect (r != __GCONV_NOCONV, 1)) + return NULL; + + convd->conv = (__gconv_t) -1; + } # else # if HAVE_ICONV /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, @@ -1155,8 +1177,9 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, convd->conv_tab = (char **) -1; if (__builtin_expect (convd->conv_tab == (char **) -1, 0)) - /* Nothing we can do, no more memory. */ - goto converted; + /* Nothing we can do, no more memory. We cannot use the + translation because it might be encoded incorrectly. */ + return (char *) -1; if (convd->conv_tab[act] == NULL) { @@ -1204,8 +1227,10 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, if (res != __GCONV_FULL_OUTPUT) { + /* We should not use the translation at all, it + is incorrectly encoded. */ __libc_lock_unlock (lock); - goto converted; + return NULL; } inbuf = (const unsigned char *) result; @@ -1231,7 +1256,7 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, if (errno != E2BIG) { __libc_lock_unlock (lock); - goto converted; + return NULL; } # endif # endif @@ -1267,7 +1292,7 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, freemem = NULL; freemem_size = 0; __libc_lock_unlock (lock); - goto converted; + return (char *) -1; } # ifdef _LIBC @@ -1306,7 +1331,6 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, } } - converted: /* The result string is converted. */ #endif /* _LIBC || HAVE_ICONV */ |