drop io.lines()

I'd already dropped the variant without a filename. But even the variant
with a filename is very easy to use in a way that is confusing to use in
the presence of sandboxing:

* call io.lines()
* Sandboxing saves an error, io.lines() returns nil
* Caller (usually a loop) raises an error.
* We show the error and not the sandboxing failure.
* Worse, there's no way to adjust permissions from within Teliva,
  because we can't ever get to that menu while there's an error.

Best solution I can come up with: encourage a separate step for
translating filename to file handle. That way it's more obvious that we
need to check for errors.
This commit is contained in:
Kartik K. Agaram 2022-02-02 23:44:25 -08:00
parent 8f8a0e5a18
commit a8dfea1d3c
2 changed files with 5 additions and 40 deletions

View File

@ -160,22 +160,13 @@
> while (os.clock() < sec) do
> end
>end
- __teliva_timestamp: original
file_exists:
>function file_exists(filename)
> local f = io.open(filename, "r")
> if f ~= nil then
> io.close(f)
> return true
> else
> return false
> end
>end
- __teliva_timestamp: original
load_file:
>function load_file(window, filename)
> local infile = io.open(filename, 'r')
> if infile == nil then return end
> local line_index = lines
> for line in io.lines(filename) do
> for line in infile:lines() do
> if line:sub(1,1) ~= '!' then -- comment; plaintext files can't have whitespace before comments
> local col_index = cols
> for c in line:gmatch(".") do
@ -286,7 +277,7 @@
> grid[8][5] = 1
> grid[7][4] = 1
> grid[6][3] = 1
> elseif file_exists(arg[1]) then
> else
> -- Load a file in the standard "plaintext" format: https://www.conwaylife.com/wiki/Plaintext
> --
> -- Each pattern page at https://www.conwaylife.com/wiki provides its

View File

@ -38,12 +38,6 @@ static int pushresult (lua_State *L, int i, const char *filename) {
}
static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, "%s: %s", filename, strerror(errno));
luaL_argerror(L, arg, lua_tostring(L, -1));
}
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
@ -171,26 +165,6 @@ 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);
static char buffer[1024] = {0};
memset(buffer, '\0', 1024);
snprintf(buffer, 1020, "io.lines(\"%s\")", filename);
append_to_audit_log(L, buffer);
if (file_operation_permitted(caller(L), filename, "r"))
*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);
return 1;
}
/*
** {======================================================
** READ
@ -393,7 +367,7 @@ static const luaL_Reg iolib[] = {
{"close", io_close},
/* no 'flush' since Teliva is ncurses-based */
/* no 'input' since Teliva is ncurses-based */
{"lines", io_lines},
/* no 'io.lines'; it can confusingly fail without showing sandboxing errors */
{"open", io_open},
/* no 'output' since Teliva is ncurses-based */
/* no 'popen' without sandboxing it */