Diff options
Diffstat (limited to 'source/ui-snapshot.c')
-rw-r--r--source/ui-snapshot.c52
1 file changed, 21 insertions, 31 deletions
diff --git a/source/ui-snapshot.c b/source/ui-snapshot.c
index 321bf61..04defa6 100644
--- a/source/ui-snapshot.c
+++ b/source/ui-snapshot.c
@@ -211,14 +211,11 @@ static int candidate_resolves(const struct cgit_repo *repo, const char *stem,
* any is tried as a branch, which a branch spelled like a tag's stem would
* otherwise win.
*/
-static const char *ref_from_filename(const struct cgit_repo *repo, const char *filename,
- const struct cgit_snapshot_format *format)
+static char *ref_from_filename(const struct cgit_repo *repo, const char *stem)
{
struct strbuf rev = STRBUF_INIT;
- char *stem = xstrndup(filename, strlen(filename) - strlen(format->suffix));
int found = candidate_resolves(repo, stem, &rev, 1) || candidate_resolves(repo, stem, &rev, 0);
- free(stem);
if (!found)
strbuf_release(&rev);
return found ? strbuf_detach(&rev, NULL) : NULL;
@@ -363,58 +360,51 @@ void cgit_print_snapshot(const char *head, const char *hex, const char *filename
const char *sig_filename = NULL;
char *archive_name = NULL;
char *prefix = NULL;
+ char *ref = NULL;
+ size_t len;
if (!filename) {
cgit_print_error_page(400, "Bad Request", "No snapshot name specified");
return;
}
- if (ends_with(filename, SIG_SUFFIX)) {
+ if (strip_suffix(filename, SIG_SUFFIX, &len)) {
sig_filename = filename;
- archive_name = xstrdup(filename);
- archive_name[strlen(archive_name) - strlen(SIG_SUFFIX)] = '\0';
- filename = archive_name;
+ filename = archive_name = xstrndup(filename, len);
}
f = find_format(filename);
if (!f || (!sig_filename && !(ctx.repo->snapshots & cgit_snapshot_format_bit(f)))) {
cgit_print_error_page(400, "Bad Request", "Unsupported snapshot format: %s", filename);
- return;
+ goto done;
}
- // The name becomes the prefix of every member of the archive, and a
- // revision expression such as :/pattern could carry a path in it.
- if (!hex && dwim && strchr(filename, '/')) {
- cgit_print_error_page(404, "Not Found", "Not found");
- return;
- }
- // A name that is all suffix names no revision, though the lookup below
- // would settle on a ref called v.
- if (!hex && dwim && strlen(filename) == strlen(f->suffix)) {
- cgit_print_error_page(404, "Not Found", "Not found");
- return;
- }
if (!hex && dwim) {
- hex = ref_from_filename(ctx.repo, filename, f);
+ strip_suffix(filename, f->suffix, &len);
+ prefix = xstrndup(filename, len);
+ // The stem becomes the prefix of every member of the archive,
+ // and a revision expression such as :/pattern could carry a path
+ // in it. An empty stem names no revision, though the lookup
+ // would settle on a ref called v.
+ if (len && !strchr(prefix, '/'))
+ hex = ref = ref_from_filename(ctx.repo, prefix);
if (!hex) {
cgit_print_error_page(404, "Not Found", "Not found");
- return;
+ goto done;
}
- prefix = xstrdup(filename);
- prefix[strlen(filename) - strlen(f->suffix)] = '\0';
- }
-
- if (!hex)
- hex = head;
-
- if (!prefix)
+ } else {
prefix = xstrdup(cgit_snapshot_prefix(ctx.repo));
+ if (!hex)
+ hex = head;
+ }
if (sig_filename)
send_sig(f, hex, filename, sig_filename);
else
send_snapshot(f, hex, prefix, filename);
+done:
free(prefix);
+ free(ref);
free(archive_name);
}