[klibc] [klibc:update-dash] dash: builtin: Reject malformed printf specifications with digits after '*'

klibc-bot for Patrick Brown opensource at whoopdedo.org
Sat Mar 28 14:48:43 PDT 2020


Commit-ID:  d310db70cde8a212a463635f7321744ec502fe94
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=d310db70cde8a212a463635f7321744ec502fe94
Author:     Patrick Brown <opensource at whoopdedo.org>
AuthorDate: Sun, 6 Dec 2015 15:09:42 +0100
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 28 Mar 2020 21:42:54 +0000

[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 at whoopdedo.org>
Forwarded-by: Gioele Barabucci <gioele at svario.it>

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

---
 usr/dash/bltin/printf.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/usr/dash/bltin/printf.c b/usr/dash/bltin/printf.c
index d4ae794d..78bf388a 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)


More information about the klibc mailing list