50 lines
2.1 KiB
C
50 lines
2.1 KiB
C
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
// Bounded, clamping printf-append for the fixed-size CLI reply buffers used by
|
|
// MQTTBridge's status/stats/diag formatters. Factored out of MQTTBridge so the
|
|
// bound is provable on the host instead of holding "by input-size accident"
|
|
// (see the A1 out-of-bounds-write finding, 2026-07-19 MQTT observer review).
|
|
//
|
|
// Appends `fmt...` to `buf` starting at offset `*pos`, then advances `*pos` by
|
|
// the number of characters actually written, CLAMPED to [0, bufsize-1]. Because
|
|
// snprintf returns the *would-have-written* length, the naive
|
|
// `*pos += snprintf(buf + *pos, bufsize - *pos, ...)` idiom can push `*pos` past
|
|
// `bufsize` after a truncated append; the next append then computes
|
|
// `bufsize - *pos` as a huge size_t and `buf + *pos` past the end, writing out of
|
|
// bounds. Clamping `*pos` here makes every subsequent append a safe no-op once
|
|
// the buffer is full.
|
|
//
|
|
// buf is always left NUL-terminated (vsnprintf guarantees this for bufsize > 0).
|
|
// No-ops on null buf/pos or bufsize == 0. A negative incoming *pos is treated as
|
|
// 0. Typical use: `int pos = 0;` then a sequence of replyAppendf() calls.
|
|
static inline void replyAppendf(char* buf, size_t bufsize, int* pos, const char* fmt, ...) {
|
|
if (!buf || !pos || bufsize == 0) return;
|
|
if (*pos < 0) *pos = 0;
|
|
// Full: no room for anything but the terminator. Keep buf NUL-terminated and
|
|
// leave *pos pinned at the last writable index.
|
|
if ((size_t)*pos >= bufsize - 1) {
|
|
*pos = (int)bufsize - 1;
|
|
buf[*pos] = '\0';
|
|
return;
|
|
}
|
|
size_t remaining = bufsize - (size_t)*pos;
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
int n = vsnprintf(buf + *pos, remaining, fmt, args);
|
|
va_end(args);
|
|
// Encoding error: vsnprintf still NUL-terminated buf + *pos; leave *pos as-is.
|
|
if (n < 0) return;
|
|
*pos += n;
|
|
if ((size_t)*pos >= bufsize) *pos = (int)bufsize - 1; // clamp truncated append
|
|
}
|
|
|
|
static inline uint32_t mbedtlsErrorMagnitude(int32_t stack_err) {
|
|
return stack_err < 0 ? (uint32_t)(-(int64_t)stack_err)
|
|
: (uint32_t)stack_err;
|
|
}
|