diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | intl/dcigettext.c | 54 | ||||
-rw-r--r-- | string/_strerror.c | 7 |
3 files changed, 52 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog index 77c7d23110..e1e2c4820e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-06-22 Ulrich Drepper <drepper@redhat.com> + + * intl/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-21 Ulrich Drepper <drepper@redhat.com> + + * string/_strerror.c (__strerror_r): Add __builtin_expect. + 2006-06-14 Jakub Jelinek <jakub@redhat.com> [BZ #2766] 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 */ diff --git a/string/_strerror.c b/string/_strerror.c index f6f16ff2af..cb5d9e3609 100644 --- a/string/_strerror.c +++ b/string/_strerror.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1991,93,95,96,97,98,2000,2002 Free Software Foundation, Inc. +/* Copyright (C) 1991,93,95,96,97,98,2000,2002,2006 + Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -35,8 +36,8 @@ char * __strerror_r (int errnum, char *buf, size_t buflen) { - if (errnum < 0 || errnum >= _sys_nerr_internal - || _sys_errlist_internal[errnum] == NULL) + if (__builtin_expect (errnum < 0 || errnum >= _sys_nerr_internal + || _sys_errlist_internal[errnum] == NULL, 0)) { /* Buffer we use to print the number in. For a maximum size for `int' of 8 bytes we never need more than 20 digits. */ |