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;
