]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(print_long_format): Detect and handle strftime failure
authorJim Meyering <jim@meyering.net>
Sun, 5 Jan 1997 20:32:49 +0000 (20:32 +0000)
committerJim Meyering <jim@meyering.net>
Sun, 5 Jan 1997 20:32:49 +0000 (20:32 +0000)
due to pathologically long strings in locale tables. Patch from Paul Eggert.
(print_long_format): Change references to BIGBUF in use of FPUT macro
to references to BUF.
Use 11 (not 20) bytes for mode string buffer.

src/ls.c

index bd94629419bb3f8fc6fee5b621527f0172edb3e3..a69292e295135413c07817141b834f191a9e31e8 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
@@ -2034,16 +2034,17 @@ print_current_files (void)
 static void
 print_long_format (const struct fileinfo *f)
 {
-  char modebuf[20];
-/* This is more than enough for all known LC_TIME locales.  */
-#define TIMEBUF_SIZE 100
+  char modebuf[11];
 
   /* 7 fields that may (worst case: 64-bit integral values) require 20 bytes,
-     1 10-character mode string,
-     1 TIMEBUF_SIZE-character time string,
-     9 spaces, one following each of these fields,
-     and 1 trailing NUL byte.  */
-  char bigbuf[7 * 20 + 10 + TIMEBUF_SIZE + 9 + 1];
+     1 10-byte mode string,
+     1 24-byte time string (may be longer in some locales -- see below),
+     9 spaces, one following each of these fields, and
+     1 trailing NUL byte.  */
+  char init_bigbuf[7 * 20 + 10 + 24 + 9 + 1];
+  char *buf = init_bigbuf;
+  size_t bufsize = sizeof (init_bigbuf);
+  size_t s;
   char *p;
   time_t when;
   const char *fmt;
@@ -2092,7 +2093,7 @@ print_long_format (const struct fileinfo *f)
        }
     }
 
-  p = bigbuf;
+  p = buf;
 
   if (print_inode)
     {
@@ -2137,12 +2138,23 @@ print_long_format (const struct fileinfo *f)
 
   /* Use strftime rather than ctime, because the former can produce
      locale-dependent names for the weekday (%a) and month (%b).  */
-  p += strftime (p, TIMEBUF_SIZE, fmt, localtime (&when));
+
+  while (! (s = strftime (p, buf + bufsize - p, fmt, localtime (&when))))
+    {
+      char *newbuf = alloca (bufsize *= 2);
+      memcpy (newbuf, buf, p - buf);
+      p = newbuf + (p - buf);
+      buf = newbuf;
+    }
+
+  p += s;
   *p++ = ' ';
+
+  /* NUL-terminate the string -- fputs (via FPUTS) requires it.  */
   *p = '\0';
 
   DIRED_INDENT ();
-  FPUTS (bigbuf, stdout, p - bigbuf);
+  FPUTS (buf, stdout, p - buf);
   PUSH_CURRENT_DIRED_POS (&dired_obstack);
   print_name_with_quoting (f->name, f->stat.st_mode, f->linkok);
   PUSH_CURRENT_DIRED_POS (&dired_obstack);