From eb56c5e699de4481e54cc1b7841523af3009befe Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Thu, 16 Jan 2025 10:55:41 +0300 Subject: [PATCH] tests/lapi add io tests The functions below are not covered: `io.close()`, `io.flush()`, `io.input()`, `io.open()`, `io.output()`, `io.tmpfile()`, `io.type()`, `io.write()`, `file:close()`, `file:flush()`, `file:lines()`, `file:read()`, `file:seek()`, `file:setvbuf()`, `file:write()`. --- tests/lapi/io_lines_test.lua | 35 +++++++++++++++++++++++++++++++++++ tests/lapi/io_popen_test.lua | 34 ++++++++++++++++++++++++++++++++++ tests/lapi/io_read_test.lua | 34 ++++++++++++++++++++++++++++++++++ tests/lapi/lib.lua | 10 ++++++++++ 4 files changed, 113 insertions(+) create mode 100644 tests/lapi/io_lines_test.lua create mode 100644 tests/lapi/io_popen_test.lua create mode 100644 tests/lapi/io_read_test.lua diff --git a/tests/lapi/io_lines_test.lua b/tests/lapi/io_lines_test.lua new file mode 100644 index 0000000..e644990 --- /dev/null +++ b/tests/lapi/io_lines_test.lua @@ -0,0 +1,35 @@ +--[[ +SPDX-License-Identifier: ISC +Copyright (c) 2023-2025, Sergey Bronnikov. + +5.7 – Input and Output Facilities +https://www.lua.org/manual/5.1/manual.html#5.7 +https://www.lua.org/pil/21.1.html + +Does io.lines() stream or slurp the file? +https://stackoverflow.com/questions/43005068/does-io-lines-stream-or-slurp-the-file + +io.lines does not check maximum number of options, +https://www.lua.org/bugs.html#5.3.1-1 + +Synopsis: io.lines([filename, ...]) +]] + +local luzer = require("luzer") +local test_lib = require("lib") + +local function TestOneInput(buf) + local fdp = luzer.FuzzedDataProvider(buf) + local str = fdp:consume_string(test_lib.MAX_STR_LEN) + local lua_chunk = ("io.write([[%s]])"):format(str) + local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), lua_chunk) + local fh = assert(io.popen(lua_cmd)) + fh:lines("*all") + fh:flush() + fh:close() +end + +local args = { + artifact_prefix = "io_lines_", +} +luzer.Fuzz(TestOneInput, nil, args) diff --git a/tests/lapi/io_popen_test.lua b/tests/lapi/io_popen_test.lua new file mode 100644 index 0000000..43d7d3b --- /dev/null +++ b/tests/lapi/io_popen_test.lua @@ -0,0 +1,34 @@ +--[[ +SPDX-License-Identifier: ISC +Copyright (c) 2023-2025, Sergey Bronnikov. + +5.7 – Input and Output Facilities +https://www.lua.org/manual/5.1/manual.html#5.7 + +'popen' can crash if called with an invalid mode, +https://github.com/lua/lua/commit/1ecfbfa1a1debd2258decdf7c1954ac6f9761699 + +On some machines, closing a "piped file" (created with io.popen) may crash Lua, +https://www.lua.org/bugs.html#5.0.2-8 + +Synopsis: io.popen(prog [, mode]) +]] + +local luzer = require("luzer") +local test_lib = require("lib") + +local function TestOneInput(buf) + local fdp = luzer.FuzzedDataProvider(buf) + local str = fdp:consume_string(test_lib.MAX_STR_LEN) + local lua_chunk = ("io.write([[%s]])"):format(str) + local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), lua_chunk) + local fh = assert(io.popen(lua_cmd, "r")) + fh:lines("*all") + fh:flush() + fh:close() +end + +local args = { + artifact_prefix = "io_popen_", +} +luzer.Fuzz(TestOneInput, nil, args) diff --git a/tests/lapi/io_read_test.lua b/tests/lapi/io_read_test.lua new file mode 100644 index 0000000..d07fa97 --- /dev/null +++ b/tests/lapi/io_read_test.lua @@ -0,0 +1,34 @@ +--[[ +SPDX-License-Identifier: ISC +Copyright (c) 2023-2025, Sergey Bronnikov. + +5.7 – Input and Output Facilities +https://www.lua.org/manual/5.1/manual.html#5.7 +https://www.lua.org/pil/21.3.html + +Synopsis: io.read(...) +]] + +local luzer = require("luzer") +local test_lib = require("lib") + +local READ_MODE = { "*n", "*a", "*l" } + +local function TestOneInput(buf) + local fdp = luzer.FuzzedDataProvider(buf) + local str = fdp:consume_string(test_lib.MAX_STR_LEN) + local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), str) + local fh = io.popen(lua_cmd, "w") + local mode = fdp:oneof(READ_MODE) + local cur_pos = fh:seek() + fh:seek("end") + fh:seek("set", cur_pos) + fh:read(mode) + fh:flush() + fh:close() +end + +local args = { + artifact_prefix = "io_read_", +} +luzer.Fuzz(TestOneInput, nil, args) diff --git a/tests/lapi/lib.lua b/tests/lapi/lib.lua index c4bb890..d406cd8 100644 --- a/tests/lapi/lib.lua +++ b/tests/lapi/lib.lua @@ -119,11 +119,21 @@ local function arrays_equal(t1, t2) return #t1 == #t2 end +local function luabin(argv) + -- arg[-1] is guaranteed to be not nil. + local idx = -2 + while argv[idx] do + idx = idx - 1 + end + return argv[idx + 1] +end + return { approx_equal = approx_equal, arrays_equal = arrays_equal, bitwise_op = bitwise_op, err_handler = err_handler, + luabin = luabin, lua_current_version_ge_than = lua_current_version_ge_than, lua_current_version_lt_than = lua_current_version_lt_than, lua_version = lua_version,