Fixed bug: invalid mode can crash 'io.popen'
diff --git a/liolib.c b/liolib.c
index 7ac3444..60ab1bf 100644
--- a/liolib.c
+++ b/liolib.c
@@ -52,6 +52,12 @@
** =======================================================
*/
+#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 @@
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 677c0dc..16cf9b6 100644
--- a/testes/files.lua
+++ b/testes/files.lua
@@ -721,6 +721,21 @@
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"},