summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2003-03-27 14:59:26 +0000
committerJim Meyering <jim@meyering.net>2003-03-27 14:59:26 +0000
commitcb392d10229f35798fbc1dd3de7e7a5cf690d47d (patch)
treeeaaf8b3f9ee4f9750c709eeb1fa568552d656e4b /src
parenta89b7d3e831e28521d996e39cf8abe0ece8e22d8 (diff)
downloadcoreutils-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.
Diffstat (limited to 'src')
-rw-r--r--src/printf.c17
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)