From dac2147178850a6d27132032c80d1d91dadce4ce Mon Sep 17 00:00:00 2001 From: Tristan Riehs Date: Mon, 29 Dec 2025 14:44:14 +0100 Subject: Add routine for safely creating formatted strings --- src/main.c | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 667a79f..c380dda 100644 --- a/src/main.c +++ b/src/main.c @@ -128,11 +128,45 @@ static void sanitize_sql_str(char **str) *str = new_str; } -/* TODO: add a routine for safely creating formatted string +/* Safely create a formatted string and write it to BUF. BUF shall be a buffer + * of size at least SIZE. BUF can be stack-allocated. If the formatting cannot + * be performed, exit(3) is called. This function is not meant to be called + * directly: the macro strbuild should be used. The code is adapted from the + * make_message function of the vsnprintf(3) manual page, section "examples". */ +static void __strbuild(char *buf, int size, + const char *file, int line, + const char *fmt, ...) +{ + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(NULL, 0, fmt, ap); + va_end(ap); + + if (len < 0) { + fprintf(stderr, "%s:%d: ", file, line); + perror(""); + exit(EXIT_FAILURE); + } + if (len >= size) { + fprintf(stderr, "%s:%d: error: not enough space, " + "have %d, need at least %d\n", + file, line, + size, len + 1); + exit(EXIT_FAILURE); + } + + va_start(ap, fmt); + len = vsnprintf(buf, size, fmt, ap); + va_end(ap); + + assert(n >= 0); +} - Using stack-allocated space would be nice. Sketch: - static void strbuild(char *buf, int size, char *fmt, ...) - Advice: read the example at the end of the vsnprintf(3) manual page. */ +/* Convenience wrapper for __strbuild. */ +#define strbuild(buf, fmt, ...) \ + __strbuild(buf, sizeof(buf), __FILE__, __LINE__, fmt, __VA_ARGS__) /* Compute something that identifies the content of FILE. Algorithm by Dan Bernstein from http://www.cse.yorku.ca/~oz/hash.html via -- cgit v1.2.3