#!/bin/sh # Checks what the configuration parser reports on stderr. test_description='Check configuration diagnostics' . ./setup.sh test_expect_success 'set up configs' ' write_script drain-filter <<-\EOF && cat >/dev/null EOF cgitrc_repo diagrc diag no-such-key=1 "repo.path=$PWD/repos/foo/.git" repo.no-such-repo-key=1 && { echo "virtual-root=/" && echo "cache-size=0" && echo "repo.desc=early" && echo "repo.url=diag" && echo "repo.path=$PWD/repos/foo/.git" && echo "repo.readme=:file-1" && echo "repo.about-filter=exec:$PWD/drain-filter" } >earlyrc ' test_expect_success 'unknown keys are reported and the page still renders' ' cgit_rc diagrc "url=diag/" >tmp 2>err && grep "Status: 200" tmp && grep "Unknown config key: no-such-key" err && grep "Unknown repo config key: no-such-repo-key" err ' test_expect_success 'a repo key before any repo.url is reported' ' cgit_rc earlyrc "url=diag/" >tmp 2>err && grep "Status: 200" tmp && grep "Ignoring repo.desc before any repo.url" err ' test_expect_success 'a filter in a scanned repository is reported without its flag' ' git clone -q --bare repos/foo/.git scan/foo.git && echo "commit-filter=exec:$FILTER_DIRECTORY/dump.sh" >scan/foo.git/cgitrc && { echo "virtual-root=/" && echo "cache-size=0" && echo "scan-path=$PWD/scan" } >scanrc && cgit_rc scanrc "url=foo.git/commit/" >tmp 2>err && grep "
commit 5" tmp && test_grep -F "Ignoring commit-filter in $PWD/scan/foo.git/: trust-scan-config is not set" err ' test_expect_success 'the flag lets a scanned repository set its filters' ' { echo "trust-scan-config=1" && cat scanrc } >scanrc-on && cgit_rc scanrc-on "url=foo.git/commit/" >tmp 2>err && grep "
COMMIT 5" tmp && ! grep "Ignoring" err ' # The filter prints nothing, so an empty about div shows that it ran in place # of the readme. It reads its input first, so its exit cannot race cgit's # write. test_expect_success 'a repo filter in the main cgitrc needs no flag' ' cgit_rc earlyrc "url=diag/about/" >tmp 2>err && grep "
" tmp && ! grep "about-filter" err ' # The repository may turn up before a cached 404 would expire, so error pages # skip the cache. A page from one that opens shows this config does cache. test_expect_success 'a repository whose path is missing answers 404' ' { echo "virtual-root=/" && echo "cache-size=1021" && echo "cache-root=$PWD/gone-cache" && echo "repo.url=gone" && echo "repo.path=$PWD/no/such/repo/.git" && echo "repo.url=foo" && echo "repo.path=$PWD/repos/foo/.git" } >gonerc && mkdir -p gone-cache && for page in "" log/ commit/ "tag/&h=x" atom/ plain/f do cgit_rc gonerc "url=gone/$page" >tmp 2>err && grep "^Status: 404 Not Found" tmp && grep "Failed to open gone: No such file or directory" tmp || return 1 done && test -z "$(ls gone-cache)" && cgit_ok gonerc "url=foo/log/" >tmp && ls gone-cache >slots && test_line_count = 1 slots ' test_expect_success 'a fully understood config stays silent' ' cgit_url "foo/" >tmp 2>err && grep "Status: 200" tmp && ! grep "\[cgit\]" err ' # A comment runs to the end of its line, whatever bytes it holds, so nothing # after a NUL inside one is read as a setting. test_expect_success 'a NUL inside a comment does not end it' ' { echo "virtual-root=/" && echo "cache-size=0" && printf "# note\\000root-title=Smuggled\\n" && echo "repo.url=foo" && echo "repo.path=$PWD/repos/foo/.git" } >nulrc && grep -c Smuggled nulrc && cgit_rc nulrc "url=" >tmp && grep "" tmp && ! grep Smuggled tmp ' # A file saved with DOS line endings reads as one saved with Unix endings, a # semicolon starts a comment as a hash does, and a line with no equals sign # is dropped alone. None of it moves the line a warning names. test_expect_success 'line endings, comments and stray lines leave the rest alone' ' printf "%s\r\n" "virtual-root=/" "cache-size=0" "; root-title=Smuggled" \ "no equals sign here" "repo.url=foo" "repo.path=$PWD/repos/foo/.git" \ "repo.hide=yes" >crlfrc && cgit_rc crlfrc "url=foo/" >tmp 2>err && test_grep "^Status: 200" tmp && test_grep "data-page=.summary. data-repo=.foo." tmp && test_grep ! "Smuggled" tmp && test_grep -F "Reading hide=yes in $PWD/crlfrc line 7 as 0, since it is not a whole number" err && test_line_count = 1 err ' # cgitrc and the files it includes are meant to be there, so one that cannot # be read is logged rather than left to show an empty index. test_expect_success 'a config file that cannot be read is reported' ' CGIT_CONFIG="$PWD/no-such-rc" QUERY_STRING="url=" cgit >tmp 2>err && grep "No repositories found" tmp && test_grep -F "Unable to read config file $PWD/no-such-rc: No such file or directory" err && mkdir rc-dir && CGIT_CONFIG="$PWD/rc-dir" QUERY_STRING="url=" cgit >tmp 2>err && test_grep -F "Unable to read config file $PWD/rc-dir: Is a directory" err && { echo "include=$PWD/no-such-include" && cat diagrc } >includerc && cgit_rc includerc "url=diag/" >tmp 2>err && grep "Status: 200" tmp && test_grep -F "Unable to read config file $PWD/no-such-include: No such file or directory" err ' # An include is parsed from inside the line that names it, so a file that # includes itself would recurse until the stack gave out. Includes nest eight # deep below cgitrc, and a ninth is left unread. Each level sets root-desc # before it includes the next, so the deepest level read is what shows. test_expect_success 'includes stop at the nesting limit' ' { echo "virtual-root=/" && echo "cache-size=0" && echo "repo.url=foo" && echo "repo.path=$PWD/repos/foo/.git" && echo "include=$PWD/selfrc" } >selfrc && cgit_ok selfrc "url=foo/" >tmp && test_grep "data-page=.summary. data-repo=.foo." tmp && for level in 1 2 3 4 5 6 7 8 do { echo "root-desc=level $level" && echo "include=$PWD/level$((level + 1))rc" } >level${level}rc || return 1 done && echo "root-desc=level 9" >level9rc && cgitrc_repo chainrc foo "include=$PWD/level1rc" && cgit_ok chainrc "url=" >tmp && test_grep "level 8" tmp && test_grep ! "level 9" tmp ' # A scanned repository's own cgitrc is optional, so a scan says nothing when # one is missing, and neither does reading the scan back from the cache. The # first request leaves one list there for the second to read. test_expect_success 'a scan says nothing of the files it may lack' ' git clone -q --bare repos/foo/.git quiet/foo.git && mkdir quiet-cache && { echo "virtual-root=/" && echo "cache-root=$PWD/quiet-cache" && echo "cache-size=64" && echo "cache-index-ttl=0" && echo "scan-path=$PWD/quiet" } >quietrc && cgit_rc quietrc "url=" >tmp 2>err && grep ">foo.git" tmp && ls quiet-cache | grep "^rc-" >cached && test_line_count = 1 cached && cgit_rc quietrc "url=" >tmp 2>>err && grep ">foo.git" tmp && test_must_be_empty err ' # A number is read as atoi reads it, which makes a word 0 without a sound, so # a value that is not a whole number is logged with the file and line it came # from, and still read the way it always was. An include in between leaves # the line count of the file around it alone. test_expect_success 'a word where a number belongs is reported' ' cgitrc_repo wordrc word enable-index-owner=no "max-repo-count= 20 " \ "repo.path=$PWD/repos/foo/.git" repo.hide=yes && cgit_rc wordrc "url=" >tmp 2>err && grep ">word" tmp && ! grep "col-owner" tmp && test_grep -F "Reading enable-index-owner=no in $PWD/wordrc line 3 as 0, since it is not a whole number" err && test_grep -F "Reading hide=yes in $PWD/wordrc line 7 as 0, since it is not a whole number" err && ! grep "max-repo-count" err && { echo "include=$PWD/wordrc" && echo "enable-blame=on" } >outerrc && cgit_rc outerrc "url=" >tmp 2>err && test_grep -F "Reading enable-index-owner=no in $PWD/wordrc line 3 as 0, since it is not a whole number" err && test_grep -F "Reading enable-blame=on in $PWD/outerrc line 2 as 0, since it is not a whole number" err ' # A number left empty reads as 0 as well, so it is logged as a word is. test_expect_success 'an empty number is reported' ' cgitrc_repo emptyrc foo cache-size= && cgit_rc emptyrc "url=foo/" >tmp 2>err && test_grep "^Status: 200" tmp && test_grep -F "Reading cache-size= in $PWD/emptyrc line 3 as 0, since it is not a whole number" err && test_line_count = 1 err ' test_expect_success 'a word in a scanned git config is reported' ' git clone -q --bare repos/foo/.git wordscan/foo.git && git -C wordscan/foo.git config cgit.hide true && line=$(grep -n "hide = true" wordscan/foo.git/config | cut -d: -f1) && { echo "virtual-root=/" && echo "cache-size=0" && echo "enable-git-config=1" && echo "scan-path=$PWD/wordscan" } >wordscanrc && cgit_rc wordscanrc "url=" >tmp 2>err && grep ">foo.git" tmp && test_grep -F "Reading hide=true in $PWD/wordscan/foo.git/config line $line as 0, since it is not a whole number" err ' test_expect_success 'a word in a scanned cgitrc is reported' ' git clone -q --bare repos/foo/.git wordrcscan/foo.git && printf "%s\n" "# set by the owner" "desc=scanned" "hide=yes" >wordrcscan/foo.git/cgitrc && { echo "virtual-root=/" && echo "cache-size=0" && echo "scan-path=$PWD/wordrcscan" } >wordrcscanrc && cgit_rc wordrcscanrc "url=" >tmp 2>err && grep ">foo.git" tmp && test_grep -F "Reading hide=yes in $PWD/wordrcscan/foo.git/cgitrc line 3 as 0, since it is not a whole number" err && test_line_count = 1 err ' # A snapshot format name that matches nothing used to drop out without a # word, so a typo read like a format left off on purpose. The legacy 0 for # none stays quiet, and a leading number other than 0 still means tar alone. test_expect_success 'an unknown snapshot format is reported' ' cgitrc_repo snaprc snap "snapshots=tar zap tar.gz" \ "repo.path=$PWD/repos/foo/.git" "repo.snapshots=tar 0 tar.gzz" && cgit_rc snaprc "url=snap/commit/" >tmp 2>err && grep "href=./snap/snapshot/snap-master.tar.>" tmp && ! grep "snap-master.tar.gz" tmp && test_grep -F "Ignoring unknown snapshot format zap in $PWD/snaprc line 3" err && test_grep -F "Ignoring unknown snapshot format tar.gzz in $PWD/snaprc line 6" err && test_line_count = 2 err && cgitrc_repo legacyrc snap "snapshots=2 zip" "repo.path=$PWD/repos/foo/.git" && cgit_rc legacyrc "url=snap/commit/" >tmp 2>err && grep "href=./snap/snapshot/snap-master.tar.>" tmp && ! grep "snap-master.zip" tmp && test_must_be_empty err ' # A max-stats value that names no period turns the statistics page off as if # it were unset, so it is logged with the file and line it came from. The # empty value and 0 that turn the page off on purpose stay quiet, and so does # a period's one letter code. test_expect_success 'a max-stats that names no period is reported' ' cgitrc_repo statsrc stats max-stats=decade "repo.path=$PWD/repos/foo/.git" && cgit_rc statsrc "url=stats/stats/" >tmp 2>err && test_grep "^Status: 404" tmp && test_grep -F "Turning statistics off for max-stats=decade in $PWD/statsrc line 3, since it names no period" err && test_line_count = 1 err && cgitrc_repo repostatsrc stats max-stats=year "repo.path=$PWD/repos/foo/.git" repo.max-stats=century && cgit_rc repostatsrc "url=stats/stats/" >tmp 2>err && test_grep "^Status: 404" tmp && test_grep -F "Turning statistics off for max-stats=century in $PWD/repostatsrc line 6, since it names no period" err && test_line_count = 1 err && cgitrc_repo letterrc stats max-stats=y "repo.path=$PWD/repos/foo/.git" && cgit_ok letterrc "url=stats/stats/" >tmp && test_grep "" tmp && for off in 0 "" do cgitrc_repo offrc stats max-stats=year "repo.path=$PWD/repos/foo/.git" "repo.max-stats=$off" && cgit_rc offrc "url=stats/stats/" >tmp 2>err && test_grep "^Status: 404" tmp && test_must_be_empty err || return 1 done ' # The error page names the repository alone, so the log gets the path that # would not open, once for the request. The cache stays on, since a fill # rendered a second time is how the path could reach the log twice. test_expect_success 'a repository that will not open is logged with its path' ' mkdir unopened-cache && cgitrc_repo unopenedrc gone cache-size=1021 "cache-root=$PWD/unopened-cache" "repo.path=$PWD/no/such/repo/.git" && cgit_rc unopenedrc "url=gone/log/" >tmp 2>err && grep "^Status: 404 Not Found" tmp && test_grep -F "Unable to open repository gone at $PWD/no/such/repo/.git: No such file or directory" err && test_line_count = 1 err && mkdir not-a-repo && cgitrc_repo notreporc notrepo "repo.path=$PWD/not-a-repo" && cgit_rc notreporc "url=notrepo/" >tmp 2>err && grep "^Status: 404 Not Found" tmp && test_grep -F "Unable to open repository notrepo at $PWD/not-a-repo: " err ' test_done