[PATCH] fix printf positional arguments for !_MB_CAPABLE case

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] fix printf positional arguments for !_MB_CAPABLE case

Ivan Grokhotkov
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 <[hidden email]>
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)


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] fix printf positional arguments for !_MB_CAPABLE case

Corinna Vinschen
On Jan  9 14:50, Ivan Grokhotkov wrote:

> 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
Pushed.


Thanks,
Corinna

--
Corinna Vinschen
Cygwin Maintainer
Red Hat

signature.asc (849 bytes) Download Attachment