|
|
Message-ID: <20260721203136.624-1-mailto.luca.kellermann@gmail.com>
Date: Tue, 21 Jul 2026 22:31:04 +0200
From: Luca Kellermann <mailto.luca.kellermann@...il.com>
To: musl@...ts.openwall.com
Subject: [PATCH] sprintf: fix one byte truncation when producing string of length INT_MAX
(v)sprint() is supposed to return the number of bytes written to s,
excluding the terminating null byte. however, when these functions
return INT_MAX, only INT_MAX - 1 bytes (excluding the terminating null
byte) are written.
this is caused by the way vsprintf() is implemented: calling
vsnprintf() with n = INT_MAX. vsnprintf() returns the number of bytes
that would be written to s had n been sufficiently large excluding the
terminating null byte. output bytes beyond the n-1st are discarded.
to accommodate the largest strings (v)sprintf() can produce (length
INT_MAX, the return value is of type int), vsnprintf() has to be
called with n >= INT_MAX + 1.
calling vsnprintf() with n > INT_MAX is possible since commit
11fb383275d20f5f94c00425bd888a02ecbd218e.
the following program demonstrates the issue:
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *s = malloc(INT_MAX + 1U);
if (!s) exit(1);
int r = sprintf(s, "%*s", INT_MAX, "");
printf("r: %d\nl: %zu\n", r, strlen(s));
}
$ ./sprintf-truncation
r: 2147483647
l: 2147483646
---
src/stdio/vsprintf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/stdio/vsprintf.c b/src/stdio/vsprintf.c
index c57349d4d888d532b39a15d525d248b0eee3c48d..daceeba7b31e983d6775ff2898052fb556c87872 100644
--- a/src/stdio/vsprintf.c
+++ b/src/stdio/vsprintf.c
@@ -3,5 +3,5 @@
int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
{
- return vsnprintf(s, INT_MAX, fmt, ap);
+ return vsnprintf(s, INT_MAX + 1U, fmt, ap);
}
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.