summaryrefslogtreecommitdiff
path: root/usr.bin/printf
diff options
context:
space:
mode:
authorMartynas Venckus <martynas@cvs.openbsd.org>2009-07-17 17:39:31 +0000
committerMartynas Venckus <martynas@cvs.openbsd.org>2009-07-17 17:39:31 +0000
commitb5bbaedc253e1406375563930e7f02d209b16642 (patch)
tree67c5245c0c7fe202fe732e16cb57d82c039f7187 /usr.bin/printf
parentff129840bbc95ad2f504d1fac3afee6547e707f2 (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.c34
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);