diff --git a/cmake/BuildLuzer.cmake b/cmake/BuildLuzer.cmake index e057697..833204b 100644 --- a/cmake/BuildLuzer.cmake +++ b/cmake/BuildLuzer.cmake @@ -34,7 +34,7 @@ endif() ExternalProject_Add(bundled-luzer GIT_REPOSITORY https://github.com/ligurio/luzer - GIT_TAG 3f4eb03b4ff7596855a0aaf45aa557f61b25ddb2 + GIT_TAG fc4a32fe98f1da8b07f74a35f40b678692e7152b GIT_PROGRESS TRUE GIT_SHALLOW FALSE SOURCE_DIR ${LUZER_DIR}/source 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/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 diff --git a/tests/lapi/os_date_test.lua b/tests/lapi/os_date_test.lua index ac63eac..61a59b4 100644 --- a/tests/lapi/os_date_test.lua +++ b/tests/lapi/os_date_test.lua @@ -32,11 +32,9 @@ 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" + local undocumented_type_check = type(res) == "number" or res == nil + assert(type_check or undocumented_type_check) end local args = { 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 = { diff --git a/tests/lapi/os_time_test.lua b/tests/lapi/os_time_test.lua index 981ffed..8bab123 100644 --- a/tests/lapi/os_time_test.lua +++ b/tests/lapi/os_time_test.lua @@ -32,11 +32,9 @@ 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" + local undocumented_type_check = res == nil + assert(type_check or undocumented_type_check) end local args = { diff --git a/tests/lapi/string_byte_test.lua b/tests/lapi/string_byte_test.lua index e309f72..b21726c 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,9 +7,9 @@ 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") @@ -18,17 +18,15 @@ 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) - end + -- Note, `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. + local bytes = string.char(string.byte(str, i, j)) + assert(bytes == string.sub(str, i, j)) end local args = { 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)) diff --git a/tests/lapi/table_clear_test.lua b/tests/lapi/table_clear_test.lua new file mode 100644 index 0000000..78d9bca --- /dev/null +++ b/tests/lapi/table_clear_test.lua @@ -0,0 +1,46 @@ +--[[ +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) + -- Make sure the table is empty. + local n_items = 0 + for _ in pairs(tbl) do + n_items = n_items + 1 + end + assert(n_items == 0) +end + +local args = { + artifact_prefix = "table_clear_", +} +luzer.Fuzz(TestOneInput, nil, args) diff --git a/tests/lapi/table_remove_test.lua b/tests/lapi/table_remove_test.lua index 330d946..347e6b9 100644 --- a/tests/lapi/table_remove_test.lua +++ b/tests/lapi/table_remove_test.lua @@ -16,11 +16,17 @@ 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 min_index = 0 + -- PUC Rio Lua 5.2+ raises an error "position out of bounds" + -- when `pos` is equal to 0 and table is not empty. + if test_lib.lua_current_version_ge_than(5, 2) then + min_index = 1 + end + local indices = fdp:consume_integers(min_index, count, indices_count) for _, idx in ipairs(indices) do local old_v = tbl[idx] assert(table.remove(tbl, idx) == old_v)