gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

commit 5e07b449b19e29773d52f03c1cdb734b7a67e78e
parent fdedf8cca985829fcb0dd6e51b0c901d87e84e9b
Author: Chris Bracken <chris@bracken.jp>
Date:   Fri, 20 Feb 2026 14:33:24 +0900

Better error handling for snprintf

Ensure we're checking not just for errors (negative return values) but
also values that exceed the target buffer size, indicating truncation.

Diffstat:
Msrc/utils.c | 15+++++++++------
Msrc/writer/gopher/commit.c | 10+++++++---
2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/utils.c b/src/utils.c @@ -30,20 +30,23 @@ char* path_concat(const char* p1, const char* p2) { if (p1_slash && p2_slash) { total_len = p1_len + p2_len; out = ecalloc(total_len, sizeof(char)); - if (snprintf(out, total_len, "%s%s", p1, p2 + 1) < 0) { - err(1, "snprintf"); + int r = snprintf(out, total_len, "%s%s", p1, p2 + 1); + if (r < 0 || (size_t)r >= total_len) { + errx(1, "snprintf: path truncated or error"); } } else if (!p1_slash && !p2_slash) { total_len = p1_len + p2_len + 2; out = ecalloc(total_len, sizeof(char)); - if (snprintf(out, total_len, "%s/%s", p1, p2) < 0) { - err(1, "snprintf"); + int r = snprintf(out, total_len, "%s/%s", p1, p2); + if (r < 0 || (size_t)r >= total_len) { + errx(1, "snprintf: path truncated or error"); } } else { total_len = p1_len + p2_len + 1; out = ecalloc(total_len, sizeof(char)); - if (snprintf(out, total_len, "%s%s", p1, p2) < 0) { - err(1, "snprintf"); + int r = snprintf(out, total_len, "%s%s", p1, p2); + if (r < 0 || (size_t)r >= total_len) { + errx(1, "snprintf: path truncated or error"); } } return out; diff --git a/src/writer/gopher/commit.c b/src/writer/gopher/commit.c @@ -147,11 +147,15 @@ static void gopher_commit_write_diffstat_row(GopherCommit* commit, char filename[PATH_MAX]; const char* old_file_path = delta->old_file_path; const char* new_file_path = delta->new_file_path; + int r; if (strcmp(old_file_path, new_file_path) == 0) { - snprintf(filename, sizeof(filename), "%s", old_file_path); + r = snprintf(filename, sizeof(filename), "%s", old_file_path); } else { - snprintf(filename, sizeof(filename), "%s -> %s", old_file_path, - new_file_path); + r = snprintf(filename, sizeof(filename), "%s -> %s", old_file_path, + new_file_path); + } + if (r < 0 || (size_t)r >= sizeof(filename)) { + errx(1, "snprintf: filename truncated or error"); } print_gopher_link_padded(out, filename, 35, ' ');