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 0cf592689c50dd0bc2c43dcca2dac6c1a397fca1
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Nov 5 06:51:55 2026 +0100

    libs/libc/stream: Limit the width and the precision to INT_MAX.
    
    The digits of a width or a precision had no limit: "%99999999999d" had a
    signed overflow, and the width became a wrong value.  A width of INT_MIN
    from "%*d" had a signed overflow when printf() negated it.
    
    A numbered "*" did not check the value: "%2$.*1$e" with a negative value
    gave a negative precision, and "%2$*1$d" did not left-justify.
    
    Keep the value at INT_MAX in the digits and for INT_MIN.  Use one path
    for the value of "*", with or without a number, and for the digits, so
    all later code gets a width and a precision from 0 to INT_MAX.  The one
    path also makes the code smaller.
    
    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/stream/lib_libvsprintf.c | 46 +++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/libs/libc/stream/lib_libvsprintf.c 
b/libs/libc/stream/lib_libvsprintf.c
index 3629aa1c0ee..3455bd8e017 100644
--- a/libs/libc/stream/lib_libvsprintf.c
+++ b/libs/libc/stream/lib_libvsprintf.c
@@ -225,6 +225,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
   FAR const char *pnt;
   size_t size;
   int ch;
+  int star;
   unsigned char len;
   int total_len = 0;
 
@@ -408,14 +409,8 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
                             }
                           else
                             {
-                              if ((flags & FL_PREC) == 0)
-                                {
-                                  width = (int)arglist->value[index - 1].u;
-                                }
-                              else
-                                {
-                                  prec = (int)arglist->value[index - 1].u;
-                                }
+                              star = arglist->value[index - 1].u;
+                              goto set_star;
                             }
                         }
                       else
@@ -434,16 +429,22 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
 
               if (c >= '0' && c <= '9')
                 {
-                  c -= '0';
+                  star = width;
                   if ((flags & FL_PREC) != 0)
                     {
-                      prec = 10 * prec + c;
-                      continue;
+                      star = prec;
                     }
 
-                  width = 10 * width + c;
-                  flags |= FL_WIDTH;
-                  continue;
+                  if (star > (INT_MAX - 9) / 10)
+                    {
+                      star = INT_MAX;
+                    }
+                  else
+                    {
+                      star = 10 * star + (c - '0');
+                    }
+
+                  goto set_star;
                 }
 
               if (c == '*')
@@ -460,24 +461,23 @@ static int vsprintf_internal(FAR struct lib_outstream_s 
*stream,
                     }
 #endif
 
+                  star = va_arg(ap, int);
+
+set_star:
                   if ((flags & FL_PREC) != 0)
                     {
-                      prec = va_arg(ap, int);
-                      if (prec < 0)
-                        {
-                          prec = 0;
-                        }
+                      prec = star < 0 ? 0 : star;
                     }
                   else
                     {
-                      width = va_arg(ap, int);
                       flags |= FL_WIDTH;
-
-                      if (width < 0)
+                      if (star < 0)
                         {
-                          width = -width;
+                          star = star == INT_MIN ? INT_MAX : -star;
                           flags |= FL_LPAD;
                         }
+
+                      width = star;
                     }
 
                   continue;

Reply via email to