Skip to content

tests/lapi: table tests #142

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

Merged
merged 1 commit into from
Jul 28, 2025
Merged
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
10 changes: 10 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,13 @@ files["tests/capi/luaL_loadbuffer_proto/preamble.lua"] = {
"211",
},
}

-- The new function introduced in the Lua 5.5, it is not yet
-- supported by the luacheck, see [1].
--
-- 1. https://github.com/lunarmodules/luacheck/issues/132
globals = {
table = {
fields = { "create" }
}
}
15 changes: 15 additions & 0 deletions tests/lapi/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,23 @@ local function err_handler(ignored_msgs)
end
end

local function is_nan(v)
return v ~= v
end

local function arrays_equal(t1, t2)
for i = 1, #t1 do
if t1[i] ~= t2[i] and
not (is_nan(t1[i]) and is_nan(t2[i])) then
return false
end
end
return #t1 == #t2
end

return {
approx_equal = approx_equal,
arrays_equal = arrays_equal,
bitwise_op = bitwise_op,
err_handler = err_handler,
lua_current_version_ge_than = lua_current_version_ge_than,
Expand Down
40 changes: 40 additions & 0 deletions tests/lapi/table_concat_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--[=[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

5.5 – Table Manipulation,
https://www.lua.org/manual/5.1/manual.html#5.5

Infinite loop on table lookup,
https://github.com/LuaJIT/LuaJIT/issues/494

Synopsis: table.concat(list [, sep [, i [, j]]])
--]=]

local luzer = require("luzer")
local test_lib = require("lib")

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local str = fdp:consume_string(test_lib.MAX_STR_LEN)
local tbl_size = #str
if tbl_size == 0 then return -1 end

-- Split string to a table.
local tbl = {}
str:gsub(".", function(c)
table.insert(tbl, c)
end)
assert(#tbl == tbl_size)

-- Join table to a string.
local j = fdp:consume_integer(1, tbl_size)
local i = fdp:consume_integer(1, j)
local sep = ""
assert(string.sub(str, i, j) == table.concat(tbl, sep, i, j))
end

local args = {
artifact_prefix = "table_concat_",
}
luzer.Fuzz(TestOneInput, nil, args)
40 changes: 40 additions & 0 deletions tests/lapi/table_create_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

Bad lookup generated by lj_record_idx in GC64,
https://github.com/LuaJIT/LuaJIT/issues/840

Synopsis:
LuaJIT: table.new(narray, nhash)
PUC Rio Lua: table.create(narray, nhash)
]]

local luzer = require("luzer")
local test_lib = require("lib")

local table_create
if test_lib.lua_version() == "LuaJIT" then
table_create = require("table.new")
elseif test_lib.lua_current_version_ge_than(5, 5) then
-- New function 'table.create()' in PUC Rio Lua,
-- https://github.com/lua/lua/commit/3e9dbe143d3338f5f13a5e421ea593adff482da0
table_create = table.create
else
print("Unsupported version.")
os.exit(0)
end

local function TestOneInput(buf)
local fdp = luzer.FuzzedDataProvider(buf)
-- Beware, huge number triggers OOM or table overflow.
local MAX_N = 1000
local narray = fdp:consume_integer(0, MAX_N)
local nhash = fdp:consume_integer(0, MAX_N)
local _ = table_create(narray, nhash) -- luacheck: no unused
end

local args = {
artifact_prefix = "table_create_",
}
luzer.Fuzz(TestOneInput, nil, args)
39 changes: 39 additions & 0 deletions tests/lapi/table_foreach_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

5.4 – Table Manipulation,
https://www.lua.org/manual/5.0/manual.html#5.4

Bad loop initialization in table.foreach(),
https://github.com/LuaJIT/LuaJIT/issues/844

string.dump(table.foreach) will trigger an assert,
https://github.com/LuaJIT/LuaJIT/issues/1038

Synopsis: table.foreach(table, f)
]]

local luzer = require("luzer")
local test_lib = require("lib")

-- Function `table.foreach` is deprecated in Lua 5.1.
if test_lib.lua_current_version_ge_than(5, 2) then
print("Unsupported version.")
os.exit(0)
end

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local count = fdp:consume_integer(1, test_lib.MAX_INT)
local tbl = fdp:consume_strings(test_lib.MAX_STR_LEN, count)
local i = 0
local fn = function(_idx, _v) i = i + 1 end
table.foreach(tbl, fn)
assert(#tbl == i)
end

local args = {
artifact_prefix = "table_foreach_",
}
luzer.Fuzz(TestOneInput, nil, args)
33 changes: 33 additions & 0 deletions tests/lapi/table_foreachi_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

5.4 – Table Manipulation,
https://www.lua.org/manual/5.0/manual.html#5.4

Synopsis: table.foreachi(table, f)
]]

local luzer = require("luzer")
local test_lib = require("lib")

-- Function `table.foreach` is deprecated in Lua 5.1.
if test_lib.lua_current_version_ge_than(5, 2) then
print("Unsupported version.")
os.exit(0)
end

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local count = fdp:consume_integer(1, test_lib.MAX_INT)
local tbl = fdp:consume_strings(test_lib.MAX_STR_LEN, count)
local i = 0
local fn = function(_idx, _v) i = i + 1 end
table.foreachi(tbl, fn)
assert(#tbl == i)
end

local args = {
artifact_prefix = "table_foreachi_",
}
luzer.Fuzz(TestOneInput, nil, args)
36 changes: 36 additions & 0 deletions tests/lapi/table_insert_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2024, Sergey Bronnikov.

5.5 – Table Manipulation,
https://www.lua.org/manual/5.1/manual.html#5.5

Synopsis: table.insert(list, [pos,] value)
]]

local luzer = require("luzer")
local test_lib = require("lib")

local MAX_INT = test_lib.MAX_INT

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local str = fdp:consume_string(test_lib.MAX_STR_LEN)
local tbl = {}
str:gsub(".", function(c)
-- The `pos` value cannot be negative in PUC Rio Lua 5.2+
-- and in LuaJIT `table.insert()` works too slow with huge
-- `pos` values.
local MAX_POS = #tbl + 1
if test_lib.lua_version() == "LuaJIT" then
MAX_POS = MAX_INT
end
local pos = fdp:consume_integer(1, MAX_POS)
table.insert(tbl, pos, c)
end)
end

local args = {
artifact_prefix = "table_insert_",
}
luzer.Fuzz(TestOneInput, nil, args)
30 changes: 30 additions & 0 deletions tests/lapi/table_maxn_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

5.5 – Table Manipulation,
https://www.lua.org/manual/5.1/manual.html#5.5

Synopsis: table.maxn(table)
]]

local luzer = require("luzer")
local test_lib = require("lib")

if test_lib.lua_current_version_ge_than(5, 3) then
print("Unsupported version.")
os.exit(0)
end

local function TestOneInput(buf)
local fdp = luzer.FuzzedDataProvider(buf)
local count = fdp:consume_integer(0, test_lib.MAX_INT64)
local tbl = fdp:consume_strings(test_lib.MAX_STR_LEN, count)
local maxn = table.maxn(tbl)
assert(maxn == #tbl)
end

local args = {
artifact_prefix = "table_maxn_",
}
luzer.Fuzz(TestOneInput, nil, args)
38 changes: 38 additions & 0 deletions tests/lapi/table_move_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

6.6 – Table Manipulation,
https://www.lua.org/manual/5.3/manual.html#6.6

Synopsis: table.move(a1, f, e, t [,a2])
]]

local luzer = require("luzer")
local test_lib = require("lib")

if test_lib.lua_current_version_lt_than(5, 3) and
test_lib.lua_version == "PUC Rio Lua" then
print("Unsupported version.")
os.exit(0)
end

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local count = fdp:consume_integer(0, test_lib.MAX_INT)
local a1 = fdp:consume_strings(test_lib.MAX_STR_LEN, count)
local a2 = {}
-- Move random items from the table `a1` to the table `a2`.
-- Beware, `table.move()` works too slow with huge numbers.
local MAX_N = 1000
local f = fdp:consume_integer(-MAX_N, MAX_N)
local e = fdp:consume_integer(-MAX_N, MAX_N)
local t = fdp:consume_integer(-MAX_N, MAX_N)
local res = table.move(a1, f, e, t, a2)
assert(test_lib.arrays_equal(a2, res))
end

local args = {
artifact_prefix = "table_move_",
}
luzer.Fuzz(TestOneInput, nil, args)
35 changes: 35 additions & 0 deletions tests/lapi/table_pack_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.

6.5 – Table Manipulation,
https://www.lua.org/manual/5.2/manual.html#6.5

Synopsis: table.pack(...)
]]

local luzer = require("luzer")
local test_lib = require("lib")

if test_lib.lua_current_version_lt_than(5, 2) then
print("Unsupported version.")
os.exit(0)
end

local unpack = unpack or table.unpack

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
-- Beware, huge number triggers 'too many results to unpack'.
local MAX_N = 1000
local count = fdp:consume_integer(1, MAX_N)
local tbl = fdp:consume_integers(test_lib.MIN_INT, test_lib.MAX_INT, count)
local packed = table.pack(unpack(tbl))
assert(#packed == #tbl)
assert(test_lib.arrays_equal(packed, tbl))
end

local args = {
artifact_prefix = "table_pack_",
}
luzer.Fuzz(TestOneInput, nil, args)
34 changes: 34 additions & 0 deletions tests/lapi/table_remove_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.5 – Table Manipulation,
https://www.lua.org/manual/5.1/manual.html#5.5

table.remove removes last element of a table when given an
out-of-bound index, https://www.lua.org/bugs.html#5.1.2-10

Synopsis: table.remove(list [, pos])
]]

local luzer = require("luzer")
local test_lib = require("lib")

local function TestOneInput(buf, _size)
local fdp = luzer.FuzzedDataProvider(buf)
local count = fdp:consume_integer(0, test_lib.MAX_INT)
local tbl = fdp:consume_strings(test_lib.MAX_STR_LEN, count)

local indices_count = fdp:consume_integer(0, #tbl)
local indices = fdp:consume_integers(0, count, indices_count)
for _, idx in ipairs(indices) do
local old_v = tbl[idx]
assert(table.remove(tbl, idx) == old_v)
assert(tbl[idx] == nil)
end
end

local args = {
artifact_prefix = "table_remove_",
}
luzer.Fuzz(TestOneInput, nil, args)
Loading