bug-gnulib
[Top][All Lists]
Advanced

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

xreadlink.c initial buffer size guesstimate


From: Liyang HU
Subject: xreadlink.c initial buffer size guesstimate
Date: Fri, 12 Jan 2007 01:29:10 +0000
User-agent: Mutt/1.4.1i

Hallo,

I've been getting ``ls: memory exhausted'' messages, which I eventually
tracked down to xreadlink() attempting to allocate several hundred MB of
memory, since that's what lstat() returns[0] for the symlink's st_size.
In actuality, the length of the symlink were mostly under 128 bytes.

It seems a rather large amount of memory to allocate as an initial attempt.
Sometimes ls worked, other times, memory exhaustion. :(

According to:

    http://www.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html

(It seems that) POSIX demands {SYMLINK_MAX} to be 255 bytes; SUS v3 says
{SYMLINK_MAX} has to be at least what POSIX says. So 256 bytes seems a much
more sensible maximal initial value.

And anyway, even the comments in xreadlink.c say:

    SIZE is a hint as to how long the link is expected to be;
    typically it is taken from st_size. It need not be correct.

And sometimes it isn't, with comedic effect[1]. So it wouldn't hurt to set
the /initial/ buffer size within somewhat more likely limits, right?

Patch to CVS HEAD, xreadlink.c rev 1.22 below. I haven't tested it. :-/

SYMLINK_MAX didn't seem like it was easily available, so I've substituted
PATH_MAX instead. Good enough for an initial guess. They ought to be around
the same order of magnitude at least.

Cheers,
/Liyang

[0] I know, lstat() should report the on-disk usage of the symlink; however
I thought of more nefarious uses for st_size. Consider my FS braindead if
you will, but xreadlink() needn't fail...

[1] ls --color=auto fails, but plain /bin/ls doesn't. Took a while to figure
out what was going on... (and I only did because I cheated and ltraced the
bugger.)

----8<----

--- xreadlink.c.orig    2007-01-12 00:56:50.000000000 +0000
+++ xreadlink.c 2007-01-12 01:14:40.000000000 +0000
@@ -31,6 +31,8 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "pathmax.h"
+
 #ifndef SIZE_MAX
 # define SIZE_MAX ((size_t) -1)
 #endif
@@ -38,6 +40,7 @@
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif
 
+#define MAXINIT PATH_MAX
 #define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)
 
 #include "xalloc.h"
@@ -54,8 +57,9 @@
 xreadlink (char const *file, size_t size)
 {
   /* 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 < MAXSIZE ? size + 1 : MAXSIZE;
+     detects arithmetic overflow earlier, but is not required.
+     Take size only as a hint; don't go overboard with the xmalloc().  */
+  size_t buf_size = size < MAXINIT ? size + 1 : MAXINIT;
 
   while (1)
     {


This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.





reply via email to

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