diff options
author | Martynas Venckus <martynas@cvs.openbsd.org> | 2009-07-17 17:39:31 +0000 |
---|---|---|
committer | Martynas Venckus <martynas@cvs.openbsd.org> | 2009-07-17 17:39:31 +0000 |
commit | b5bbaedc253e1406375563930e7f02d209b16642 (patch) | |
tree | 67c5245c0c7fe202fe732e16cb57d82c039f7187 /usr.bin/printf | |
parent | ff129840bbc95ad2f504d1fac3afee6547e707f2 (diff) |
be more careful with parsing format string. we can't do multiple
widths or precisions. fixes crash reported by Maksymilian Arciemowicz,
where printf(3) took more args from stack than printf(1) passed it.
behavior consistent with linucses and ieee 1003.1-2001.
ok millert@, otto@
Diffstat (limited to 'usr.bin/printf')
-rw-r--r-- | usr.bin/printf/printf.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index 3e2d7891805..01be054439f 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printf.c,v 1.14 2008/09/08 17:04:20 martynas Exp $ */ +/* $OpenBSD: printf.c,v 1.15 2009/07/17 17:39:30 martynas Exp $ */ /* * Copyright (c) 1989 The Regents of the University of California. @@ -39,7 +39,7 @@ char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)printf.c 5.9 (Berkeley) 6/1/90";*/ -static char rcsid[] = "$OpenBSD: printf.c,v 1.14 2008/09/08 17:04:20 martynas Exp $"; +static char rcsid[] = "$OpenBSD: printf.c,v 1.15 2009/07/17 17:39:30 martynas Exp $"; #endif /* not lint */ #include <ctype.h> @@ -134,7 +134,7 @@ main(int argc, char *argv[]) gargv = ++argv; #define SKIP1 "#-+ 0" -#define SKIP2 "*0123456789" +#define SKIP2 "0123456789" do { /* * Basic algorithm is to scan the format string for conversion @@ -163,16 +163,28 @@ main(int argc, char *argv[]) } /* skip to field width */ - for (; strchr(SKIP1, *fmt); ++fmt) ; - fieldwidth = *fmt == '*' ? getint() : 0; - - /* skip to possible '.', get following precision */ - for (; strchr(SKIP2, *fmt); ++fmt) ; - if (*fmt == '.') + for (; strchr(SKIP1, *fmt); ++fmt) + ; + if (*fmt == '*') { + ++fmt; + fieldwidth = getint(); + } else + fieldwidth = 0; + + /* skip to field precision */ + for (; strchr(SKIP2, *fmt); ++fmt) + ; + precision = 0; + if (*fmt == '.') { ++fmt; - precision = *fmt == '*' ? getint() : 0; + if (*fmt == '*') { + ++fmt; + precision = getint(); + } + for (; strchr(SKIP2, *fmt); ++fmt) + ; + } - for (; strchr(SKIP2, *fmt); ++fmt) ; if (!*fmt) { warnx ("missing format character"); return(1); |