diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Harden the lua filter failure paths
Diffstat (limited to '')
-rw-r--r--source/filter.c14
-rwxr-xr-xtests/t0201-filters.sh22
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