commit c4edd894077a09547707f9ff76e4e188b361354b
parent 233b8132b5436b0980c16a89d0f6d22f8c637495
Author: Chris Bracken <chris@bracken.jp>
Date: Fri, 20 Feb 2026 17:37:04 +0900
atom: ensure base URL + path concatenation includes a slash
In the case where baseurl doesn't end in a slash, add one.
Diffstat:
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/src/writer/atom/atom.c b/src/writer/atom/atom.c
@@ -64,6 +64,7 @@ void atom_add_commit(Atom* atom,
assert(atom != NULL);
assert(commit != NULL);
assert(path != NULL);
+ assert(path[0] != '\0');
assert(content_type != NULL);
FILE* out = atom->out;
@@ -99,7 +100,15 @@ void atom_add_commit(Atom* atom,
if (strlen(content_type) > 0) {
fprintf(out, "type=\"%s\" ", content_type);
}
- fprintf(out, "href=\"%s%s\" />\n", atom->baseurl, path);
+ size_t baseurl_len = strlen(atom->baseurl);
+ const char* p = path;
+ if (baseurl_len > 0 && atom->baseurl[baseurl_len - 1] == '/' && p[0] == '/') {
+ p++;
+ }
+ bool needs_slash =
+ (baseurl_len > 0 && atom->baseurl[baseurl_len - 1] != '/' && p[0] != '/');
+ fprintf(out, "href=\"%s%s%s\" />\n", atom->baseurl, needs_slash ? "/" : "",
+ p);
fprintf(out, "<author>\n<name>");
if (commit->author_name) {
diff --git a/src/writer/atom/atom_tests.c b/src/writer/atom/atom_tests.c
@@ -167,3 +167,37 @@ UTEST(atom, limit_commits) {
fclose(out);
free(buf);
}
+
+UTEST(atom, url_concatenation) {
+ GitRepo repo = {.short_name = "test-repo"};
+ GitCommit commit = {.oid = "sha"};
+
+ struct {
+ const char* base;
+ const char* path;
+ const char* expected;
+ } cases[] = {
+ {"https://ex.com/", "c/1.html", "href=\"https://ex.com/c/1.html\""},
+ {"https://ex.com", "c/1.html", "href=\"https://ex.com/c/1.html\""},
+ {"https://ex.com", "/c/1.html", "href=\"https://ex.com/c/1.html\""},
+ {"https://ex.com/", "/c/1.html", "href=\"https://ex.com/c/1.html\""},
+ {"", "c/1.html", "href=\"c/1.html\""},
+ };
+
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
+ char* buf = NULL;
+ size_t size = 0;
+ FILE* out = open_memstream(&buf, &size);
+ Atom* atom = atom_create(&repo, out);
+ atom_set_baseurl(atom, cases[i].base);
+
+ atom_add_commit(atom, &commit, cases[i].path, "text/html", "");
+
+ fflush(out);
+ EXPECT_NE(NULL, strstr(buf, cases[i].expected));
+
+ atom_free(atom);
+ fclose(out);
+ free(buf);
+ }
+}