This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0c009a8cbaf7bf645af37e283094585e2f1802fe
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Nov 5 06:51:54 2026 +0100

    libs/libc/stream: Take the argument of %a and print a question mark.
    
    printf() has no %a.  It went to the path of the unknown conversions,
    which takes an unsigned int.  The argument is a double, and on arm64,
    RISC-V and x86_64 it is in a floating point register.  The next %s used
    a wrong general register as a pointer, and printf() crashed.
    
    Take the double for %a and %A and print "?", padded to the width.  With
    CONFIG_LIBC_FLOATINGPOINT off, do the same for %e, %f and %g, in place
    of the text "*float*".  So a conversion that is not available has one
    behavior, and the rest of the line stays correct.
    
    Part of https://github.com/apache/nuttx/issues/21467
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/stdio/Kconfig            |  2 ++
 libs/libc/stream/lib_libvsprintf.c | 27 ++++++++++++++++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/libs/libc/stdio/Kconfig b/libs/libc/stdio/Kconfig
index ff25cacb619..70b5bfe4ab8 100644
--- a/libs/libc/stdio/Kconfig
+++ b/libs/libc/stdio/Kconfig
@@ -59,6 +59,8 @@ config LIBC_FLOATINGPOINT
        ---help---
                By default, floating point support in printf, sscanf, etc. is
                disabled.  This option will enable floating point support.
+               Without it, printf() takes the argument of %e, %f and %g and
+               prints "?".
 
 config LIBC_NUMBERED_ARGS
        bool "Enable numbered arguments in printf"
diff --git a/libs/libc/stream/lib_libvsprintf.c 
b/libs/libc/stream/lib_libvsprintf.c
index 1bb3d1ebe63..80083855c1c 100644
--- a/libs/libc/stream/lib_libvsprintf.c
+++ b/libs/libc/stream/lib_libvsprintf.c
@@ -112,6 +112,11 @@
 
 #define fmt_ungetc(fmt)   ((fmt)--)
 
+/* e, f, g and a in either case: 0x20 makes an ASCII letter lower case */
+
+#define fmt_isfloat(c)    ((((c) | 0x20) >= 'e' && ((c) | 0x20) <= 'g') || \
+                           ((c) | 0x20) == 'a')
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -596,8 +601,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
             {
               if (stream == NULL)
                 {
-                  if ((c >= 'E' && c <= 'G')
-                      || (c >= 'e' && c <= 'g'))
+                  if (fmt_isfloat(c))
                     {
                       arglist->type[argnumber - 1] = TYPE_DOUBLE;
                     }
@@ -645,13 +649,13 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
 #endif
 
 #ifdef CONFIG_LIBC_FLOATINGPOINT
-      if (c >= 'E' && c <= 'G')
+      if ((c >= 'E' && c <= 'G') || c == 'A')
         {
           flags |= FL_FLTUPP;
           c += 'e' - 'E';
           goto flt_oper;
         }
-      else if (c >= 'e' && c <= 'g')
+      else if ((c >= 'e' && c <= 'g') || c == 'a')
         {
           double value;
           int exp;              /* Exponent of master decimal digit */
@@ -706,6 +710,15 @@ flt_oper:
               value = va_arg(ap, double);
             }
 
+          /* %a has no output yet */
+
+          if (c == 'a')
+            {
+              pnt  = "?";
+              size = 1;
+              goto str_lpad;
+            }
+
           ndigs = __dtoa_engine(value, &_dtoa, ndigs,
                                 ndecimal);
           exp = _dtoa.exp;
@@ -982,7 +995,7 @@ flt_oper:
         }
 
 #else /* !CONFIG_LIBC_FLOATINGPOINT */
-      if ((c >= 'E' && c <= 'G') || (c >= 'e' && c <= 'g'))
+      if (fmt_isfloat(c))
         {
 #  ifdef CONFIG_LIBC_NUMBERED_ARGS
           if ((flags & FL_ARGNUMBER) == 0)
@@ -991,8 +1004,8 @@ flt_oper:
               va_arg(ap, double);
             }
 
-          pnt  = "*float*";
-          size = sizeof("*float*") - 1;
+          pnt  = "?";
+          size = 1;
           goto str_lpad;
         }
 #endif

Reply via email to