aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--intl/dcigettext.c54
-rw-r--r--string/_strerror.c7
3 files changed, 52 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 77c7d23..e1e2c48 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 b56196c..cb2b181 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 f6f16ff..cb5d9e3 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. */