diff options
author | Jim Meyering <jim@meyering.net> | 2003-03-27 14:59:26 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2003-03-27 14:59:26 +0000 |
commit | cb392d10229f35798fbc1dd3de7e7a5cf690d47d (patch) | |
tree | eaaf8b3f9ee4f9750c709eeb1fa568552d656e4b | |
parent | a89b7d3e831e28521d996e39cf8abe0ece8e22d8 (diff) | |
download | coreutils-cb392d10229f35798fbc1dd3de7e7a5cf690d47d.tar.xz |
Fix buffer overrun problem reported by TAKAI Kousuke, along
with some other POSIX incompatibilities.
(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.
-rw-r--r-- | src/printf.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/printf.c b/src/printf.c index 32b8c3e8e..22e1b9755 100644 --- a/src/printf.c +++ b/src/printf.c @@ -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 argc, char **argv) } break; } - if (strchr ("-+ #", *f)) + while (*f == ' ' || *f == '#' || *f == '+' || *f == '-') { ++f; ++direc_length; @@ -508,7 +515,7 @@ print_formatted (const char *format, int argc, char **argv) ++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) |