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:
parent
8f8a0e5a18
commit
a8dfea1d3c
17
life.tlv
17
life.tlv
|
@ -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
|
||||
|
|
28
src/liolib.c
28
src/liolib.c
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue