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

    libs/libc/stream: Avoid overflow in a float conversion of large precision.
    
    A float conversion had signed overflows with a precision near INT_MAX: in
    the length of the conversion, and in exp - n, which is the digit index.
    
    Use an unsigned int for the length.  Use unsigned arithmetic for the
    index: a value below 0 becomes large, so one compare has the job of two.
    
    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 | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/libs/libc/stream/lib_libvsprintf.c 
b/libs/libc/stream/lib_libvsprintf.c
index 029e9bf934f..372544a8917 100644
--- a/libs/libc/stream/lib_libvsprintf.c
+++ b/libs/libc/stream/lib_libvsprintf.c
@@ -662,6 +662,7 @@ set_star:
           double value;
           int exp;              /* Exponent of master decimal digit */
           int n;
+          unsigned int flen;    /* Length of the conversion */
           uint8_t sign;         /* Sign character (or 0) */
           unsigned int ndigs;   /* Number of digits to convert */
           int ndecimal;         /* Digits after decimal (for 'f' format), 0 if
@@ -814,28 +815,28 @@ flt_oper:
 
           if ((flags & FL_FLTFIX) != 0)
             {
-              n = (exp > 0 ? exp + 1 : 1);
+              flen = (exp > 0 ? exp + 1 : 1);
             }
           else
             {
-              n = 5;              /* 1e+00 */
+              flen = 5;           /* 1e+00 */
             }
 
           if (sign != 0)
             {
-              n += 1;
+              flen += 1;
             }
 
           if (prec != 0)
             {
-              n += prec + 1;
+              flen += prec + 1u;
             }
           else if ((flags & FL_ALT) != 0)
             {
-              n += 1;
+              flen += 1;
             }
 
-          width = width > n ? width - n : 0;
+          width = width > flen ? width - flen : 0;
 
           /* Output before first digit */
 
@@ -860,6 +861,7 @@ flt_oper:
             {
               /* 'f' format */
 
+              unsigned int uexp = exp;
               char out;
 
               /* At this point, we should have exp exponent of leftmost digit
@@ -880,7 +882,7 @@ flt_oper:
 
                   /* Pull digits from buffer when in-range, otherwise use 0 */
 
-                  if (0 <= exp - n && exp - n < ndigs)
+                  if (uexp - n < ndigs)
                     {
                       out = _dtoa.digits[exp - n];
                     }
@@ -901,10 +903,10 @@ flt_oper:
                       while (n != -1)
                         {
                           int next = n - 1;
-                          int offset = exp - n;
+                          unsigned int offset = uexp - n;
 
                           if (next < -prec ||
-                              (0 <= offset && offset < ndigs &&
+                              (offset < ndigs &&
                                _dtoa.digits[offset] != '0'))
                             {
                               break;

Reply via email to