This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
[PATCH] fix printf positional arguments for !_MB_CAPABLE case
- From: Ivan Grokhotkov <ivan at espressif dot com>
- To: newlib at sourceware dot org
- Date: Tue, 9 Jan 2018 14:50:31 +0800
- Subject: [PATCH] fix printf positional arguments for !_MB_CAPABLE case
- Authentication-results: sourceware.org; auth=none
Hi,
In newlib builds with multibyte support disabled and positional arguments support enabled, positional arguments sometimes are not printed correctly. For example,
printf(“%1$f”, 1.0);
may print garbage value on a 32-bit platform.
This issue happens because the code path in get_arg, which looks for ‘%’ character, does not work correctly for the ! _MB_CAPABLE case. In _MB_CAPABLE case, fmt pointer is advanced to the next character, and then the check for ‘%’ is performed. In !_MB_CAPABLE case, the check is performed before advancing ‘fmt’ pointer. Net result is that in !_MB_CAPABLE case fmt still points to ‘%’ character, which causes the subsequent state machine to go from START to DONE state immediately. ‘spec_type’ defaults to INT, so arguments which are longer than int (for example, double) are not fetched correctly using va_arg.
Patch is attached.
Thanks,
Ivan
From 50289be4275d5fd9b197daa3fe2ad2a0672080a9 Mon Sep 17 00:00:00 2001
From: Ivan Grokhotkov <ivan@espressif.com>
Date: Tue, 9 Jan 2018 14:07:25 +0800
Subject: [PATCH] newlib: fvprintf: fix get_arg for !_MB_CAPABLE
Code path for _MB_CAPABLE scans for the '%' character and advances
'fmt' pointer past '%'. Code path for !_MB_CAPABLE leaved fmt pointing
to '%', which caused the state machine to go from START to DONE state
immediately.
---
newlib/libc/stdio/vfprintf.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c
index 50a3478a4..211cb17bb 100644
--- a/newlib/libc/stdio/vfprintf.c
+++ b/newlib/libc/stdio/vfprintf.c
@@ -2098,6 +2098,8 @@ _DEFUN(get_arg, (data, n, fmt, ap, numargs_p, args, arg_type, last_fmt),
if (*fmt == '\0')
break;
+
+ fmt++;
# endif /* ! _MB_CAPABLE */
state = START;
flags = 0;
base-commit: fcd33916ac03086b9090c68e88036afa4b25d913
--
2.14.3 (Apple Git-98)