From 1ecfbfa1a1debd2258decdf7c1954ac6f9761699 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 15 Jul 2020 16:01:03 -0300 Subject: [PATCH] Fixed bug: invalid mode can crash 'io.popen' --- liolib.c | 7 +++++++ testes/files.lua | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/liolib.c b/liolib.c index 7ac34443..60ab1bfa 100644 --- a/liolib.c +++ b/liolib.c @@ -52,6 +52,12 @@ static int l_checkmode (const char *mode) { ** ======================================================= */ +#if !defined(l_checkmodep) +/* By default, Lua accepts only "r" or "w" as mode */ +#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0') +#endif + + #if !defined(l_popen) /* { */ #if defined(LUA_USE_POSIX) /* { */ @@ -279,6 +285,7 @@ static int io_popen (lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *mode = luaL_optstring(L, 2, "r"); LStream *p = newprefile(L); + luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode"); p->f = l_popen(L, filename, mode); p->closef = &io_pclose; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; diff --git a/testes/files.lua b/testes/files.lua index 677c0dc2..16cf9b6a 100644 --- a/testes/files.lua +++ b/testes/files.lua @@ -721,6 +721,21 @@ if not _port then progname = '"' .. arg[i + 1] .. '"' end print("testing popen/pclose and execute") + -- invalid mode for popen + checkerr("invalid mode", io.popen, "cat", "") + checkerr("invalid mode", io.popen, "cat", "r+") + checkerr("invalid mode", io.popen, "cat", "rw") + do -- basic tests for popen + local file = os.tmpname() + local f = assert(io.popen("cat - > " .. file, "w")) + f:write("a line") + assert(f:close()) + local f = assert(io.popen("cat - < " .. file, "r")) + assert(f:read("a") == "a line") + assert(f:close()) + assert(os.remove(file)) + end + local tests = { -- command, what, code {"ls > /dev/null", "ok"},