Skip to content

tests/lapi: add io tests #140

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions tests/lapi/io_lines_test.lua
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If str contains ]] this string becomes invalid.

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)
34 changes: 34 additions & 0 deletions tests/lapi/io_popen_test.lua
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If str contains ]] this string becomes invalid.

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)
34 changes: 34 additions & 0 deletions tests/lapi/io_read_test.lua
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get the idea of the following test, please add the comment.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is the following create IO object and make random operations with it (read, write, seek)

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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the expected behaviour if returned string str == "abc".

local fh = io.popen(lua_cmd, "w")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we use "w" mode if we read data from that program?

local mode = fdp:oneof(READ_MODE)
local cur_pos = fh:seek()
fh:seek("end")
fh:seek("set", cur_pos)
fh:read(mode)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got the following return values for this read.

nil     Bad file descriptor     9

fh:flush()
fh:close()
end

local args = {
artifact_prefix = "io_read_",
}
luzer.Fuzz(TestOneInput, nil, args)
10 changes: 10 additions & 0 deletions tests/lapi/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down