aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Brown <opensource@whoopdedo.org>2015-12-06 15:09:42 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-03-28 21:42:54 +0000
commitd310db70cde8a212a463635f7321744ec502fe94 (patch)
treebf00adfb707e1d6d2e22a29b1e358c71e0ac5fb8
parente909caa28f9822a4d8610bbf0f3344f613928b43 (diff)
downloadklibc-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.c23
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)