From 41b551f4a3b79ecc922f16a6ab51976fc927af0c Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Fri, 16 Oct 2026 06:14:23 -1000 Subject: Keep the charset off types that only spell xml Matching xml anywhere in the type also caught the Office formats, whose names hold openxmlformats, so a .docx went out with a UTF-8 charset. --- source/ui-shared.c | 6 ++++-- tests/t0105-plain.sh | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/source/ui-shared.c b/source/ui-shared.c index c23e2e1..e5afb2e 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -1426,11 +1426,13 @@ void cgit_print_age(time_t t, int tz, time_t max_relative) /* * Whether a content type carries text a charset applies to, which is every - * text type and the XML ones, the atom feed among them. + * text type and the XML types of RFC 7303, the atom feed among them. */ static int type_has_charset(const char *mimetype) { - return starts_with(mimetype, "text/") || strstr(mimetype, "xml"); + return starts_with(mimetype, "text/") || + !strcmp(mimetype, "application/xml") || + ends_with(mimetype, "+xml"); } void cgit_print_http_headers(void) diff --git a/tests/t0105-plain.sh b/tests/t0105-plain.sh index 4041d98..27e8daa 100755 --- a/tests/t0105-plain.sh +++ b/tests/t0105-plain.sh @@ -46,4 +46,29 @@ test_expect_success 'a blob whose bytes look binary is served as octet-stream' ' sed "/^$/q" tmp | grep "^Content-Type: application/octet-stream$" ' +# RFC 7303 names the XML types by an xml subtype or a +xml suffix, and those +# take a charset like text does. A type that only spells xml inside a word, +# as the Office formats do, is binary and gets none. +test_expect_success 'only text and xml types carry a charset' ' + ( + cd repos/foo && + printf "PK" >doc.docx && + printf "" >pic.svg && + git add doc.docx pic.svg && + git commit -m types + ) && + docx=application/vnd.openxmlformats-officedocument. && + docx=${docx}wordprocessingml.document && + { + echo "enable-html-serving=1" && + echo "mimetype.docx=$docx" && + echo "mimetype.svg=image/svg+xml" && + cat cgitrc + } >typesrc && + CGIT_CONFIG="$PWD/typesrc" QUERY_STRING="url=foo/plain/doc.docx" cgit >tmp && + sed "/^$/q" tmp | grep "^Content-Type: $docx$" && + CGIT_CONFIG="$PWD/typesrc" QUERY_STRING="url=foo/plain/pic.svg" cgit >tmp && + sed "/^$/q" tmp | grep "^Content-Type: image/svg+xml; charset=UTF-8$" +' + test_done -- cgit