diff options
Diffstat (limited to 'usr.bin/printf')
-rw-r--r-- | usr.bin/printf/printf.c | 35 | ||||
-rw-r--r-- | usr.bin/printf/tests/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/printf/tests/regress.m2.out | 1 | ||||
-rw-r--r-- | usr.bin/printf/tests/regress.missingpos1.out | 1 | ||||
-rw-r--r-- | usr.bin/printf/tests/regress.sh | 10 |
5 files changed, 36 insertions, 12 deletions
diff --git a/usr.bin/printf/printf.c b/usr.bin/printf/printf.c index ac122f7..452711e 100644 --- a/usr.bin/printf/printf.c +++ b/usr.bin/printf/printf.c @@ -101,6 +101,8 @@ static void usage(void); static const char digits[] = "0123456789"; +static char end_fmt[1]; + static int myargc; static char **myargv; static char **gargv; @@ -171,11 +173,11 @@ main(int argc, char *argv[]) fmt += 2; } else { fmt = printf_doformat(fmt, &rval); - if (fmt == NULL) { + if (fmt == NULL || fmt == end_fmt) { #ifdef SHELL INTON; #endif - return (1); + return (fmt == NULL ? 1 : rval); } end = 0; } @@ -215,13 +217,11 @@ printf_doformat(char *fmt, int *rval) static const char skip1[] = "#'-+ 0"; int fieldwidth, haveprec, havewidth, mod_ldbl, precision; char convch, nextch; - char *start; + char start[strlen(fmt) + 1]; char **fargv; char *dptr; int l; - start = alloca(strlen(fmt) + 1); - dptr = start; *dptr++ = '%'; *dptr = 0; @@ -244,11 +244,11 @@ printf_doformat(char *fmt, int *rval) /* save format argument */ fargv = gargv; } else { - fargv = NULL; + fargv = NULL; } /* skip to field width */ - while (strchr(skip1, *fmt) != NULL) { + while (*fmt && strchr(skip1, *fmt) != NULL) { *dptr++ = *fmt++; *dptr = 0; } @@ -259,12 +259,19 @@ printf_doformat(char *fmt, int *rval) l = strspn(fmt, digits); if ((l > 0) && (fmt[l] == '$')) { int idx = atoi(fmt); + if (fargv == NULL) { + warnx("incomplete use of n$"); + return (NULL); + } if (idx <= myargc) { gargv = &myargv[idx - 1]; } else { gargv = &myargv[myargc]; } fmt += l + 1; + } else if (fargv != NULL) { + warnx("incomplete use of n$"); + return (NULL); } if (getint(&fieldwidth)) @@ -296,12 +303,19 @@ printf_doformat(char *fmt, int *rval) l = strspn(fmt, digits); if ((l > 0) && (fmt[l] == '$')) { int idx = atoi(fmt); + if (fargv == NULL) { + warnx("incomplete use of n$"); + return (NULL); + } if (idx <= myargc) { gargv = &myargv[idx - 1]; } else { gargv = &myargv[myargc]; } fmt += l + 1; + } else if (fargv != NULL) { + warnx("incomplete use of n$"); + return (NULL); } if (getint(&precision)) @@ -374,7 +388,7 @@ printf_doformat(char *fmt, int *rval) fputs(p, stdout); free(p); if (getout) - exit(*rval); + return (end_fmt); break; } case 'c': { @@ -442,8 +456,7 @@ mknum(char *str, char ch) len = strlen(str) + 2; if (len > copy_size) { newlen = ((len + 1023) >> 10) << 10; - if ((newcopy = realloc(copy, newlen)) == NULL) - { + if ((newcopy = realloc(copy, newlen)) == NULL) { warnx("%s", strerror(ENOMEM)); return (NULL); } @@ -575,7 +588,7 @@ getnum(intmax_t *ip, uintmax_t *uip, int signedconv) int rval; if (!*gargv) { - *ip = 0; + *ip = *uip = 0; return (0); } if (**gargv == '"' || **gargv == '\'') { diff --git a/usr.bin/printf/tests/Makefile b/usr.bin/printf/tests/Makefile index da3f533..5e212ef 100644 --- a/usr.bin/printf/tests/Makefile +++ b/usr.bin/printf/tests/Makefile @@ -15,6 +15,7 @@ FILES+= regress.m2.out FILES+= regress.m3.out FILES+= regress.m4.out FILES+= regress.m5.out +FILES+= regress.missingpos1.out FILES+= regress.s.out FILES+= regress.sh FILES+= regress.zero.out diff --git a/usr.bin/printf/tests/regress.m2.out b/usr.bin/printf/tests/regress.m2.out index 8baef1b..cf14915 100644 --- a/usr.bin/printf/tests/regress.m2.out +++ b/usr.bin/printf/tests/regress.m2.out @@ -1 +1,2 @@ abc +cdef
\ No newline at end of file diff --git a/usr.bin/printf/tests/regress.missingpos1.out b/usr.bin/printf/tests/regress.missingpos1.out new file mode 100644 index 0000000..3b04f03 --- /dev/null +++ b/usr.bin/printf/tests/regress.missingpos1.out @@ -0,0 +1 @@ +printf: incomplete use of n$ diff --git a/usr.bin/printf/tests/regress.sh b/usr.bin/printf/tests/regress.sh index 84e183b..c9668a3 100644 --- a/usr.bin/printf/tests/regress.sh +++ b/usr.bin/printf/tests/regress.sh @@ -2,7 +2,7 @@ REGRESSION_START($1) -echo '1..15' +echo '1..23' REGRESSION_TEST(`b', `printf "abc%b%b" "def\n" "\cghi"') REGRESSION_TEST(`d', `printf "%d,%5d,%.5d,%0*d,%.*d\n" 123 123 123 5 123 5 123') @@ -19,5 +19,13 @@ REGRESSION_TEST('zero', `printf "%u%u\n" 15') REGRESSION_TEST('zero', `printf "%d%d\n" 15') REGRESSION_TEST('zero', `printf "%d%u\n" 15') REGRESSION_TEST('zero', `printf "%u%d\n" 15') +REGRESSION_TEST(`missingpos1', `printf "%1\$*s" 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%*1\$s" 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%1\$*.*s" 1 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%*1\$.*s" 1 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%*.*1\$s" 1 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%1\$*2\$.*s" 1 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%*1\$.*2\$s" 1 1 1 2>&1') +REGRESSION_TEST(`missingpos1', `printf "%1\$*.*2\$s" 1 1 1 2>&1') REGRESSION_END() |