浏览代码

Fixed bug: invalid mode can crash 'io.popen'

Roberto Ierusalimschy 5 年之前
父节点
当前提交
1ecfbfa1a1
共有 2 个文件被更改,包括 22 次插入0 次删除
  1. 7 0
      liolib.c
  2. 15 0
      testes/files.lua

+ 7 - 0
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;

+ 15 - 0
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"},