bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug-gnulib] Re: quotearg.c can clobber errno [was: fileutils 4.1.9: inc


From: Paul Eggert
Subject: [Bug-gnulib] Re: quotearg.c can clobber errno [was: fileutils 4.1.9: incorrect error message
Date: Fri, 22 Nov 2002 22:52:15 -0800 (PST)

> From: Jim Meyering <address@hidden>
> Date: Tue, 19 Nov 2002 11:24:04 +0100

> Here's a suggested patch for the problem Tim forwarded below:
> 
>       * quotearg.c (quotearg_buffer_restyled): If mbrtowc returns
>       `(size_t) -1' (at which point it would also set errno to EILSEQ),
>       then restore errno to its previous value.

Thanks for forwarding that.  The fix is incomplete, though, as errno
isn't preserved in some other cases.

I fixed the other cases, and merged all the other quotearg.c and
quotearg.h fixes that have been piling up in Bison and tar's copy
(e.g., trigraphs were not quoted properly), and while I was at it I
removed the old K&R cruft.  I installed the following patch into
gnulib, so you can sync at your leisure.

2002-11-22  Paul Eggert  <address@hidden>

        * quotearg.h: Allow multiple inclusion by surrounding with
        "#ifndef QUOTEARG_H_".  Include <stddef.h>, for size_t,
        so that we can be included first.
        (PARAMS): Remove; we now assume C89 or later.  All uses removed.
        * quotearg.c: Include quotearg.h immediately after config.h.
        No need to include stddef.h or sys/types.h any more.
        Surround local include files with "", not "<>".
        Assume HAVE_LIMITS_H unconditionally, as we assume C89.
        Similarly, assume HAVE_C_BACKSLASH_A, CHAR_BIT, UCHAR_MAX, UINT_MAX,
        HAVE_STDLIB_H, HAVE_STRING_H, STDC_HEADERS.
        (HAVE_MBSINIT): Undef if !HAVE_MBRTOWC.
        (mbsinit): Define to 1 if !defined mbsinit && !HAVE_MBSINIT.
        (ISPRINT): Remove; no longer needed now that we assume C89.

        (clone_quoting_options, quotearg_buffer, quotearg_n_options):
        Preserve errno.

        (quotearg_buffer_restyled, quotearg_n, quotearg_n_style,
        quotearg_char): Use SIZE_MAX rather than
        (size_t) -1 when we are talking about "infinity".

        (quotearg_buffer_restyled): Fix bug when quoting trigraphs.

Index: lib/quotearg.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/quotearg.c,v
retrieving revision 1.37
diff -p -u -r1.37 quotearg.c
--- lib/quotearg.c      5 Nov 2002 21:45:29 -0000       1.37
+++ lib/quotearg.c      23 Nov 2002 06:43:58 -0000
@@ -21,49 +21,20 @@
 # include <config.h>
 #endif
 
-#if HAVE_STDDEF_H
-# include <stddef.h>  /* For the definition of size_t on windows w/MSVC.  */
-#endif
-#include <sys/types.h>
-#include <quotearg.h>
-#include <xalloc.h>
+#include "quotearg.h"
+
+#include "xalloc.h"
 
 #include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #define N_(msgid) msgid
 
-#if HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#ifndef CHAR_BIT
-# define CHAR_BIT 8
-#endif
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-#ifndef UCHAR_MAX
-# define UCHAR_MAX ((unsigned char) -1)
-#endif
-#ifndef UINT_MAX
-# define UINT_MAX ((unsigned int) -1)
-#endif
-
-#if HAVE_C_BACKSLASH_A
-# define ALERT_CHAR '\a'
-#else
-# define ALERT_CHAR '\7'
-#endif
-
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#if HAVE_STRING_H
-# include <string.h>
-#endif
-
 #if HAVE_WCHAR_H
 
 /* BSD/OS 4.1 wchar.h requires FILE and struct tm to be declared.  */
@@ -80,8 +51,12 @@
 # undef MB_CUR_MAX
 # define MB_CUR_MAX 1
 # define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
+# define iswprint(wc) isprint ((unsigned char) (wc))
+# undef HAVE_MBSINIT
+#endif
+
+#if !defined mbsinit && !HAVE_MBSINIT
 # define mbsinit(ps) 1
-# define iswprint(wc) ISPRINT ((unsigned char) (wc))
 #endif
 
 #ifndef iswprint
@@ -93,17 +68,11 @@
 # endif
 #endif
 
-#define INT_BITS (sizeof (int) * CHAR_BIT)
-
-#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii(c)
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
 #endif
 
-/* Undefine to protect against the definition in wctype.h of solaris2.6.   */
-#undef ISPRINT
-#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
+#define INT_BITS (sizeof (int) * CHAR_BIT)
 
 struct quoting_options
 {
@@ -149,9 +118,10 @@ static struct quoting_options default_qu
 struct quoting_options *
 clone_quoting_options (struct quoting_options *o)
 {
-  struct quoting_options *p
-    = (struct quoting_options *) xmalloc (sizeof (struct quoting_options));
+  int e = errno;
+  struct quoting_options *p = xmalloc (sizeof *p);
   *p = *(o ? o : &default_quoting_options);
+  errno = e;
   return p;
 }
 
@@ -283,7 +253,7 @@ quotearg_buffer_restyled (char *buffer, 
       break;
     }
 
-  for (i = 0;  ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize);  
i++)
+  for (i = 0;  ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize);  i++)
     {
       unsigned char c;
       unsigned char esc;
@@ -322,8 +292,8 @@ quotearg_buffer_restyled (char *buffer, 
                  case '<': case '=': case '>':
                    /* Escape the second '?' in what would otherwise be
                       a trigraph.  */
-                   i += 2;
                    c = arg[i + 2];
+                   i += 2;
                    STORE ('?');
                    STORE ('\\');
                    STORE ('?');
@@ -336,7 +306,7 @@ quotearg_buffer_restyled (char *buffer, 
            }
          break;
 
-       case ALERT_CHAR: esc = 'a'; goto c_escape;
+       case '\a': esc = 'a'; goto c_escape;
        case '\b': esc = 'b'; goto c_escape;
        case '\f': esc = 'f'; goto c_escape;
        case '\n': esc = 'n'; goto c_and_shell_escape;
@@ -424,7 +394,7 @@ quotearg_buffer_restyled (char *buffer, 
            if (unibyte_locale)
              {
                m = 1;
-               printable = ISPRINT (c);
+               printable = isprint (c);
              }
            else
              {
@@ -433,7 +403,7 @@ quotearg_buffer_restyled (char *buffer, 
 
                m = 0;
                printable = 1;
-               if (argsize == (size_t) -1)
+               if (argsize == SIZE_MAX)
                  argsize = strlen (arg);
 
                do
@@ -529,8 +499,11 @@ quotearg_buffer (char *buffer, size_t bu
                 struct quoting_options const *o)
 {
   struct quoting_options const *p = o ? o : &default_quoting_options;
-  return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
-                                  p->style, p);
+  int e = errno;
+  size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
+                                      p->style, p);
+  errno = e;
+  return r;
 }
 
 /* Use storage slot N to return a quoted version of argument ARG.
@@ -544,6 +517,8 @@ static char *
 quotearg_n_options (int n, char const *arg, size_t argsize,
                    struct quoting_options const *options)
 {
+  int e = errno;
+
   /* Preallocate a slot 0 buffer, so that the caller can always quote
      one small component of a "memory exhausted" message in slot 0.  */
   static char slot0[256];
@@ -571,10 +546,10 @@ quotearg_n_options (int n, char const *a
 
       if (slotvec == &slotvec0)
        {
-         slotvec = (struct slotvec *) xmalloc (sizeof *slotvec);
+         slotvec = xmalloc (sizeof *slotvec);
          *slotvec = slotvec0;
        }
-      slotvec = (struct slotvec *) xrealloc (slotvec, s);
+      slotvec = xrealloc (slotvec, s);
       memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec);
       nslots = n1;
     }
@@ -591,6 +566,7 @@ quotearg_n_options (int n, char const *a
        quotearg_buffer (val, size, arg, argsize, options);
       }
 
+    errno = e;
     return val;
   }
 }
@@ -598,7 +574,7 @@ quotearg_n_options (int n, char const *a
 char *
 quotearg_n (int n, char const *arg)
 {
-  return quotearg_n_options (n, arg, (size_t) -1, &default_quoting_options);
+  return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
 }
 
 char *
@@ -621,7 +597,7 @@ char *
 quotearg_n_style (int n, enum quoting_style s, char const *arg)
 {
   struct quoting_options const o = quoting_options_from_style (s);
-  return quotearg_n_options (n, arg, (size_t) -1, &o);
+  return quotearg_n_options (n, arg, SIZE_MAX, &o);
 }
 
 char *
@@ -644,7 +620,7 @@ quotearg_char (char const *arg, char ch)
   struct quoting_options options;
   options = default_quoting_options;
   set_char_quoting (&options, ch, 1);
-  return quotearg_n_options (0, arg, (size_t) -1, &options);
+  return quotearg_n_options (0, arg, SIZE_MAX, &options);
 }
 
 char *
Index: lib/quotearg.h
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/quotearg.h,v
retrieving revision 1.8
diff -p -u -r1.8 quotearg.h
--- lib/quotearg.h      22 Jan 2002 08:02:43 -0000      1.8
+++ lib/quotearg.h      23 Nov 2002 06:43:58 -0000
@@ -1,5 +1,7 @@
 /* quotearg.h - quote arguments for output
-   Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+
+   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -17,6 +19,11 @@
 
 /* Written by Paul Eggert <address@hidden> */
 
+#ifndef QUOTEARG_H_
+# define QUOTEARG_H_ 1
+
+# include <stddef.h>
+
 /* Basic quoting styles.  */
 enum quoting_style
   {
@@ -30,9 +37,9 @@ enum quoting_style
   };
 
 /* For now, --quoting-style=literal is the default, but this may change.  */
-#ifndef DEFAULT_QUOTING_STYLE
-# define DEFAULT_QUOTING_STYLE literal_quoting_style
-#endif
+# ifndef DEFAULT_QUOTING_STYLE
+#  define DEFAULT_QUOTING_STYLE literal_quoting_style
+# endif
 
 /* Names of quoting styles and their corresponding values.  */
 extern char const *const quoting_style_args[];
@@ -40,37 +47,27 @@ extern enum quoting_style const quoting_
 
 struct quoting_options;
 
-#ifndef PARAMS
-# if defined PROTOTYPES || defined __STDC__
-#  define PARAMS(Args) Args
-# else
-#  define PARAMS(Args) ()
-# endif
-#endif
-
 /* The functions listed below set and use a hidden variable
    that contains the default quoting style options.  */
 
 /* Allocate a new set of quoting options, with contents initially identical
    to O if O is not null, or to the default if O is null.
    It is the caller's responsibility to free the result.  */
-struct quoting_options *clone_quoting_options
-   PARAMS ((struct quoting_options *o));
+struct quoting_options *clone_quoting_options (struct quoting_options *o);
 
 /* Get the value of O's quoting style.  If O is null, use the default.  */
-enum quoting_style get_quoting_style PARAMS ((struct quoting_options *o));
+enum quoting_style get_quoting_style (struct quoting_options *o);
 
 /* In O (or in the default if O is null),
    set the value of the quoting style to S.  */
-void set_quoting_style PARAMS ((struct quoting_options *o,
-                               enum quoting_style s));
+void set_quoting_style (struct quoting_options *o, enum quoting_style s);
 
 /* In O (or in the default if O is null),
    set the value of the quoting options for character C to I.
    Return the old value.  Currently, the only values defined for I are
    0 (the default) and 1 (which means to quote the character even if
    it would not otherwise be quoted).  */
-int set_char_quoting PARAMS ((struct quoting_options *o, char c, int i));
+int set_char_quoting (struct quoting_options *o, char c, int i);
 
 /* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
    argument ARG (of size ARGSIZE), using O to control quoting.
@@ -80,35 +77,38 @@ int set_char_quoting PARAMS ((struct quo
    If BUFFERSIZE is too small to store the output string, return the
    value that would have been returned had BUFFERSIZE been large enough.
    If ARGSIZE is -1, use the string length of the argument for ARGSIZE.  */
-size_t quotearg_buffer PARAMS ((char *buffer, size_t buffersize,
-                               char const *arg, size_t argsize,
-                               struct quoting_options const *o));
+size_t quotearg_buffer (char *buffer, size_t buffersize,
+                       char const *arg, size_t argsize,
+                       struct quoting_options const *o);
 
 /* Use storage slot N to return a quoted version of the string ARG.
    Use the default quoting options.
    The returned value points to static storage that can be
    reused by the next call to this function with the same value of N.
    N must be nonnegative.  */
-char *quotearg_n PARAMS ((int n, char const *arg));
+char *quotearg_n (int n, char const *arg);
 
 /* Equivalent to quotearg_n (0, ARG).  */
-char *quotearg PARAMS ((char const *arg));
+char *quotearg (char const *arg);
 
 /* Use style S and storage slot N to return a quoted version of the string ARG.
    This is like quotearg_n (N, ARG), except that it uses S with no other
    options to specify the quoting method.  */
-char *quotearg_n_style PARAMS ((int n, enum quoting_style s, char const *arg));
+char *quotearg_n_style (int n, enum quoting_style s, char const *arg);
+
 /* Use style S and storage slot N to return a quoted version of the
    argument ARG of size ARGSIZE.  This is like quotearg_n_style
    (N, S, ARG), except it can quote null bytes.  */
-char *quotearg_n_style_mem PARAMS ((int n, enum quoting_style s,
-                                   char const *arg, size_t argsize));
+char *quotearg_n_style_mem (int n, enum quoting_style s,
+                           char const *arg, size_t argsize);
 
 /* Equivalent to quotearg_n_style (0, S, ARG).  */
-char *quotearg_style PARAMS ((enum quoting_style s, char const *arg));
+char *quotearg_style (enum quoting_style s, char const *arg);
 
 /* Like quotearg (ARG), except also quote any instances of CH.  */
-char *quotearg_char PARAMS ((char const *arg, char ch));
+char *quotearg_char (char const *arg, char ch);
 
 /* Equivalent to quotearg_char (ARG, ':').  */
-char *quotearg_colon PARAMS ((char const *arg));
+char *quotearg_colon (char const *arg);
+
+#endif /* !QUOTEARG_H_ */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]