|
Re: bug: printf overruns an argument: msg#00094gnu.core-utils.bugs
TAKAI Kousuke <takai@xxxxxxxxxxxxxxxxxxxxxxx> writes: > 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. 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: $ ./printf '\X' printf: \X: invalid escape POSIX says that the output should be '\X'. $ ./printf '\x40' @ POSIX says that the output should be '\x40'. $ ./printf '% +d' 234 printf: %+: invalid directive POSIX says that the output should be '+234'. Here is a proposed patch for all these problems: 2003-03-24 Paul Eggert <eggert@xxxxxxxxxxx> Fix buffer overrun problem reported by TAKAI Kousuke, along with some other POSIX incompatibilities. * src/printf.c (print_esc): Do not treat \x specially if POSIXLY_CORRECT. Avoid buffer overrun if the format ends in backslash. Treat incomplete escape sequences as strings of characters, as POSIX requires. (print_formatted): Allow multiple flags. Avoid buffer overrun if the format is incomplete. --- printf.c 2003/03/11 10:30:59 4.5.11.0 +++ printf.c 2003/03/25 00:17:55 4.5.11.4 @@ -243,7 +243,7 @@ print_esc (const char *escstart) int esc_value = 0; /* Value of \nnn escape. */ int esc_length; /* Length of \nnn escape. */ - if (*p == 'x') + if (!posixly_correct && (*p == 'x')) { /* A hexadecimal \xhh escape sequence must have 1 or 2 hex. digits. */ for (esc_length = 0, ++p; @@ -264,7 +264,7 @@ print_esc (const char *escstart) esc_value = esc_value * 8 + octtobin (*p); putchar (esc_value); } - else if (strchr ("\"\\abcfnrtv", *p)) + else if (*p && strchr ("\"\\abcfnrtv", *p)) print_esc_char (*p++); else if (!posixly_correct && (*p == 'u' || *p == 'U')) { @@ -295,7 +295,14 @@ print_esc (const char *escstart) print_unicode_char (stdout, uni_value, 0); } else - error (EXIT_FAILURE, 0, _("\\%c: invalid escape"), *p); + { + putchar ('\\'); + if (*p) + { + putchar (*p); + p++; + } + } return p - escstart - 1; } @@ -449,7 +456,7 @@ print_formatted (const char *format, int } break; } - if (strchr ("-+ #", *f)) + while (*f == ' ' || *f == '#' || *f == '+' || *f == '-') { ++f; ++direc_length; @@ -508,7 +515,7 @@ print_formatted (const char *format, int ++f; ++direc_length; } - if (!strchr ("diouxXfeEgGcs", *f)) + if (! (*f && strchr ("diouxXfeEgGcs", *f))) error (EXIT_FAILURE, 0, _("%%%c: invalid directive"), *f); ++direc_length; if (argc > 0) |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | bug: printf overruns an argument: 00094, TAKAI Kousuke |
|---|---|
| Next by Date: | Re: printf \xNNN: 00094, Paul Eggert |
| Previous by Thread: | bug: printf overruns an argumenti: 00094, TAKAI Kousuke |
| Next by Thread: | Re: bug: printf overruns an argument: 00094, Jim Meyering |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |