lib: cbprintf: perform length calculation dry-run.

C99 § 7.19.6.5 defines `snprintf`. According to ¶ 2:

> If `n` is zero, nothing is written, and `s` may be a null pointer.

And according to § 7.19.6.12 ¶ 2:

> The `vsnprintf` function is equivalent to `snprintf` (...)

However, prior to this change, `vsnprintfcb` (and indirectly, `snprintfcb`)
unconditionally null-terminates the output buffer.

This fixes #48394, which was auto-closed without actually being fixed.

Co-authored-by: Adrien Lessard <adrien.lessard@rbr-global.com>
Signed-off-by: Samuel Coleman <samuel.coleman@rbr-global.com>
This commit is contained in:
Samuel Coleman
2025-08-27 14:25:38 +01:00
committed by Henrik Brix Andersen
parent c86c748ff0
commit 3332a97295

View File

@@ -23,6 +23,7 @@ int cbprintf(cbprintf_cb out, void *ctx, const char *format, ...)
#if defined(CONFIG_CBPRINTF_LIBC_SUBSTS)
#include <stdio.h>
#include <zephyr/sys/__assert.h>
/* Context for sn* variants is the next space in the buffer, and the buffer
* end.
@@ -96,12 +97,18 @@ int snprintfcb(char *str, size_t size, const char *format, ...)
int vsnprintfcb(char *str, size_t size, const char *format, va_list ap)
{
__ASSERT(str || !size, "str may only be NULL when size == 0");
struct str_ctx ctx = {
.dp = str,
.dpe = str + size,
};
int rv = cbvprintf(str_out, &ctx, format, ap);
if (!size) {
return rv;
}
if (ctx.dp < ctx.dpe) {
ctx.dp[0] = 0;
} else {