From 1ecf3e052d85ad600373b7f6e6e616c995391ad1 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sat, 31 Oct 2026 13:14:54 -0700 Subject: Trim a snapshot name without reading out of bounds For a url of .git, or an empty one, repo_basename stepped its index to the byte before its buffer, read it, and would have cleared it had it held a slash. Git's strbuf trims take the same steps safely, and they lift the 1024-byte cap that failed the page for a longer url. --- source/ui-shared.c | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) (limited to 'source/ui-shared.c') diff --git a/source/ui-shared.c b/source/ui-shared.c index 936a6a4..9ad398f 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -35,33 +35,6 @@ // into a tab title while it still leaves room to spare in that buffer. #define MAX_TITLE_PATH_LEN 256 -static const char *repo_basename(const char *reponame) -{ - // The result lives in a static buffer, so it is only good until the - // next call. - static char buf[1024]; - const char *slash; - size_t len; - int last; - - len = strlcpy(buf, reponame, sizeof(buf)); - if (len >= sizeof(buf)) - die("Repository name too long: %s", reponame); - last = len - 1; - while (last && buf[last] == '/') - buf[last--] = '\0'; - if (last >= 3 && starts_with(&buf[last - 3], ".git")) { - last -= 3; - buf[last--] = '\0'; - } - while (last && buf[last] == '/') - buf[last--] = '\0'; - slash = strrchr(buf, '/'); - if (slash) - return ++slash; - return buf; -} - static const char *root_url(void) { if (ctx.cfg.virtual_root) @@ -955,10 +928,19 @@ void cgit_tree_url(const char *head, struct strbuf *base, struct strbuf *query) const char *cgit_snapshot_prefix(const struct cgit_repo *repo) { + static struct strbuf name = STRBUF_INIT; + const char *slash; + if (repo->snapshot_prefix) return repo->snapshot_prefix; - return repo_basename(repo->url); + strbuf_reset(&name); + strbuf_addstr(&name, repo->url); + strbuf_trim_trailing_dir_sep(&name); + strbuf_strip_suffix(&name, ".git"); + strbuf_trim_trailing_dir_sep(&name); + slash = strrchr(name.buf, '/'); + return slash ? slash + 1 : name.buf; } void cgit_index_link(const char *name, const char *title, const char *class, -- cgit