diff options
-rw-r--r--source/ui-plain.c8
-rwxr-xr-xtests/t0105-plain.sh25
2 files changed, 32 insertions, 1 deletion
diff --git a/source/ui-plain.c b/source/ui-plain.c
index 67b2044..57e4699 100644
--- a/source/ui-plain.c
+++ b/source/ui-plain.c
@@ -84,7 +84,9 @@ static void print_object(const struct object_id *oid, const char *path)
ctx.page.size = size;
cgit_print_http_headers();
html_raw(buf, size);
- free(mimetype);
+ // ctx.page.mimetype may still point into mimetype, and the headers
+ // are read again by whatever renders after this, so it stays alive
+ // for the rest of the request.
free(buf);
}
@@ -166,6 +168,10 @@ static int walk_tree(const struct object_id *oid, struct strbuf *base,
{
struct walk_tree_context *walk = context;
+ // A tree can hold two entries of one name, and only the first answers:
+ // a second response would follow the first in the same body.
+ if (walk->response != RESPONSE_NONE && walk->dir_len >= 0 && base->len == (size_t)walk->dir_len)
+ return 0;
if (walk->dir_len >= 0 && base->len == (size_t)walk->dir_len) {
if (S_ISREG(mode) || S_ISLNK(mode)) {
print_object(oid, pathname);
diff --git a/tests/t0105-plain.sh b/tests/t0105-plain.sh
index 27e8daa..2e5513f 100755
--- a/tests/t0105-plain.sh
+++ b/tests/t0105-plain.sh
@@ -71,4 +71,29 @@ test_expect_success 'only text and xml types carry a charset' '
sed "/^$/q" tmp | grep "^Content-Type: image/svg+xml; charset=UTF-8$"
'
+# A tree can carry two entries of one name, which only a repository with
+# fsck off accepts, and the plain view answers the first alone.
+test_expect_success 'plain answers once for duplicate tree entries' '
+ test_create_repo repos/dup &&
+ (
+ cd repos/dup &&
+ blob=$(printf PNGDATA | git hash-object -w --stdin) &&
+ inner=$(printf "100644 blob %s\\tinside\\n" $blob | git mktree) &&
+ top=$(printf "100644 blob %s\\tx.png\\n040000 tree %s\\tx.png\\n" $blob $inner | git mktree --missing) &&
+ c=$(echo dup | git commit-tree $top) &&
+ git update-ref refs/heads/master $c
+ ) &&
+ {
+ echo "virtual-root=/" &&
+ echo "cache-size=0" &&
+ echo "mimetype.png=image/png" &&
+ echo "repo.url=dup" &&
+ echo "repo.path=$PWD/repos/dup/.git"
+ } >duprc &&
+ CGIT_CONFIG="$PWD/duprc" QUERY_STRING="url=dup/plain/x.png" cgit >tmp &&
+ test $(grep -c "^Status:" tmp) = 1 &&
+ test $(grep -c "^Content-Type:" tmp) = 1 &&
+ grep "^Content-Type: image/png" tmp
+'
+
test_done