diff options
author | Patrick Brown <opensource@whoopdedo.org> | 2015-12-06 15:09:42 +0100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2020-03-28 21:42:54 +0000 |
commit | d310db70cde8a212a463635f7321744ec502fe94 (patch) | |
tree | bf00adfb707e1d6d2e22a29b1e358c71e0ac5fb8 | |
parent | e909caa28f9822a4d8610bbf0f3344f613928b43 (diff) | |
download | klibc-d310db70cde8a212a463635f7321744ec502fe94.tar.gz |
[klibc] dash: builtin: Reject malformed printf specifications with digits after '*'
[ dash commit 0134f725b7d254ddbc3cc6dd72399edea832559c ]
Dash doesn't notice when a format string has digits following a * width
specifier.
$ dash -c 'printf "%*0s " 1 2 && echo FAIL || echo OK'
%10s FAIL
$ bash -c 'printf "%*0s " 1 2 && echo FAIL || echo OK'
bash: line 0: printf: `0': invalid format character
OK
$ mksh -c 'printf "%*0s " 1 2 && echo FAIL || echo OK'
printf: %*0: invalid conversion specification
OK
With this patch dash complains about the malformed specifications.
$ ./src/dash -c 'printf "%*0s " 1 2 && echo FAIL || echo OK'
./src/dash: 1: printf: %*0: invalid directive
OK
Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779618
Originally-by: Patrick Brown <opensource@whoopdedo.org>
Forwarded-by: Gioele Barabucci <gioele@svario.it>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r-- | usr/dash/bltin/printf.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c index d4ae794d5bb54..78bf388a99376 100644 --- a/usr/dash/bltin/printf.c +++ b/usr/dash/bltin/printf.c @@ -177,17 +177,24 @@ pc: /* skip to field width */ fmt += strspn(fmt, SKIP1); - if (*fmt == '*') - *param++ = getuintmax(1); - - /* skip to possible '.', get following precision */ - fmt += strspn(fmt, SKIP2); - if (*fmt == '.') + if (*fmt == '*') { ++fmt; - if (*fmt == '*') *param++ = getuintmax(1); + } else { + /* skip to possible '.', + * get following precision + */ + fmt += strspn(fmt, SKIP2); + } - fmt += strspn(fmt, SKIP2); + if (*fmt == '.') { + ++fmt; + if (*fmt == '*') { + ++fmt; + *param++ = getuintmax(1); + } else + fmt += strspn(fmt, SKIP2); + } ch = *fmt; if (!ch) |