From 16d949e2596fa56003cf01e3c78fa901e0614c0a Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 25 Dec 2021 18:55:01 -0800 Subject: file open() is now sandboxed In the process we now also have a mechanism for Teliva to overlay errors while apps run. Might make sense to make that available to apps as well. But I'm starting to realize that any app access to the Teliva areas of the screen is fraught with risk. --- src/liolib.c | 17 ++++++++++++++--- src/teliva.c | 33 +++++++++++++++++++++------------ src/teliva.h | 1 + 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/liolib.c b/src/liolib.c index 6092cac..b0148e8 100644 --- a/src/liolib.c +++ b/src/liolib.c @@ -14,9 +14,9 @@ #define LUA_LIB #include "lua.h" - #include "lauxlib.h" #include "lualib.h" +#include "teliva.h" @@ -128,11 +128,17 @@ static int io_tostring (lua_State *L) { } +static char iolib_errbuf[1024] = {0}; static int io_open (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); FILE **pf = newfile(L); - *pf = fopen(filename, mode); + if (file_operations_allowed) + *pf = fopen(filename, mode); + else { + snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename); + Previous_message = iolib_errbuf; + } return (*pf == NULL) ? pushresult(L, 0, filename) : 1; } @@ -164,7 +170,12 @@ static int f_lines (lua_State *L) { static int io_lines (lua_State *L) { const char *filename = luaL_checkstring(L, 1); FILE **pf = newfile(L); - *pf = fopen(filename, "r"); + if (file_operations_allowed) + *pf = fopen(filename, "r"); + else { + snprintf(iolib_errbuf, 1024, "app tried to open file '%s'; adjust its permissions (ctrl-p) if that is expected", filename); + Previous_message = iolib_errbuf; + } if (*pf == NULL) fileerror(L, 1, filename); aux_lines(L, lua_gettop(L), 1); diff --git a/src/teliva.c b/src/teliva.c index f2814c2..1129dc3 100644 --- a/src/teliva.c +++ b/src/teliva.c @@ -32,6 +32,7 @@ void draw_menu_item(const char* key, const char* name) { } static void render_permissions(lua_State* L); +char* Previous_message; static void draw_menu(lua_State* L) { attron(A_BOLD|A_REVERSE); color_set(COLOR_PAIR_MENU, NULL); @@ -42,20 +43,28 @@ static void draw_menu(lua_State* L) { draw_menu_item("^e", "edit"); draw_menu_item("^p", "perms"); - /* render any app-specific items */ - lua_getglobal(L, "menu"); - int table = lua_gettop(L); - if (lua_istable(L, -1)) { - for (int i = 1; i <= luaL_getn(L, table); ++i) { - lua_rawgeti(L, table, i); - int menu_item = lua_gettop(L); - lua_rawgeti(L, menu_item, 1); /* key */ - lua_rawgeti(L, menu_item, 2); /* value */ - draw_menu_item(lua_tostring(L, -2), lua_tostring(L, -1)); - lua_pop(L, 3); + /* if app ran successfully, render any app-specific items */ + if (Previous_message == NULL) { + lua_getglobal(L, "menu"); + int table = lua_gettop(L); + if (lua_istable(L, -1)) { + for (int i = 1; i <= luaL_getn(L, table); ++i) { + lua_rawgeti(L, table, i); + int menu_item = lua_gettop(L); + lua_rawgeti(L, menu_item, 1); /* key */ + lua_rawgeti(L, menu_item, 2); /* value */ + draw_menu_item(lua_tostring(L, -2), lua_tostring(L, -1)); + lua_pop(L, 3); + } } + lua_pop(L, 1); + } + else { + /* otherwise render the flash message */ + attron(COLOR_PAIR(COLOR_PAIR_ERROR)); + addstr(Previous_message); + attroff(COLOR_PAIR(COLOR_PAIR_ERROR)); } - lua_pop(L, 1); /* render app permissions on the right */ render_permissions(L); diff --git a/src/teliva.h b/src/teliva.h index bf01c11..42ebdc7 100644 --- a/src/teliva.h +++ b/src/teliva.h @@ -151,6 +151,7 @@ enum color_pair { /* Integrate with Lua VM */ extern char** Argv; +extern char* Previous_message; extern int handle_image(lua_State* L, char** argv, int n); extern void developer_mode(lua_State* L); extern void permissions_mode(lua_State* L); -- cgit 1.4.1-2-gfad0