[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug-gnulib] xreadlink.c patch
From: |
Mark D. Baushke |
Subject: |
[Bug-gnulib] xreadlink.c patch |
Date: |
Tue, 02 Nov 2004 02:44:33 -0800 |
Hi,
A patch for GNULIB lib/xreadlink.c
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. (I am given to understand via the
Ffile_symlink_p function in GNU Emacs
src/fileio.c that the same is true for
at least some versions of HP-UX.)
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.
Thank you for your consideration of this patch.
-- Mark
ChangeLog:
* xreadlink.c (xreadlink): Deal with AIX and HP-UX readlink()
returning ERANGE if the buffer is too small. Validate caller
input parameter. Make one last attempt at SSIZE_MAX if
doubling buf_size would have been greater than it. Use times()
instead of *= to avoid numerical overflow.
Index: xreadlink.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/xreadlink.c,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 xreadlink.c
--- xreadlink.c 7 Aug 2004 00:09:39 -0000 1.15
+++ xreadlink.c 2 Nov 2004 10:46:54 -0000
@@ -56,14 +56,20 @@ 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 < SSIZE_MAX) ? size + 1 : size;
while (1)
{
char *buffer = xmalloc (buf_size);
ssize_t link_length = readlink (filename, buffer, buf_size);
- if (link_length < 0)
+ /* AIX and HP-UX realloc() report ERANGE if the buffer is too
+ small */
+ if (link_length < 0
+#ifdef ERANGE
+ && errno != ERANGE
+#endif
+ )
{
int saved_errno = errno;
free (buffer);
@@ -71,15 +77,20 @@ xreadlink (char const *filename, size_t
return NULL;
}
- if ((size_t) link_length < buf_size)
+ if (link_length >= 0 && (size_t) 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 >= SSIZE_MAX)
+ /* Our buffer cannot grow any bigger. */
xalloc_die ();
+
+ buf_size = xtimes (buf_size, 2);
+ if (buf_size > SSIZE_MAX)
+ /* readlink()'s maximum buffer size. */
+ buf_size = SSIZE_MAX;
}
}
- [Bug-gnulib] xreadlink.c patch,
Mark D. Baushke <=
Re: [Bug-gnulib] xreadlink.c patch, Bruno Haible, 2004/11/05