bug-gnulib
[Top][All Lists]
Advanced

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

Re: [bug-gnulib] xreadlink.c initial buffer size guesstimate


From: Paul Eggert
Subject: Re: [bug-gnulib] xreadlink.c initial buffer size guesstimate
Date: Fri, 12 Jan 2007 14:02:53 -0800
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/21.4 (gnu/linux)

Bruno Haible <address@hidden> writes:

> in the frequent case that the link is smaller than 1024 and that the
> guess was right, both implementations call xmalloc just once.

Thanks.  I installed the following to make it more robust for this
case.

2007-01-12  Paul Eggert  <address@hidden>

        * lib/xreadlink.c (SYMLINK_MAX) [!defined SYMLINK_MAX]: Define
        to a reasonable default for memory allocation.
        (xreadlink): Don't allocate a huge buffer, to work around a buggy
        file system that reports garbage st_size values for symlinks.
        Problem reported by Liyang Hu.

--- lib/xreadlink.c     13 Sep 2006 22:38:14 -0000      1.22
+++ lib/xreadlink.c     12 Jan 2007 21:54:19 -0000
@@ -38,6 +38,13 @@
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif

+/* SYMLINK_MAX is used only for an initial memory-allocation sanity
+   check, so it's OK to guess too small on hosts where there is no
+   arbitrary limit to symbolic link length.  */
+#ifndef SYMLINK_MAX
+# define SYMLINK_MAX 1024
+#endif
+
 #define MAXSIZE (SIZE_MAX < SSIZE_MAX ? SIZE_MAX : SSIZE_MAX)

 #include "xalloc.h"
@@ -53,9 +60,17 @@
 char *
 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;
+  /* Some buggy file systems report garbage in st_size.  Defend
+     against them by ignoring outlandish st_size values in the initial
+     memory allocation.  */
+  size_t symlink_max = SYMLINK_MAX;
+  size_t INITIAL_LIMIT_BOUND = 8 * 1024;
+  size_t initial_limit = (symlink_max < INITIAL_LIMIT_BOUND
+                         ? symlink_max + 1
+                         : INITIAL_LIMIT_BOUND);
+
+  /* The initial buffer size for the link value.  */
+  size_t buf_size = size < initial_limit ? size + 1 : initial_limit;

   while (1)
     {




reply via email to

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