bug-coreutils
[Top][All Lists]
Advanced

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

bug: printf overruns an argument


From: TAKAI Kousuke
Subject: bug: printf overruns an argument
Date: Mon, 24 Mar 2003 22:43:54 +0900
User-agent: T-gnus/6.15.10 (based on Oort Gnus v0.10) EMIKO/1.14.1 (Choanoflagellata) SLIM/1.14.8 (小池栄子) APEL/10.3 Emacs/21.3 (sparc-sun-solaris2.6) MULE/5.0 (賢木)

Hello,

I have noticed that the `printf' command from GNU coreutils
sometimes overruns its argument on some error conditions,
such as incomplete %-directive or \-escape:

  $ ./printf --version
  printf (GNU coreutils) 4.5.11
  [...]

  $ ./printf abc%
  abc./printf: %H: invalid directive
  $ ./printf 'test\'
  address@hidden/home/takai$

  $ ./printf '%b\n' \\
  address@hidden/home/takai
  $

(Two ^@ are actually NUL bytes.  "HOME=/home/takai" happend to
be the first environment variable.)

These will not happen on correct usage, but I think that
these behaviour is confusing.

I made the following patch to fix this problem.  I also made
a lone backslash at the end of string to be treated as a
literal backslash (Solaris and FreeBSD's printf behave as
this), but this may be inappropriate.


2003-03-24  TAKAI Kousuke  <address@hidden>

        * src/printf.c (print_esc): Treat a trailing backslash
        as a literal one.
        (print_formatted): Handle incomplete %-directives.
        Print whole directive (rather than conversion specifier
        only) in diagnostic message.


--- coreutils-4.5.11/src/printf.c.orig  2003-03-11 19:30:59.000000000 +0900
+++ coreutils-4.5.11/src/printf.c       2003-03-24 09:29:02.000000000 +0900
@@ -264,6 +264,9 @@ print_esc (const char *escstart)
        esc_value = esc_value * 8 + octtobin (*p);
       putchar (esc_value);
     }
+  else if (!*p)
+    /* Treat a lone backslash as a literal \.  */
+    putchar ('\\');
   else if (strchr ("\"\\abcfnrtv", *p))
     print_esc_char (*p++);
   else if (!posixly_correct && (*p == 'u' || *p == 'U'))
@@ -508,8 +511,9 @@ print_formatted (const char *format, int
              ++f;
              ++direc_length;
            }
-         if (!strchr ("diouxXfeEgGcs", *f))
-           error (EXIT_FAILURE, 0, _("%%%c: invalid directive"), *f);
+         if (!*f || !strchr ("diouxXfeEgGcs", *f))
+           error (EXIT_FAILURE, 0, _("%.*s: invalid directive"),
+                  (int) direc_length + 1, direc_start);
          ++direc_length;
          if (argc > 0)
            {
[patch ends here]

Sorry for my poor English.

-- 
 TAKAI Kousuke <address@hidden>
  Dept. of Communications and Computer Engineering,
  Graduate School of Infomatics, Kyoto University, Japan




reply via email to

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