Diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
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.
Diffstat (limited to 'source/ui-shared.c')
| -rw-r--r-- | source/ui-shared.c | 38 |
1 file changed, 10 insertions, 28 deletions
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, |
