diff options
author | 2009-07-17 17:39:30 +0000 | |
---|---|---|
committer | 2009-07-17 17:39:30 +0000 | |
commit | 27ea1e893ff96e195d550a6662e3330d2bb58afe (patch) | |
tree | d08c70da0a259d27469185a4095cd1cbb62cf348 | |
parent | Tidy up new-session and attach-session and change them to work from inside (diff) | |
download | wireguard-openbsd-27ea1e893ff96e195d550a6662e3330d2bb58afe.tar.xz wireguard-openbsd-27ea1e893ff96e195d550a6662e3330d2bb58afe.zip |
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@
-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); |