Skip to content

Commit 33941a1

Browse files
committed
tests/lapi: add debug tests
1 parent bfac9d7 commit 33941a1

File tree

3 files changed

+165
-0
lines changed

3 files changed

+165
-0
lines changed

tests/lapi/debug_getinfo_test.lua

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
Parameter 'what' of 'debug.getinfo' cannot start with '>',
6+
https://www.lua.org/bugs.html#5.4.2-2
7+
8+
Access to debug information in line hook of stripped function,
9+
https://github.com/lua/lua/commit/ae5b5ba529753c7a653901ffc29b5ea24c3fdf3a
10+
11+
Return hook may not see correct values for active local variables when function returns,
12+
https://www.lua.org/bugs.html#5.3.0-4
13+
14+
The PC out-of-range in lj_debug_frameline(),
15+
https://github.com/LuaJIT/LuaJIT/issues/1369
16+
17+
LuaJIT segfault in debug.getinfo(),
18+
https://github.com/LuaJIT/LuaJIT/issues/509
19+
20+
Synopsis: debug.getinfo([thread,] function [, what])
21+
]]
22+
23+
local luzer = require("luzer")
24+
25+
local what = {
26+
"n", -- fills in the field name and namewhat.
27+
"S", -- fills in the fields source, short_src, linedefined,
28+
-- lastlinedefined, and what.
29+
"l", -- fills in the field currentline.
30+
"u", -- fills in the field nups.
31+
"f", -- pushes onto the stack the function that is running at
32+
-- the given level.
33+
"L", -- pushes onto the stack a table whose indices are the
34+
-- numbers of the lines that are valid on the function.
35+
}
36+
37+
local what_modes
38+
39+
local hook_mask = {
40+
"c", -- the hook is called every time Lua calls a function.
41+
"r", -- the hook is called every time Lua returns from a function.
42+
"l", -- the hook is called every time Lua enters a new line of code.
43+
}
44+
45+
local loadstring = type(loadstring) == "function" and loadstring or load
46+
47+
local function debug_hook()
48+
debug.getinfo(1, table.concat(what_modes))
49+
end
50+
51+
local function TestOneInput(buf)
52+
local fdp = luzer.FuzzedDataProvider(buf)
53+
54+
-- Generate a random 'what'.
55+
what_modes = {}
56+
local n_modes = fdp:consume_integer(0, #what)
57+
for _ = 0, n_modes do
58+
table.insert(what_modes, fdp:oneof(what))
59+
end
60+
61+
-- Generate a random hook mask.
62+
local n_hook_mask = fdp:consume_integer(0, #hook_mask)
63+
local mask = {}
64+
for _ = 0, n_hook_mask do
65+
table.insert(mask, fdp:oneof(hook_mask))
66+
end
67+
68+
debug.sethook(debug_hook, table.concat(mask))
69+
assert(loadstring(buf))()
70+
debug.sethook() -- Turn off the hook.
71+
end
72+
73+
local args = {
74+
artifact_prefix = "debug_getinfo_",
75+
}
76+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/debug_getlocal_test.lua

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
Negation overflow in getlocal/setlocal,
6+
https://github.com/lua/lua/commit/a585eae6e7ada1ca9271607a4f48dfb17868ab7b
7+
8+
debug.getlocal on a coroutine suspended in a hook can crash the interpreter,
9+
https://www.lua.org/bugs.html#5.3.0-2
10+
11+
Synopsis: debug.getlocal([thread,] level, local)
12+
]]
13+
14+
local luzer = require("luzer")
15+
16+
local function debug_hook()
17+
-- TODO: getlocal
18+
end
19+
20+
local loadstring = type(loadstring) == "function" and loadstring or load
21+
22+
local hook_mask = {
23+
"c", -- the hook is called every time Lua calls a function.
24+
"r", -- the hook is called every time Lua returns from a function.
25+
"l", -- the hook is called every time Lua enters a new line of code.
26+
}
27+
28+
local function TestOneInput(buf)
29+
local fdp = luzer.FuzzedDataProvider(buf)
30+
31+
-- Generate a random hook mask.
32+
local n_hook_mask = fdp:consume_integer(0, #hook_mask)
33+
local mask = {}
34+
for _ = 0, n_hook_mask do
35+
table.insert(mask, fdp:oneof(hook_mask))
36+
end
37+
38+
debug.sethook(debug_hook, table.concat(mask))
39+
assert(loadstring(buf))()
40+
debug.sethook() -- Turn off the hook.
41+
end
42+
43+
local args = {
44+
artifact_prefix = "debug_getlocal_",
45+
}
46+
luzer.Fuzz(TestOneInput, nil, args)

tests/lapi/debug_getupvalue_test.lua

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--[[
2+
SPDX-License-Identifier: ISC
3+
Copyright (c) 2023-2025, Sergey Bronnikov.
4+
5+
lua_getupvalue and lua_setupvalue do not check for index too small,
6+
https://www.lua.org/bugs.html#5.0.2-2
7+
8+
Synopsis: debug.getupvalue (f, up)
9+
]]
10+
11+
local luzer = require("luzer")
12+
13+
local function debug_hook()
14+
-- TODO: getupvalue
15+
end
16+
17+
local loadstring = type(loadstring) == "function" and loadstring or load
18+
19+
local hook_mask = {
20+
"c", -- the hook is called every time Lua calls a function.
21+
"r", -- the hook is called every time Lua returns from a function.
22+
"l", -- the hook is called every time Lua enters a new line of code.
23+
}
24+
25+
local function TestOneInput(buf)
26+
local fdp = luzer.FuzzedDataProvider(buf)
27+
28+
-- Generate a random hook mask.
29+
local n_hook_mask = fdp:consume_integer(0, #hook_mask)
30+
local mask = {}
31+
for _ = 0, n_hook_mask do
32+
table.insert(mask, fdp:oneof(hook_mask))
33+
end
34+
35+
debug.sethook(debug_hook, table.concat(mask))
36+
assert(loadstring(buf))()
37+
debug.sethook() -- Turn off the hook.
38+
end
39+
40+
local args = {
41+
artifact_prefix = "debug_getupvalue_",
42+
}
43+
luzer.Fuzz(TestOneInput, nil, args)

0 commit comments

Comments
 (0)