* intl/dcigettext.c (DCIGETTEXT): If _nl_find_msg returns -1 don't
authorUlrich Drepper <drepper@redhat.com>
Thu, 22 Jun 2006 23:59:32 +0000 (23:59 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 22 Jun 2006 23:59:32 +0000 (23:59 +0000)
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.

ChangeLog
intl/dcigettext.c
string/_strerror.c

index 77c7d23..e1e2c48 100644 (file)
--- 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]
index b56196c..cb2b181 100644 (file)
@@ -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 */
index f6f16ff..cb5d9e3 100644 (file)
@@ -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.  */