Use __fxprintf instead of inline stream orientation test and two
authordrepper <drepper>
Tue, 19 Jul 2005 23:44:54 +0000 (23:44 +0000)
committerdrepper <drepper>
Tue, 19 Jul 2005 23:44:54 +0000 (23:44 +0000)
separate function calls.

Fix memory leak and possibly endless loop.

misc/error.c

index 2501583..5f00ae9 100644 (file)
@@ -1,7 +1,6 @@
 /* Error handler for noninteractive utilities
-   Copyright (C) 1990-1998, 2000-2003, 2004 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.  Its master source is NOT part of
-   the C library, however.  The master source lives in /gd/gnu/lib.
+   Copyright (C) 1990-1998, 2000-2004, 2005 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
    modify it under the terms of the GNU Lesser General Public
@@ -74,6 +73,7 @@ unsigned int error_message_count;
 
 # define program_name program_invocation_name
 # include <errno.h>
+# include <limits.h>
 # include <libio/libioP.h>
 
 /* In GNU libc we want do not want to use the common name `error' directly.
@@ -158,14 +158,10 @@ print_errno_message (int errnum)
 #endif
 
 #if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    {
-      __fwprintf (stderr, L": %s", s);
-      return;
-    }
-#endif
-
+  __fxprintf (NULL, ": %s", L": %s", s);
+#else
   fprintf (stderr, ": %s", s);
+#endif
 }
 
 #ifdef VA_START
@@ -182,14 +178,15 @@ error_tail (int status, int errnum, const char *message, va_list args)
       mbstate_t st;
       size_t res;
       const char *tmp;
+      bool use_malloc = false;
 
-      do
+      while (1)
        {
-         if (len < ALLOCA_LIMIT)
+         if (__libc_use_alloca (len * sizeof (wchar_t)))
            wmessage = (wchar_t *) alloca (len * sizeof (wchar_t));
          else
            {
-             if (wmessage != NULL && len / 2 < ALLOCA_LIMIT)
+             if (!use_malloc)
                wmessage = NULL;
 
              wchar_t *p = (wchar_t *) realloc (wmessage,
@@ -201,18 +198,38 @@ error_tail (int status, int errnum, const char *message, va_list args)
                  return;
                }
              wmessage = p;
+             use_malloc = true;
            }
 
          memset (&st, '\0', sizeof (st));
          tmp = message;
+
+         res = mbsrtowcs (wmessage, &tmp, len, &st);
+         if (res != len)
+           break;
+
+         if (__builtin_expect (len >= SIZE_MAX / 2, 0))
+           {
+             /* This reallyy should not happen if everything is fine.  */
+             res = (size_t) -1;
+             break;
+           }
+
+         len *= 2;
        }
-      while ((res = mbsrtowcs (wmessage, &tmp, len, &st)) == len);
 
       if (res == (size_t) -1)
-       /* The string cannot be converted.  */
-       wmessage = (wchar_t *) L"???";
+       {
+         /* The string cannot be converted.  */
+         if (use_malloc)
+           free (wmessage);
+         wmessage = (wchar_t *) L"???";
+       }
 
       __vfwprintf (stderr, wmessage, args);
+
+      if (use_malloc)
+       free (wmessage);
     }
   else
 #  endif
@@ -226,11 +243,10 @@ error_tail (int status, int errnum, const char *message, va_list args)
   if (errnum)
     print_errno_message (errnum);
 # if _LIBC
-  if (_IO_fwide (stderr, 0) > 0)
-    putwc (L'\n', stderr);
-  else
+  __fxprintf (NULL, "\n", L"\n");
+# else
+  putc ('\n', stderr);
 # endif
-    putc ('\n', stderr);
   fflush (stderr);
   if (status)
     exit (status);
@@ -275,11 +291,10 @@ error (status, errnum, message, va_alist)
   else
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s: ", program_name);
-      else
+      __fxprintf (NULL, "%s: ", L"%s: ", program_name);
+#else
+      fprintf (stderr, "%s: ", program_name);
 #endif
-       fprintf (stderr, "%s: ", program_name);
     }
 
 #ifdef VA_START
@@ -359,21 +374,19 @@ error_at_line (status, errnum, file_name, line_number, message, va_alist)
   else
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s: ", program_name);
-      else
+      __fxprintf (NULL, "%s:", L"%s: ", program_name);
+#else
+      fprintf (stderr, "%s:", program_name);
 #endif
-       fprintf (stderr, "%s:", program_name);
     }
 
   if (file_name != NULL)
     {
 #if _LIBC
-      if (_IO_fwide (stderr, 0) > 0)
-       __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
-      else
+      __fxprintf (NULL, "%s:%d: ", L"%s:%d: ", file_name, line_number);
+#else
+      fprintf (stderr, "%s:%d: ", file_name, line_number);
 #endif
-       fprintf (stderr, "%s:%d: ", file_name, line_number);
     }
 
 #ifdef VA_START