vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit 0fb3088b544c6ce92c7d5ba962aed6842b291ed6
parent e51190ca3df5e8ec9ced3493eda8017447d18973
Author: Randy Palamar <palamar@ualberta.ca>
Date:   Mon,  3 Jul 2023 00:35:29 -0600

vis:pipe(): don't segfault if vis->win isn't present

When `file` was made optional the variable was changed to be initialized
by `vis->win->file` instead of a known safe file pointer. If `vis:pipe()`
is called based on the event `FILE_OPEN` the `file` parameter can be
valid even when `vis->win` is not yet present. Assuming `file` was
provided this would be handled later on if vis didn't segfault. By
initializing to NULL when `vis->win` isn't present `file` is given
a chance be handled later. In the case where `file` wasn't given and
`vis->win` is missing an error is thrown and `vis:pipe()` exits.

fixes #1107 - Lua API: vis:pipe() causes a segfault when called before
a window is open

Diffstat:
Mvis-lua.c | 6+++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/vis-lua.c b/vis-lua.c @@ -1340,7 +1340,7 @@ static int pipe_func(lua_State *L) { Vis *vis = obj_ref_check(L, 1, "vis"); int cmd_idx = 4; char *out = NULL, *err = NULL; - File *file = vis->win->file; + File *file = vis->win ? vis->win->file : NULL; Filerange range = text_range_new(0, 0); if (lua_gettop(L) <= 3) { cmd_idx = 2; @@ -1350,6 +1350,10 @@ static int pipe_func(lua_State *L) { } const char *cmd = luaL_checkstring(L, cmd_idx); bool fullscreen = lua_isboolean(L, cmd_idx + 1) && lua_toboolean(L, cmd_idx + 1); + + if (!file) + return luaL_error(L, "vis:pipe(cmd = '%s'): win not open, file can't be nil", cmd); + int status = vis_pipe_collect(vis, file, &range, (const char*[]){ cmd, NULL }, &out, &err, fullscreen); lua_pushinteger(L, status); if (out)