Specifying a printf conversion specifer as nl's separator string
authorJim Meyering <jim@meyering.net>
Mon, 14 Oct 2002 08:29:41 +0000 (08:29 +0000)
committerJim Meyering <jim@meyering.net>
Mon, 14 Oct 2002 08:29:41 +0000 (08:29 +0000)
could cause nl to segfault.

(build_print_fmt): Don't include separator string
in the printf format; it might contain `%'.
Use a better bound on the length of the print_fmt buffer.
(print_lineno): Print the separator here instead.

src/nl.c

index 065aa4e52fb1d66f816ebd8f397cf3de8782559f..8e227607f1fe9925fe955e2ada6a81f7ee82d571 100644 (file)
--- a/src/nl.c
+++ b/src/nl.c
@@ -234,18 +234,21 @@ FORMAT is one of:\n\
 static void
 build_print_fmt (void)
 {
-  /* 12 = 10 chars for lineno_width, 1 for %, 1 for \0.  */
-  print_fmt = xmalloc (strlen (separator_str) + 12);
+  print_fmt = xmalloc (  1 /* for `%' */
+                      + 1 /* for `-' or `0' */
+                      + INT_STRLEN_BOUND (lineno_width)
+                      + 1 /* for `d' */
+                      + 1 /* for trailing NUL byte */ );
   switch (lineno_format)
     {
     case FORMAT_RIGHT_NOLZ:
-      sprintf (print_fmt, "%%%dd%s", lineno_width, separator_str);
+      sprintf (print_fmt, "%%%dd", lineno_width);
       break;
     case FORMAT_RIGHT_LZ:
-      sprintf (print_fmt, "%%0%dd%s", lineno_width, separator_str);
+      sprintf (print_fmt, "%%0%dd", lineno_width);
       break;
     case FORMAT_LEFT:
-      sprintf (print_fmt, "%%-%dd%s", lineno_width, separator_str);
+      sprintf (print_fmt, "%%-%dd", lineno_width);
       break;
     }
 }
@@ -286,12 +289,13 @@ build_type_arg (char **typep, struct re_pattern_buffer *regexp)
   return rval;
 }
 
-/* Print and increment the line number. */
+/* Print the line number and separator; increment the line number. */
 
 static void
 print_lineno (void)
 {
   printf (print_fmt, line_no);
+  fputs (separator_str, stdout);
   line_no += page_incr;
 }