[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: bug: printf overruns an argument
From: |
TAKAI Kousuke |
Subject: |
Re: bug: printf overruns an argument |
Date: |
Thu, 27 Mar 2003 22:29:25 +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,
Paul Eggert <address@hidden> wrote:
>> Thanks for reporting this. Your patch is quite appropriate as far as
>> it goes, but unfortunately it is incomplete, since there's another
>> related buffer overrun. Also, I found some other examples where
>> printf does not conform to POSIX:
I found yet other ones:
$ ./printf '\0123'
S
POSIX says that octal escape sequences in FORMAT are specified
as "\ddd" where ddd is a one, two, or three-digit octal number,
thus the output should be a newline character (\012) followed
by a character `3'.
(In the other hand, octal escape sequences in %b's arguments
are specified as "\0ddd" where ddd is zero to three-digit octal
number, which meets current GNU printf's behaviour.)
$ ./printf 'ab\cdef'
ab
POSIX says that \c is only recognized in arguments for %b,
thus I think `ab\cdef' is better output than `ab'.
Here is a patch for these problem. Change for \c may break
some existing applications, so I protected it with POSIXLY_CORRECT,
but this may not be appropriate.
2003-03-27 TAKAI Kousuke <address@hidden>
* src/printf.c (print_esc): New argument PERCENT_B.
Recognize \ooo for FORMAT, \0ooo for %b.
Handle \c here, but don't handle when parsing FORMAT
and POSIXLY_CORRECT is set.
(print_esc_char): Remove handling of \c.
(print_esc_string, print_formatted): Callers of `print_esc'
changed.
--- coreutils-4.5.11/src/printf.c.orig 2003-03-27 20:54:17.000000000 +0900
+++ coreutils-4.5.11/src/printf.c 2003-03-27 22:03:56.131165180 +0900
@@ -208,9 +208,6 @@ print_esc_char (int c)
case 'b': /* Backspace. */
putchar (8);
break;
- case 'c': /* Cancel the rest of the output. */
- exit (EXIT_SUCCESS);
- break;
case 'f': /* Form feed. */
putchar (12);
break;
@@ -237,7 +234,7 @@ print_esc_char (int c)
besides the backslash. */
static int
-print_esc (const char *escstart)
+print_esc (const char *escstart, bool percent_b)
{
register const char *p = escstart + 1;
int esc_value = 0; /* Value of \nnn escape. */
@@ -254,17 +251,29 @@ print_esc (const char *escstart)
error (EXIT_FAILURE, 0, _("missing hexadecimal number in escape"));
putchar (esc_value);
}
+ else if (!percent_b && isodigit (*p))
+ {
+ /* An octal \ooo esacape sequence has 1 to 3 octal digits.
+ Recognized only in FORMAT. */
+ for (esc_value = octtobin (*p), esc_length = 1, ++p;
+ esc_length < 3 && isodigit (*p);
+ ++esc_length, ++p)
+ esc_value = esc_value * 8 + octtobin (*p);
+ putchar (esc_value);
+ }
else if (*p == '0')
{
/* An octal \0ooo escape sequence has 0 to 3 octal digits
- after the leading \0. */
+ after the leading \0. Recognized for arguments for %b. */
for (esc_length = 0, ++p;
esc_length < 3 && isodigit (*p);
++esc_length, ++p)
esc_value = esc_value * 8 + octtobin (*p);
putchar (esc_value);
}
- else if (*p && strchr ("\"\\abcfnrtv", *p))
+ else if ((!posixly_correct || percent_b) && *p == 'c')
+ exit (EXIT_SUCCESS); /* Cancel the rest of the output. */
+ else if (*p && strchr ("\"\\abfnrtv", *p))
print_esc_char (*p++);
else if (!posixly_correct && (*p == 'u' || *p == 'U'))
{
@@ -313,7 +322,7 @@ print_esc_string (const char *str)
{
for (; *str; str++)
if (*str == '\\')
- str += print_esc (str);
+ str += print_esc (str, true);
else
putchar (*str);
}
@@ -531,7 +540,7 @@ print_formatted (const char *format, int
break;
case '\\':
- f += print_esc (f);
+ f += print_esc (f, false);
break;
default:
[patch ends here]
Sorry for my poor English, and for troubling you
about my incomplete patch.
--
TAKAI Kousuke <address@hidden>
Dept. of Communications and Computer Engineering,
Graduate School of Infomatics, Kyoto University, Japan