about summary refs log tree commit diff
path: root/ui-shared.c
diff options
context:
space:
mode:
authorLukas Fleischer <lfleischer@lfos.de>2016-05-24 18:15:18 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2016-07-05 16:14:40 +0200
commit9984e7ab49c59e49a0d7e62c3435e7133f7a53ec (patch)
tree1f3a53622746e5fe43e9d5c7c9bc27ab2da22761 /ui-shared.c
parentgit: update to v2.9.0 (diff)
downloadcgit-pink-9984e7ab49c59e49a0d7e62c3435e7133f7a53ec.tar.gz
cgit-pink-9984e7ab49c59e49a0d7e62c3435e7133f7a53ec.zip
Avoid ambiguities when prettifying snapshot names
When composing snapshot file names for a tag with a prefix of the form
v[0-9] (resp. V[0-9]), the leading "v" (resp. "V") is stripped. This
leads to conflicts if a tag with the stripped name already exists or if
there are tags only differing in the capitalization of the leading "v".
Make sure we do not strip the "v" in these cases.

Reported-by: Juuso Lapinlampi <wub@partyvan.eu>
Signed-off-by: Lukas Fleischer <lfleischer@lfos.de>
Diffstat (limited to '')
-rw-r--r--ui-shared.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/ui-shared.c b/ui-shared.c
index 562fa0e..b1a6c46 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -1069,18 +1069,34 @@ void cgit_print_filemode(unsigned short mode)
 	html_fileperm(mode);
 }
 
+void cgit_compose_snapshot_prefix(struct strbuf *filename, const char *base,
+				  const char *ref)
+{
+	unsigned char sha1[20];
+
+	/*
+	 * Prettify snapshot names by stripping leading "v" or "V" if the tag
+	 * name starts with {v,V}[0-9] and the prettify mapping is injective,
+	 * i.e. each stripped tag can be inverted without ambiguities.
+	 */
+	if (get_sha1(fmt("refs/tags/%s", ref), sha1) == 0 &&
+	    (ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]) &&
+	    ((get_sha1(fmt("refs/tags/%s", ref + 1), sha1) == 0) +
+	     (get_sha1(fmt("refs/tags/v%s", ref + 1), sha1) == 0) +
+	     (get_sha1(fmt("refs/tags/V%s", ref + 1), sha1) == 0) == 1))
+		ref++;
+
+	strbuf_addf(filename, "%s-%s", base, ref);
+}
+
 void cgit_print_snapshot_links(const char *repo, const char *head,
 			       const char *hex, int snapshots)
 {
 	const struct cgit_snapshot_format* f;
 	struct strbuf filename = STRBUF_INIT;
 	size_t prefixlen;
-	unsigned char sha1[20];
 
-	if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
-	    (hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1]))
-		hex++;
-	strbuf_addf(&filename, "%s-%s", cgit_repobasename(repo), hex);
+	cgit_compose_snapshot_prefix(&filename, cgit_repobasename(repo), hex);
 	prefixlen = filename.len;
 	for (f = cgit_snapshot_formats; f->suffix; f++) {
 		if (!(snapshots & f->bit))