From 4251f1bb695c720f968edfcadcc4cb3e2cdbe8b8 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sun, 1 Nov 2026 09:45:16 -1000 Subject: Link snapshots of a slash ref by a dashed name The snapshot page refuses to work a revision out of a name holding a slash, since that name becomes the top directory of the archive, so every link for a ref like release/2.0 answered 404. The ref now goes in the link as the id, and the archive unpacks into the repository's own prefix, as any snapshot asked for by id does. --- source/ui-shared.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/ui-shared.c b/source/ui-shared.c index 81db404..23daa2b 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -1864,11 +1864,27 @@ static void compose_snapshot_prefix(struct strbuf *filename, const char *base, c strbuf_addf(filename, "%s-%s", base, ref); } +/* + * Unlike reporevlink, this names rev whenever it is given, even where the + * page's own head is rev, since the link does not carry that head along. + */ +static void snapshot_file_link(const char *name, const char *filename, const char *rev) +{ + const char *delim = repolink(NULL, NULL, "snapshot", NULL, filename); + + if (rev) + url_arg(delim, "id", rev); + html("'>"); + html_txt(name); + html(""); +} + void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, const char *separator) { const struct cgit_snapshot_format *f; struct strbuf filename = STRBUF_INIT; - const char *basename; + const char *basename, *rev = NULL; + char *slash; size_t prefixlen; basename = cgit_snapshot_prefix(repo); @@ -1876,6 +1892,13 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co strbuf_addstr(&filename, ref); else compose_snapshot_prefix(&filename, basename, ref); + // The snapshot page works no revision out of a name holding a slash, + // since that name becomes the archive's top directory, so a ref such + // as release/2.0 is spelled with a dash and passed outright. + for (slash = filename.buf; (slash = strchr(slash, '/')); slash++) { + *slash = '-'; + rev = ref; + } prefixlen = filename.len; for (f = cgit_snapshot_formats; f->suffix; f++) { @@ -1886,11 +1909,11 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co // A file and its signature are one unit, which the stylesheet // keeps from breaking across lines. html(""); - snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link(filename.buf, filename.buf, rev); if (cgit_snapshot_get_sig(ref, f)) { strbuf_addstr(&filename, SIG_SUFFIX); html(" ("); - snapshot_link("sig", NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link("sig", filename.buf, rev); html(")"); } else if ( starts_with(f->suffix, ".tar") && @@ -1902,7 +1925,7 @@ void cgit_print_snapshot_links(const struct cgit_repo *repo, const char *ref, co strbuf_setlen(&filename, filename.len - strlen(f->suffix)); strbuf_addstr(&filename, ".tar" SIG_SUFFIX); html(" ("); - snapshot_link("sig", NULL, NULL, NULL, NULL, filename.buf); + snapshot_file_link("sig", filename.buf, rev); html(")"); } html(""); -- cgit 2.12.1