From d9134b92807526d3c523e3fd5be114ffecabbd2a Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Mon, 28 Jul 2025 17:49:45 +0300 Subject: [PATCH 1/7] tests/lapi: fix table_remove_test Fix out-of-bound indices passed to `table.remove()`. --- tests/lapi/table_remove_test.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lapi/table_remove_test.lua b/tests/lapi/table_remove_test.lua index 330d946..323e0b6 100644 --- a/tests/lapi/table_remove_test.lua +++ b/tests/lapi/table_remove_test.lua @@ -16,11 +16,11 @@ 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 count = fdp:consume_integer(1, 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) + local indices = fdp:consume_integers(1, count, indices_count) for _, idx in ipairs(indices) do local old_v = tbl[idx] assert(table.remove(tbl, idx) == old_v) From 5daf32d7125cb1edd7ed1c607051a94dec9a22b3 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Mon, 28 Jul 2025 18:19:58 +0300 Subject: [PATCH 2/7] tests/lapi: fix string_byte_test The patch fixes the following issues: - `string.char()` returns the internal numeric codes of the characters, not a single number. - `string.char()` returns `nil` when values `i` or `j` are outside the acceptable range (less than zero and greater than the length of the string). It is not documented. --- tests/lapi/string_byte_test.lua | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/lapi/string_byte_test.lua b/tests/lapi/string_byte_test.lua index e309f72..bea7490 100644 --- a/tests/lapi/string_byte_test.lua +++ b/tests/lapi/string_byte_test.lua @@ -1,4 +1,4 @@ ---[[ +--[=[[ SPDX-License-Identifier: ISC Copyright (c) 2023-2025, Sergey Bronnikov. @@ -7,28 +7,32 @@ https://www.lua.org/manual/5.3/manual.html#6.4 string.byte gets confused with some out-of-range negative indices, https://www.lua.org/bugs.html#5.1.3-9 -]] --- Synopsis: string.byte(s [, i [, j]]) +Synopsis: string.byte(s [, i [, j]]) +]]=] local luzer = require("luzer") local test_lib = require("lib") +local unpack = unpack or table.unpack + local function TestOneInput(buf, _size) local fdp = luzer.FuzzedDataProvider(buf) os.setlocale(test_lib.random_locale(fdp), "all") local str = fdp:consume_string(test_lib.MAX_STR_LEN) - local i = fdp:consume_integer(0, test_lib.MAX_INT) - local j = fdp:consume_integer(0, test_lib.MAX_INT) + local i = fdp:consume_integer(test_lib.MIN_INT, test_lib.MAX_INT) + local j = fdp:consume_integer(test_lib.MIN_INT, test_lib.MAX_INT) -- `string.byte()` is the same as `str:byte()`. assert(string.byte(str, i, j) == str:byte(i, j)) - local char_code = string.byte(str, i, j) - if char_code then - assert(type(char_code) == "number") - local byte = string.char(char_code) - assert(byte) - assert(byte == str) + local char_codes = { string.byte(str, i, j) } + -- `string.byte()` returns `nil` when values `i` or `j` are + -- outside the acceptable range (less than zero and greater + -- than the length of the string). It is undocumented. + if #char_codes == 0 then + return end + local bytes = string.char(unpack(char_codes)) + assert(bytes == string.sub(str, i, j)) end local args = { From fb3dd2b85f1b8e7414b1b061a73ed7b4472c3672 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Mon, 28 Jul 2025 18:20:09 +0300 Subject: [PATCH 3/7] tests/lapi: fix string_rep_test The patch fixes description (synopsis is at the end of the description) and fixes lower boundary for `n`, with `n` equal to zero assertion calculates negative number in right part of expression. --- tests/lapi/string_rep_test.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/lapi/string_rep_test.lua b/tests/lapi/string_rep_test.lua index 08070e1..36af220 100644 --- a/tests/lapi/string_rep_test.lua +++ b/tests/lapi/string_rep_test.lua @@ -5,10 +5,10 @@ Copyright (c) 2023-2025, Sergey Bronnikov. 6.4 – String Manipulation https://www.lua.org/manual/5.3/manual.html#6.4 -Synopsis: string.rep(s, n [, sep]) - read overflow in 'l_strcmp', https://github.com/lua/lua/commit/f623b969325be736297bc1dff48e763c08778243 + +Synopsis: string.rep(s, n [, sep]) ]] local luzer = require("luzer") @@ -18,7 +18,7 @@ local function TestOneInput(buf, _size) local fdp = luzer.FuzzedDataProvider(buf) os.setlocale(test_lib.random_locale(fdp), "all") -- Huge length leads to slow units. - local n = fdp:consume_integer(0, test_lib.MAX_STR_LEN) + local n = fdp:consume_integer(1, test_lib.MAX_STR_LEN) local s = fdp:consume_string(test_lib.MAX_STR_LEN) local sep = fdp:consume_string(test_lib.MAX_STR_LEN) local len = string.len(string.rep(s, n, sep)) From df7609cf66984d50ffd885ff2975fe50c0bab186 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 1 Aug 2025 13:32:50 +0300 Subject: [PATCH 4/7] tests/lapi: fix formatting --- tests/lapi/builtin_pairs_test.lua | 2 +- tests/lapi/os_setlocale_test.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lapi/builtin_pairs_test.lua b/tests/lapi/builtin_pairs_test.lua index 00b4120..2d53b1f 100644 --- a/tests/lapi/builtin_pairs_test.lua +++ b/tests/lapi/builtin_pairs_test.lua @@ -28,7 +28,7 @@ local function TestOneInput(buf) local MAX_N = 1000 local count = fdp:consume_integer(0, MAX_N) local tbl = fdp:consume_integers(test_lib.MIN_INT, test_lib.MAX_INT, count) - -- Use string keys to activate hash part of the table. + -- Use string keys to activate hash part of the table. tbl.a = fdp:consume_string(test_lib.MAX_STR_LEN) tbl.b = fdp:consume_string(test_lib.MAX_STR_LEN) for key, value in pairs(tbl) do diff --git a/tests/lapi/os_setlocale_test.lua b/tests/lapi/os_setlocale_test.lua index 3a8c4cd..492226b 100644 --- a/tests/lapi/os_setlocale_test.lua +++ b/tests/lapi/os_setlocale_test.lua @@ -19,7 +19,7 @@ local function TestOneInput(buf) }) local locale_string = os.setlocale(locale, category) assert(type(locale_string) == "string" or - locale_string == nil) + locale_string == nil) end local args = { From 9b0e24a78d6c51145388a03329ffa277ca641cf2 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Wed, 6 Aug 2025 18:08:02 +0300 Subject: [PATCH 5/7] tests/lapi: cache locales in random_locale() The patch changes function `random_locale()`, so it builds a table with locales only once on the first execution and then returns a cached table. --- tests/lapi/lib.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/lapi/lib.lua b/tests/lapi/lib.lua index c4bb890..973ee22 100644 --- a/tests/lapi/lib.lua +++ b/tests/lapi/lib.lua @@ -86,9 +86,14 @@ local function approx_equal(a, b, epsilon) return abs(a - b) <= ((abs(a) < abs(b) and abs(b) or abs(a)) * epsilon) end +local locales + local function random_locale(fdp) - local locales = {} + if locales then + return fdp:oneof(locales) + end local locale_it = io.popen("locale -a"):read("*a"):gmatch("([^\n]*)\n?") + locales = {} for locale in locale_it do table.insert(locales, locale) end From 68047bac84cdcd5bc7c801885463bba0fe8978c1 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Wed, 6 Aug 2025 21:47:11 +0300 Subject: [PATCH 6/7] tests/lapi: add table.clear test The patcha adds a test for `table.clear()` function that is present in LuaJIT. Follows up the commit ee032e778059 ("tests/lapi: add table tests"). --- tests/lapi/table_clear_test.lua | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/lapi/table_clear_test.lua diff --git a/tests/lapi/table_clear_test.lua b/tests/lapi/table_clear_test.lua new file mode 100644 index 0000000..074df89 --- /dev/null +++ b/tests/lapi/table_clear_test.lua @@ -0,0 +1,40 @@ +--[[ +SPDX-License-Identifier: ISC +Copyright (c) 2023-2025, Sergey Bronnikov. + +Double-emitting of IR_NEWREF for the same key on the snap replay, +https://github.com/LuaJIT/LuaJIT/issues/1128 + +X86/X64 load fusion conflict detection doesn't detect table.clear, +https://github.com/LuaJIT/LuaJIT/issues/1117 + +Problem of HREFK with table.clear, +https://github.com/LuaJIT/LuaJIT/issues/792 + +Add support for freeing memory manually, +https://github.com/LuaJIT/LuaJIT/issues/620 + +Synopsis: table.clear(tbl) +]] + +local luzer = require("luzer") +local test_lib = require("lib") + +if test_lib.lua_version() ~= "LuaJIT" then + print("Unsupported version.") + os.exit(0) +end + +local table_clear = require("table.clear") + +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) + table_clear(tbl) +end + +local args = { + artifact_prefix = "table_clear_", +} +luzer.Fuzz(TestOneInput, nil, args) From 42fa96aff9451aec3ba58bf5911e95b220683e31 Mon Sep 17 00:00:00 2001 From: Sergey Bronnikov Date: Fri, 8 Aug 2025 15:43:53 +0300 Subject: [PATCH 7/7] tests/lapi: update assertions in os tests The patch updates assertions for values returned by `os.date()` and `os.time()`, LuaJIT-specific type checks moved under condition. --- tests/lapi/os_date_test.lua | 11 ++++++----- tests/lapi/os_time_test.lua | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/lapi/os_date_test.lua b/tests/lapi/os_date_test.lua index ac63eac..6869374 100644 --- a/tests/lapi/os_date_test.lua +++ b/tests/lapi/os_date_test.lua @@ -32,11 +32,12 @@ local function TestOneInput(buf) local err_handler = test_lib.err_handler(ignored_msgs) local ok, res = xpcall(os.date, err_handler, format, time) if not ok then return end - assert(type(res) == "string" or - type(res) == "table" or - -- Undocumented. - type(res) == "number" or - res == nil) + local type_check = type(res) == "string" or type(res) == "table" + if test_lib.lua_version() == "LuaJIT" then + assert(type_check or type(res) == "number" or res == nil) + else + assert(type_check) + end end local args = { diff --git a/tests/lapi/os_time_test.lua b/tests/lapi/os_time_test.lua index 981ffed..f8feebd 100644 --- a/tests/lapi/os_time_test.lua +++ b/tests/lapi/os_time_test.lua @@ -32,11 +32,12 @@ local function TestOneInput(buf) local err_handler = test_lib.err_handler(ignored_msgs) local ok, res = xpcall(os.time, err_handler, time) if not ok then return end - io.stderr:write(type(res) .. "\n") - assert(type(res) == "number" or - type(res) == "table" or - -- Undocumented. - res == nil) + local type_check = type(res) == "number" or type(res) == "table" + if test_lib.lua_version() == "LuaJIT" then + assert(type_check or res == nil) + else + assert(type_check) + end end local args = {