diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Name every Lua filter failure in the log
A script raising anything but a string handed die a null to print, and
a Lua state that could not be created was used anyway once the filter
closed.
Diffstat (limited to '')
| -rw-r--r-- | source/filter.c | 26 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rwxr-xr-x | tests/t0201-filters.sh | 13 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 files changed, 30 insertions, 9 deletions
diff --git a/source/filter.c b/source/filter.c index b36f03e..43ba70a 100644 --- a/source/filter.c +++ b/source/filter.c @@ -191,12 +191,20 @@ static inline void unhook_write(void) static NORETURN void die_lua_error(struct lua_filter *filter) { + lua_State *lua_state = filter->lua_state; + const char *message = lua_tostring(lua_state, -1); + + // A script may raise any value, and only a string or a number has text + // of its own, so anything else is named by its type, as lua.c does. + if (!message) + message = lua_pushfstring(lua_state, "(error object is a %s value)", + luaL_typename(lua_state, -1)); // 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)); + die("Lua error in %s: %s", filter->script_file, message); } static ssize_t write_lua_filter(struct cgit_filter *base, const void *buf, size_t count) @@ -294,15 +302,18 @@ static const struct { { "html_include", script_html_include }, }; -static int init_lua_filter(struct lua_filter *filter) +static void init_lua_filter(struct lua_filter *filter) { size_t i; if (filter->lua_state) - return 0; + return; - if (!(filter->lua_state = luaL_newstate())) - return 1; + // A new state fails only when memory has run out, which cgit answers by + // dying wherever else it allocates. + filter->lua_state = luaL_newstate(); + if (!filter->lua_state) + die("Unable to create a Lua state for %s", filter->script_file); luaL_openlibs(filter->lua_state); @@ -313,7 +324,6 @@ static int init_lua_filter(struct lua_filter *filter) if (luaL_dofile(filter->lua_state, filter->script_file)) die_lua_error(filter); - return 0; } static int open_lua_filter(struct cgit_filter *base, va_list ap) @@ -321,9 +331,7 @@ static int open_lua_filter(struct cgit_filter *base, va_list ap) struct lua_filter *filter = (struct lua_filter *)base; int i; - if (init_lua_filter(filter)) - return 1; - + init_lua_filter(filter); hook_write(base, write_lua_filter); lua_getglobal(filter->lua_state, "filter_open"); diff --git a/tests/t0201-filters.sh b/tests/t0201-filters.sh index c2d0ec4..1ffb973 100755 --- a/tests/t0201-filters.sh +++ b/tests/t0201-filters.sh @@ -130,6 +130,19 @@ test_expect_success CGIT_LUA 'a failing lua filter still renders an error page' grep "Lua error in" err ' +# A script may raise a value that is no string, which the log still names. +test_expect_success CGIT_LUA 'a lua filter raising a table is named by type' ' + cat >tabled.lua <<-\EOF && + function filter_open(...) error({}) end + function filter_write(str) end + function filter_close() return 0 end + EOF + sed "s|broken.lua|tabled.lua|" brokenrc >tabledrc && + CGIT_CONFIG="$PWD/tabledrc" QUERY_STRING="url=foo/commit" cgit >tmp 2>err && + grep "Status: 500" tmp && + grep "Lua error in .*tabled.lua: (error object is a table value)" err +' + # A script runs its top level before cgit hooks stdout for it, so what it # writes there goes straight onto the page instead of tripping the hook. test_expect_success CGIT_LUA 'a lua filter that writes while loading still renders' ' |
