Skip to content

Commit 6b1f609

Browse files
committed
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()`.
1 parent 8ef72ef commit 6b1f609

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

tests/lapi/io_lines_test.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
5.7 – Input and Output Facilities
6+
https://www.lua.org/manual/5.1/manual.html#5.7
7+
https://www.lua.org/pil/21.1.html
8+
9+
Does io.lines() stream or slurp the file?
10+
https://stackoverflow.com/questions/43005068/does-io-lines-stream-or-slurp-the-file
11+
12+
io.lines does not check maximum number of options,
13+
https://www.lua.org/bugs.html#5.3.1-1
14+
15+
Synopsis: io.lines([filename, ...])
16+
]]
17+
18+
local luzer = require("luzer")
19+
local test_lib = require("lib")
20+
21+
local function TestOneInput(buf)
22+
local fdp = luzer.FuzzedDataProvider(buf)
23+
local str = fdp:consume_string(test_lib.MAX_STR_LEN)
24+
local lua_chunk = ("io.write([[%s]])"):format(str)
25+
local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), lua_chunk)
26+
local fh = assert(io.popen(lua_cmd))
27+
fh:lines("*all")
28+
fh:flush()
29+
fh:close()
30+
end
31+
32+
local args = {
33+
artifact_prefix = "io_lines_",
34+
}
35+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/io_popen_test.lua

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
5.7 – Input and Output Facilities
6+
https://www.lua.org/manual/5.1/manual.html#5.7
7+
8+
'popen' can crash if called with an invalid mode,
9+
https://github.com/lua/lua/commit/1ecfbfa1a1debd2258decdf7c1954ac6f9761699
10+
11+
On some machines, closing a "piped file" (created with io.popen) may crash Lua,
12+
https://www.lua.org/bugs.html#5.0.2-8
13+
14+
Synopsis: io.popen(prog [, mode])
15+
]]
16+
17+
local luzer = require("luzer")
18+
local test_lib = require("lib")
19+
20+
local function TestOneInput(buf)
21+
local fdp = luzer.FuzzedDataProvider(buf)
22+
local str = fdp:consume_string(test_lib.MAX_STR_LEN)
23+
local lua_chunk = ("io.write([[%s]])"):format(str)
24+
local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), lua_chunk)
25+
local fh = assert(io.popen(lua_cmd))
26+
fh:lines("*all")
27+
fh:flush()
28+
fh:close()
29+
end
30+
31+
local args = {
32+
artifact_prefix = "io_popen_",
33+
}
34+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/io_read_test.lua

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
5.7 – Input and Output Facilities
6+
https://www.lua.org/manual/5.1/manual.html#5.7
7+
https://www.lua.org/pil/21.3.html
8+
9+
Synopsis: io.read(...)
10+
]]
11+
12+
local luzer = require("luzer")
13+
local test_lib = require("lib")
14+
15+
local READ_MODE = { "*n", "*a", "*l" }
16+
17+
local function TestOneInput(buf)
18+
local fdp = luzer.FuzzedDataProvider(buf)
19+
local str = fdp:consume_string(test_lib.MAX_STR_LEN)
20+
local lua_cmd = ("%s -e '%s'"):format(test_lib.luabin(arg), str)
21+
local fh = io.popen(lua_cmd, "w")
22+
local mode = fdp:oneof(READ_MODE)
23+
local cur_pos = fh:seek()
24+
fh:seek("end")
25+
fh:seek("set", cur_pos)
26+
fh:read(mode)
27+
fh:flush()
28+
fh:close()
29+
end
30+
31+
local args = {
32+
artifact_prefix = "io_read_",
33+
}
34+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/lib.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,19 @@ local function random_locale(fdp)
9696
return fdp:oneof(locales)
9797
end
9898

99+
local function luabin(argv)
100+
-- arg[-1] is guaranteed to be not nil.
101+
local idx = -2
102+
while argv[idx] do
103+
idx = idx - 1
104+
end
105+
return argv[idx + 1]
106+
end
107+
99108
return {
100109
approx_equal = approx_equal,
101110
bitwise_op = bitwise_op,
111+
luabin = luabin,
102112
lua_version = lua_version,
103113
lua_current_version_ge_than = lua_current_version_ge_than,
104114
lua_current_version_lt_than = lua_current_version_lt_than,

0 commit comments

Comments
 (0)