bug-gnulib
[Top][All Lists]
Advanced

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

Re: [Bug-gnulib] xreadlink.c patch


From: Paul Eggert
Subject: Re: [Bug-gnulib] xreadlink.c patch
Date: Tue, 02 Nov 2004 12:23:15 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

"Mark D. Baushke" <address@hidden> writes:

>   1) bugfix. readlink() on AIX 4.3 returns a
>      negative link_length and sets errno == ERANGE
>      when the length of the link is greater than
>      buf_size.

Shouldn't this incompatibility be fixed in readlink.c rather than
xreadlink?  I would expect other users of the readlink module to be
affected by it.  Perhaps Bruno can comment, since he did readlink.c.

>   2) enhancement. The size passed to xreadlink
>      could be the maximum value and adding one
>      could wrap it to zero which would be a bad
>      idea.
>
>   3) enhancement. Allow for at least one attempt
>      at the maximum allowed buffer size if
>      doubling the current buf_size pushes over the
>      limit.

These are both good suggestions, but there's a problem with that
patch: it assumes SSIZE_MAX < SIZE_MAX, but POSIX does not require
this.  I installed the following patch instead.

2004-11-02  Paul Eggert  <address@hidden>

        * xreadlink.c (MAXSIZE): New macro.
        (xreadlink): Use it instead of SSIZE_MAX.  Ensure initial buffer
        size does not exceed MAXSIZE.  Avoid cast.
        As suggested by Mark D. Baushke in
        <http://lists.gnu.org/archive/html/bug-gnulib/2004-11/msg00009.html>,
        if readlink fails with buffer size just under MAXSIZE, try again
        with MAXSIZE.

Index: xreadlink.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/xreadlink.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -p -u -r1.15 -r1.16
--- xreadlink.c 7 Aug 2004 00:09:39 -0000       1.15
+++ xreadlink.c 2 Nov 2004 20:17:37 -0000       1.16
@@ -41,6 +41,8 @@
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif
 
+#define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
+
 #include "xalloc.h"
 
 /* Call readlink to get the symbolic link value of FILENAME.
@@ -56,14 +58,15 @@ xreadlink (char const *filename, size_t 
 {
   /* The initial buffer size for the link value.  A power of 2
      detects arithmetic overflow earlier, but is not required.  */
-  size_t buf_size = size + 1;
+  size_t buf_size = size < MAXSIZE ? size + 1 : MAXSIZE;
 
   while (1)
     {
       char *buffer = xmalloc (buf_size);
-      ssize_t link_length = readlink (filename, buffer, buf_size);
+      ssize_t r = readlink (filename, buffer, buf_size);
+      size_t link_length = r;
 
-      if (link_length < 0)
+      if (r < 0)
        {
          int saved_errno = errno;
          free (buffer);
@@ -71,15 +74,18 @@ xreadlink (char const *filename, size_t 
          return NULL;
        }
 
-      if ((size_t) link_length < buf_size)
+      if (link_length < buf_size)
        {
          buffer[link_length] = 0;
          return buffer;
        }
 
       free (buffer);
-      buf_size *= 2;
-      if (! (0 < buf_size && buf_size <= SSIZE_MAX))
+      if (buf_size <= MAXSIZE / 2)
+       buf_size *= 2;
+      else if (buf_size < MAXSIZE)
+       buf_size = MAXSIZE;
+      else
        xalloc_die ();
     }
 }




reply via email to

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