gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

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:
Msrc/writer/atom/atom.c | 11++++++++++-
Msrc/writer/atom/atom_tests.c | 34++++++++++++++++++++++++++++++++++
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); + } +}