diff options
Diffstat (limited to 'intl')
-rw-r--r-- | intl/dcigettext.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/intl/dcigettext.c b/intl/dcigettext.c index b56196ccbe..cb2b1813a7 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -611,6 +611,7 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) if (strcmp (single_locale, "C") == 0 || strcmp (single_locale, "POSIX") == 0) { + no_translation: FREE_BLOCKS (block_list); __libc_rwlock_unlock (_nl_state_lock); __set_errno (saved_errno); @@ -646,6 +647,12 @@ DCIGETTEXT (domainname, msgid1, msgid2, plural, n, category) } } + /* 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)) + goto no_translation; + if (retval != NULL) { /* Found the translation of MSGID1 in domain DOMAIN: @@ -865,21 +872,22 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) encoding. */ struct converted_domain *new_conversions = (struct converted_domain *) - (domain->conversions != NULL - ? realloc (domain->conversions, - (nconversions + 1) * sizeof (struct converted_domain)) - : malloc ((nconversions + 1) * sizeof (struct converted_domain))); + realloc (domain->conversions, + (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; @@ -933,10 +941,18 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) /* 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, @@ -1000,8 +1016,9 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) 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) { @@ -1049,8 +1066,10 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) 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; @@ -1076,7 +1095,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) if (errno != E2BIG) { __libc_lock_unlock (lock); - goto converted; + return NULL; } # endif # endif @@ -1112,7 +1131,7 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) freemem = NULL; freemem_size = 0; __libc_lock_unlock (lock); - goto converted; + return (char *) -1; } # ifdef _LIBC @@ -1151,7 +1170,6 @@ _nl_find_msg (domain_file, domainbinding, msgid, convert, lengthp) } } - converted: /* The result string is converted. */ #endif /* _LIBC || HAVE_ICONV */ |