diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/ui-shared.c42
1 file changed, 40 insertions, 2 deletions
diff --git a/source/ui-shared.c b/source/ui-shared.c
index 1b65a7f..125a235 100644
--- a/source/ui-shared.c
+++ b/source/ui-shared.c
@@ -616,6 +616,39 @@ static struct string_list_item *lookup_path(struct string_list *list,
return NULL;
}
+/*
+ * Expand the %s placeholders in a module-link template and emit the result as
+ * an attribute value. The template is never handed to printf: a repository can
+ * supply its own through a repo-local cgitrc, and a surplus conversion would
+ * then read past the argument list.
+ */
+static void html_module_link(const char *tmpl, const char **args, int nargs)
+{
+ struct strbuf sb = STRBUF_INIT;
+ int used = 0;
+
+ while (*tmpl) {
+ if (*tmpl != '%') {
+ strbuf_addch(&sb, *tmpl++);
+ continue;
+ }
+ tmpl++;
+ if (*tmpl == '%') {
+ strbuf_addch(&sb, '%');
+ tmpl++;
+ } else if (*tmpl == 's' && used < nargs) {
+ strbuf_addstr(&sb, args[used++]);
+ tmpl++;
+ } else {
+ // Anything else is not a placeholder this template can
+ // fill, so keep it verbatim rather than dropping it.
+ strbuf_addch(&sb, '%');
+ }
+ }
+ html_attr(sb.buf);
+ strbuf_release(&sb);
+}
+
void cgit_submodule_link(const char *class, char *path, const char *rev)
{
struct string_list *list;
@@ -641,14 +674,19 @@ void cgit_submodule_link(const char *class, char *path, const char *rev)
htmlf("class='%s' ", class);
html("href='");
if (item) {
- html_attrf(item->util, rev);
+ // A per-path template names only the submodule commit.
+ const char *args[] = { rev };
+ html_module_link(item->util, args, 1);
} else {
+ const char *args[2];
dir = strrchr(path, '/');
if (dir)
dir++;
else
dir = path;
- html_attrf(ctx.repo->module_link, dir, rev);
+ args[0] = dir;
+ args[1] = rev;
+ html_module_link(ctx.repo->module_link, args, 2);
}
html("'>");
html_txt(path);