From 4bc114f972315651176ff72b32a7b4604086c9a5 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Thu, 1 Oct 2026 19:56:43 -1000 Subject: Pin the advisory classes with tests and name an empty author Each class behind cgit's published advisories now has a check against the current code, from a newline in a file name to shell syntax handed to a filter. The feed also treated an ident with an empty name and an empty address as present and wrote an empty person, which Atom forbids. --- source/ui-atom.c | 16 ++++--- tests/t0301-security.sh | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 6 deletions(-) diff --git a/source/ui-atom.c b/source/ui-atom.c index b536437..39cadb8 100644 --- a/source/ui-atom.c +++ b/source/ui-atom.c @@ -88,9 +88,12 @@ static void print_email(const char *email) if (end) *end = '\0'; - html(""); - xml_txt(start); - html("\n"); + // An empty element is no address at all, which Atom forbids. + if (*start) { + html(""); + xml_txt(start); + html("\n"); + } free(copy); } @@ -111,11 +114,12 @@ static void print_entry(struct commit *commit, const char *host) html("\n"); html("\n"); // A person construct must hold a name, so a nameless commit falls - // back to the address and then to a placeholder. + // back to the address and then to a placeholder. An ident may carry + // an empty name and an empty address, which count as missing. html(""); - if (info->author) + if (info->author && *info->author) xml_txt(info->author); - else if (info->author_email) + else if (info->author_email && strcmp(info->author_email, "<>")) xml_txt(info->author_email); else html("unknown"); diff --git a/tests/t0301-security.sh b/tests/t0301-security.sh index f1af8e9..1a5ee44 100755 --- a/tests/t0301-security.sh +++ b/tests/t0301-security.sh @@ -373,4 +373,114 @@ test_expect_success 'a quote in a web url cannot break out of the href' ' grep "href=.https://example.com/x'><script>" tmp ' +# The classes behind cgit's published advisories, each pinned against the +# current code: a newline in a file name splitting the headers, a posted +# length overflowing its buffer, a path climbing out on the dumb transport +# and the about page, a commit with an empty author, a percent sign with no +# digits behind it, script in a file name shown by the diff, and shell +# syntax in a file name handed to a filter. +test_expect_success 'set up the advisory fixtures' ' + mkrepo repos/cve 1 && + ( + cd repos/cve && + printf "x\n" >"$(printf "crlf\r\nX-Injected: 1.txt")" && + printf "x\n" >"