From 61d3eafe98847b9a76ddc04fe7a4f63f341961a4 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sun, 6 Sep 2026 21:40:19 -1000 Subject: Harden the lua filter failure paths --- source/filter.c | 14 +++++++++----- tests/t0201-filters.sh | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/source/filter.c b/source/filter.c index f5f971c..a7efe56 100644 --- a/source/filter.c +++ b/source/filter.c @@ -173,6 +173,11 @@ static inline void unhook_write(void) static NORETURN void die_lua_error(struct lua_filter *filter) { + // The error page goes out through stdout, which may still be hooked + // to the very filter that failed, so the hook comes off first or the + // page would be fed back into the broken filter. + if (filter_write) + unhook_write(); die("Lua error in %s: %s", filter->script_file, lua_tostring(filter->lua_state, -1)); } @@ -336,11 +341,10 @@ static void cleanup_lua_filter(struct cgit_filter *base) { struct lua_filter *filter = (struct lua_filter *)base; - if (!filter->lua_state) - return; - - lua_close(filter->lua_state); - filter->lua_state = NULL; + if (filter->lua_state) { + lua_close(filter->lua_state); + filter->lua_state = NULL; + } free(filter->script_file); filter->script_file = NULL; } diff --git a/tests/t0201-filters.sh b/tests/t0201-filters.sh index a8341aa..8d67c4f 100755 --- a/tests/t0201-filters.sh +++ b/tests/t0201-filters.sh @@ -65,4 +65,26 @@ do " done +test "$CGIT_HAS_LUA" -eq 1 && test_set_prereq CGIT_LUA +test "$CGIT_HAS_LUA" -eq 1 || say 'cgit built without lua, error page check skipped' + +# A die inside a lua filter has to reach the visitor as an error page rather +# than being fed back into the filter that just failed. +test_expect_success CGIT_LUA 'a failing lua filter still renders an error page' ' + cat >broken.lua <<-\EOF && + function filter_open(...) error("boom") end + function filter_write(str) end + function filter_close() return 0 end + EOF + { + echo "cache-size=0" && + echo "repo.url=foo" && + echo "repo.path=$PWD/repos/foo/.git" && + echo "auth-filter=lua:$PWD/broken.lua" + } >brokenrc && + CGIT_CONFIG="$PWD/brokenrc" QUERY_STRING="url=foo/commit" cgit >tmp && + grep "Status: 400" tmp && + grep "Lua error in" tmp +' + test_done -- cgit v2.8.0