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>
This commit is contained in:
parent
1e039ada85
commit
9984e7ab49
24
ui-refs.c
24
ui-refs.c
@ -93,34 +93,28 @@ static void print_tag_header(void)
|
|||||||
static void print_tag_downloads(const struct cgit_repo *repo, const char *ref)
|
static void print_tag_downloads(const struct cgit_repo *repo, const char *ref)
|
||||||
{
|
{
|
||||||
const struct cgit_snapshot_format* f;
|
const struct cgit_snapshot_format* f;
|
||||||
struct strbuf filename = STRBUF_INIT;
|
|
||||||
const char *basename;
|
const char *basename;
|
||||||
int free_ref = 0;
|
struct strbuf filename = STRBUF_INIT;
|
||||||
|
size_t prefixlen;
|
||||||
|
|
||||||
if (!ref || strlen(ref) < 1)
|
if (!ref || strlen(ref) < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
basename = cgit_repobasename(repo->url);
|
basename = cgit_repobasename(repo->url);
|
||||||
if (!starts_with(ref, basename)) {
|
if (starts_with(ref, basename))
|
||||||
if ((ref[0] == 'v' || ref[0] == 'V') && isdigit(ref[1]))
|
strbuf_addstr(&filename, ref);
|
||||||
ref++;
|
else
|
||||||
if (isdigit(ref[0])) {
|
cgit_compose_snapshot_prefix(&filename, basename, ref);
|
||||||
ref = fmtalloc("%s-%s", basename, ref);
|
prefixlen = filename.len;
|
||||||
free_ref = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
||||||
if (!(repo->snapshots & f->bit))
|
if (!(repo->snapshots & f->bit))
|
||||||
continue;
|
continue;
|
||||||
strbuf_reset(&filename);
|
strbuf_setlen(&filename, prefixlen);
|
||||||
strbuf_addf(&filename, "%s%s", ref, f->suffix);
|
strbuf_addstr(&filename, f->suffix);
|
||||||
cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf);
|
cgit_snapshot_link(filename.buf, NULL, NULL, NULL, NULL, filename.buf);
|
||||||
html(" ");
|
html(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (free_ref)
|
|
||||||
free((char *)ref);
|
|
||||||
strbuf_release(&filename);
|
strbuf_release(&filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
ui-shared.c
26
ui-shared.c
@ -1069,18 +1069,34 @@ void cgit_print_filemode(unsigned short mode)
|
|||||||
html_fileperm(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,
|
void cgit_print_snapshot_links(const char *repo, const char *head,
|
||||||
const char *hex, int snapshots)
|
const char *hex, int snapshots)
|
||||||
{
|
{
|
||||||
const struct cgit_snapshot_format* f;
|
const struct cgit_snapshot_format* f;
|
||||||
struct strbuf filename = STRBUF_INIT;
|
struct strbuf filename = STRBUF_INIT;
|
||||||
size_t prefixlen;
|
size_t prefixlen;
|
||||||
unsigned char sha1[20];
|
|
||||||
|
|
||||||
if (get_sha1(fmt("refs/tags/%s", hex), sha1) == 0 &&
|
cgit_compose_snapshot_prefix(&filename, cgit_repobasename(repo), hex);
|
||||||
(hex[0] == 'v' || hex[0] == 'V') && isdigit(hex[1]))
|
|
||||||
hex++;
|
|
||||||
strbuf_addf(&filename, "%s-%s", cgit_repobasename(repo), hex);
|
|
||||||
prefixlen = filename.len;
|
prefixlen = filename.len;
|
||||||
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
for (f = cgit_snapshot_formats; f->suffix; f++) {
|
||||||
if (!(snapshots & f->bit))
|
if (!(snapshots & f->bit))
|
||||||
|
@ -71,6 +71,8 @@ __attribute__((format (printf,3,4)))
|
|||||||
extern void cgit_print_error_page(int code, const char *msg, const char *fmt, ...);
|
extern void cgit_print_error_page(int code, const char *msg, const char *fmt, ...);
|
||||||
extern void cgit_print_pageheader(void);
|
extern void cgit_print_pageheader(void);
|
||||||
extern void cgit_print_filemode(unsigned short mode);
|
extern void cgit_print_filemode(unsigned short mode);
|
||||||
|
extern void cgit_compose_snapshot_prefix(struct strbuf *filename,
|
||||||
|
const char *base, const char *ref);
|
||||||
extern void cgit_print_snapshot_links(const char *repo, const char *head,
|
extern void cgit_print_snapshot_links(const char *repo, const char *head,
|
||||||
const char *hex, int snapshots);
|
const char *hex, int snapshots);
|
||||||
extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
|
extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
|
||||||
|
Loading…
Reference in New Issue
Block a user