]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/nolibc/printf: Handle "%s" with the numeric formats
authorDavid Laight <david.laight.linux@gmail.com>
Sun, 8 Mar 2026 11:37:35 +0000 (11:37 +0000)
committerThomas Weißschuh <linux@weissschuh.net>
Fri, 20 Mar 2026 16:55:50 +0000 (17:55 +0100)
Avoids the extra va_arg() call with is non-trivial on a lot of
modern ABI.

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260308113742.12649-11-david.laight.linux@gmail.com
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
tools/include/nolibc/stdio.h

index 7382b00707fb89e760c393d9b1d910b3e34ebfda..a377f164c70d9d8d5b4adbf29c6157eb1889286e 100644 (file)
@@ -412,13 +412,13 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
                 */
                ch_flag = _NOLIBC_PF_FLAG(ch);
                if (((ch >= 'a' && ch <= 'z') || ch == 'X') &&
-                   _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p')) {
-                       /* 'long' is needed for pointer conversions and ltz lengths.
+                   _NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'c', 'd', 'i', 'u', 'x', 'p', 's')) {
+                       /* 'long' is needed for pointer/string conversions and ltz lengths.
                         * A single test can be used provided 'p' (the same bit as '0')
                         * is masked from flags.
                         */
                        if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag | (flags & ~_NOLIBC_PF_FLAG('p')),
-                                                    'p', 'l', 't', 'z')) {
+                                                    'p', 's', 'l', 't', 'z')) {
                                v = va_arg(args, unsigned long);
                                signed_v = (long)v;
                        } else if (_NOLIBC_PF_FLAGS_CONTAIN(flags, 'j', 'q')) {
@@ -437,6 +437,14 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
                                goto do_output;
                        }
 
+                       if (ch == 's') {
+                               /* "%s" - character string. */
+                               outstr = (const char  *)(uintptr_t)v;
+                               if (!outstr)
+                                       outstr = "(null)";
+                               goto do_strlen_output;
+                       }
+
                        out = outbuf;
 
                        if (_NOLIBC_PF_FLAGS_CONTAIN(ch_flag, 'd', 'i')) {
@@ -465,13 +473,6 @@ int __nolibc_printf(__nolibc_printf_cb cb, void *state, const char *fmt, va_list
                        goto do_strlen_output;
                }
 
-               if (ch == 's') {
-                       outstr = va_arg(args, char *);
-                       if (!outstr)
-                               outstr = "(null)";
-                       goto do_strlen_output;
-               }
-
                if (ch == 'm') {
 #ifdef NOLIBC_IGNORE_ERRNO
                        outstr = "unknown error";