extern struct taginfo *cgit_parse_tag(struct tag *tag);
extern void cgit_parse_url(const char *url);
-extern const char *cgit_repobasename(const char *reponame);
-
extern int cgit_parse_snapshots_mask(const char *str);
extern const struct object_id *cgit_snapshot_get_sig(const char *ref,
const struct cgit_snapshot_format *f);
return cgit_fileurl(reponame, pagename, NULL, query);
}
-const char *cgit_repobasename(const char *reponame)
+/* result is NULL or must be freed */
+static char *cgit_repobasename(const char *reponame)
{
- /* I assume we don't need to store more than one repo basename */
- static char rvbuf[1024];
- int p;
- const char *rv;
- strncpy(rvbuf, reponame, sizeof(rvbuf));
- if (rvbuf[sizeof(rvbuf)-1])
- die("cgit_repobasename: truncated repository name '%s'", reponame);
- p = strlen(rvbuf)-1;
- /* strip trailing slashes */
- while (p && rvbuf[p] == '/') rvbuf[p--] = 0;
- /* strip trailing .git */
- if (p >= 3 && starts_with(&rvbuf[p-3], ".git")) {
- p -= 3; rvbuf[p--] = 0;
- }
- /* strip more trailing slashes if any */
- while ( p && rvbuf[p] == '/') rvbuf[p--] = 0;
- /* find last slash in the remaining string */
- rv = strrchr(rvbuf,'/');
- if (rv)
- return ++rv;
- return rvbuf;
+ int last = strlen(reponame) - 1, n;
+ char *rv;
+
+ if (last < 1)
+ return NULL;
+
+ while (last && reponame[last] == '/')
+ last--;
+
+ if (last >= 3 && !strncmp(&reponame[last - 3], ".git", 3))
+ last -= 3;
+
+ while (last && reponame[last] == '/')
+ last--;
+
+ n = last;
+ while (n && reponame[n] != '/')
+ n--;
+
+ rv = xmalloc(last - n + 2);
+ strncpy(rv, &reponame[n], last - n + 1);
+ rv[last - n + 1] = '\0';
+
+ return rv;
}
-const char *cgit_snapshot_prefix(const struct cgit_repo *repo)
+/* result is NULL or must be freed */
+char *cgit_snapshot_prefix(const struct cgit_repo *repo)
{
if (repo->snapshot_prefix)
- return repo->snapshot_prefix;
+ return xstrdup(repo->snapshot_prefix);
return cgit_repobasename(repo->url);
}
const char *base, const char *ref);
extern void cgit_print_snapshot_links(const struct cgit_repo *repo,
const char *ref, const char *separator);
-extern const char *cgit_snapshot_prefix(const struct cgit_repo *repo);
+/* result is NULL or must be freed */
+extern char *cgit_snapshot_prefix(const struct cgit_repo *repo);
extern void cgit_add_hidden_formfields(int incl_head, int incl_search,
const char *page);
const char *filename,
const struct cgit_snapshot_format *format)
{
- const char *reponame;
+ char *reponame = NULL;
struct object_id oid;
struct strbuf snapshot = STRBUF_INIT;
int result = 1;
strbuf_setlen(&snapshot, snapshot.len - strlen(format->suffix));
if (get_oid(snapshot.buf, &oid) == 0)
- goto out;
+ goto out1;
reponame = cgit_snapshot_prefix(repo);
+ if (!reponame)
+ goto out1;
+
if (starts_with(snapshot.buf, reponame)) {
const char *new_start = snapshot.buf;
new_start += strlen(reponame);
strbuf_release(&snapshot);
out:
+ free(reponame);
+out1:
return result ? strbuf_detach(&snapshot, NULL) : NULL;
}
hex = head;
if (!prefix)
- prefix = xstrdup(cgit_snapshot_prefix(ctx.repo));
+ prefix = cgit_snapshot_prefix(ctx.repo);
+
+ if (!prefix) {
+ cgit_print_error_page(500, "Internal Server Error",
+ "Bad repo name");
+
+ goto out1;
+ }
+
if (sig_filename)
write_sig(f, hex, filename, sig_filename);
make_snapshot(f, hex, prefix, filename);
free(prefix);
+
+out1:
free(adj_filename);
}