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')
| -rw-r--r-- | source/ui-shared.c | 38 | |
| -rw-r--r-- | source/ui-shared.h | 3 |
2 files changed, 12 insertions, 29 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, diff --git a/source/ui-shared.h b/source/ui-shared.h index da1b889..9abd4c0 100644 --- a/source/ui-shared.h +++ b/source/ui-shared.h @@ -125,7 +125,8 @@ extern void cgit_print_snapshot_links(const struct cgit_repo *repo, const char * /* * The name a snapshot of this repository is downloaded under, which is the - * configured prefix or the last component of the repository URL. + * configured prefix or the last component of the repository URL. A name taken + * from the URL is only good until the next call. */ extern const char *cgit_snapshot_prefix(const struct cgit_repo *repo); |
