Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ jobs:
run: |
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
-DUSE_LUA=ON -DENABLE_BUILD_PROTOBUF=OFF \
-DENABLE_INTERNAL_TESTS=ON \
-DENABLE_INTERNAL_TESTS=ON -DENABLE_LAPI_TESTS=ON \
-G Ninja -S . -B build
if: ${{ matrix.LUA == 'lua' }}

- name: Running CMake (LuaJIT -current)
run: |
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
-DUSE_LUAJIT=ON -DENABLE_BUILD_PROTOBUF=OFF \
-DENABLE_INTERNAL_TESTS=ON \
-DENABLE_INTERNAL_TESTS=ON -DENABLE_LAPI_TESTS=ON \
-G Ninja -S . -B build
if: ${{ matrix.LUA == 'luajit' }}

Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ option(OSS_FUZZ "Enable support of OSS Fuzz" OFF)
option(ENABLE_BUILD_PROTOBUF "Enable building Protobuf library" ON)
option(ENABLE_BONUS_TESTS "Enable bonus tests" OFF)
option(ENABLE_INTERNAL_TESTS "Enable internal tests" OFF)
option(ENABLE_LAPI_TESTS "Enable Lua API tests" OFF)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
set(CMAKE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_INCLUDE_PATH})
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ is LuaJIT-specific.
- `ENABLE_BUILD_PROTOBUF` enables building Protobuf library, otherwise system
library is used.
- `ENABLE_INTERNAL_TESTS` enables internal tests.
- `ENABLE_LAPI_TESTS` enables Lua API tests.

### Running

Expand Down
7 changes: 7 additions & 0 deletions cmake/BuildLua.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ macro(build_lua LUA_VERSION)
set(LDFLAGS "${LDFLAGS} -fprofile-instr-generate -fprofile-arcs -fcoverage-mapping -ftest-coverage")
endif (ENABLE_COV)

if(ENABLE_LAPI_TESTS)
# "relocation R_X86_64_PC32 against symbol `lua_isnumber'
# can not be used when making a shared object; recompile
# with -fPIC".
set(CFLAGS "${CFLAGS} -fPIC")
set(CFLAGS "${CFLAGS} -DLUA_USE_DLOPEN")
endif()

include(ExternalProject)

Expand Down
9 changes: 9 additions & 0 deletions cmake/BuildLuaJIT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ macro(build_luajit LJ_VERSION)
set(LDFLAGS "${LDFLAGS} -fprofile-instr-generate -fprofile-arcs -fcoverage-mapping -ftest-coverage")
endif (ENABLE_COV)

if(ENABLE_LAPI_TESTS)
# "relocation R_X86_64_PC32 against symbol `lua_isnumber'
# can not be used when making a shared object; recompile
# with -fPIC".
set(CFLAGS "${CFLAGS} -fPIC")
# CMake option LUAJIT_FRIENDLY_MODE in luzer requires
# LUAJIT_ENABLE_CHECKHOOK.
set(CFLAGS "${CFLAGS} -DLUAJIT_ENABLE_CHECKHOOK")
endif()

include(ExternalProject)

Expand Down
61 changes: 61 additions & 0 deletions cmake/BuildLuzer.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
set(LUZER_DIR ${PROJECT_BINARY_DIR}/luzer)
set(LUZER_BUILD_DIR ${LUZER_DIR}/build)
set(LUZER_LIBRARY_PATH ${LUZER_BUILD_DIR}/luzer)
list(APPEND LUZER_LIBRARIES
${LUZER_LIBRARY_PATH}/luzer/luzer.so
${LUZER_LIBRARY_PATH}/luzer/libcustom_mutator.so
)

include(ExternalProject)

get_target_property(LUA_LIBRARIES_LOCATION ${LUA_LIBRARIES} LOCATION)

list(APPEND LUZER_CMAKE_FLAGS
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DLUA_INCLUDE_DIR=${LUA_INCLUDE_DIR}"
"-DLUA_LIBRARIES=${LUA_LIBRARIES_LOCATION}"
)
if(USE_LUAJIT)
list(APPEND LUZER_CMAKE_FLAGS
"-DLUAJIT_FRIENDLY_MODE=ON"
"-DLUA_HAS_JIT=ON"
)
endif()

ExternalProject_Add(bundled-luzer
GIT_REPOSITORY https://github.com/ligurio/luzer
GIT_TAG 82d41c5f350296ca351e785a24c914165a0e8033
GIT_PROGRESS TRUE
GIT_SHALLOW FALSE
SOURCE_DIR ${LUZER_DIR}/source
BINARY_DIR ${LUZER_BUILD_DIR}
TMP_DIR ${LUZER_DIR}/tmp
STAMP_DIR ${LUZER_DIR}/stamp
CONFIGURE_COMMAND
${CMAKE_COMMAND} -B <BINARY_DIR> -S <SOURCE_DIR>
-G ${CMAKE_GENERATOR} ${LUZER_CMAKE_FLAGS}
BUILD_COMMAND cd <BINARY_DIR> && ${CMAKE_MAKE_PROGRAM}
INSTALL_COMMAND ""
CMAKE_GENERATOR ${CMAKE_GENERATOR}
BUILD_BYPRODUCTS ${LUZER_LIBRARIES}
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)

add_library(luzer-library STATIC IMPORTED GLOBAL)
set_target_properties(luzer-library PROPERTIES
IMPORTED_LOCATION "${LUZER_LIBRARIES}")
add_dependencies(luzer-library bundled-luzer)
add_dependencies(bundled-luzer bundled-liblua)

set(LUZER_LUA_PATH ${LUZER_DIR}/source/?/init.lua)
set(LUZER_LUA_PATH ${LUZER_LUA_PATH} PARENT_SCOPE)

set(LUZER_LUA_CPATH ${LUZER_LIBRARY_PATH}/?${CMAKE_SHARED_LIBRARY_SUFFIX})
set(LUZER_LUA_CPATH ${LUZER_LUA_CPATH} PARENT_SCOPE)

set(LUZER_LIBRARY luzer-library PARENT_SCOPE)

unset(LUZER_DIR)
unset(LUZER_BUILD_DIR)
55 changes: 55 additions & 0 deletions cmake/MakeLuaPath.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# lapi_tests_make_lua_path provides a convenient way to define
# LUA_PATH and LUA_CPATH variables.
#
# Example usage:
#
# lapi_tests_make_lua_path(LUA_PATH
# PATH
# ./?.lua
# ${CMAKE_BINARY_DIR}/?.lua
# ${CMAKE_CURRENT_SOURCE_DIR}/?.lua
# )
#
# This will give you the string:
# "./?.lua;${CMAKE_BINARY_DIR}/?.lua;${CMAKE_CURRENT_SOURCE_DIR}/?.lua;;"
#
# Source: https://github.com/tarantool/luajit/blob/441405c398d625fda304b16bb10f119bfd822696/cmake/MakeLuaPath.cmake

function(lapi_tests_make_lua_path path)
set(prefix ARG)
set(noValues)
set(singleValues)
set(multiValues PATHS)

include(CMakeParseArguments)
cmake_parse_arguments(${prefix}
"${noValues}"
"${singleValues}"
"${multiValues}"
${ARGN})

set(_MAKE_LUA_PATH_RESULT "")

foreach(inc ${ARG_PATHS})
# XXX: If one joins two strings with the semicolon, the value
# automatically becomes a list. I found a single working
# solution to make result variable be a string via "escaping"
# the semicolon right in string interpolation.
set(_MAKE_LUA_PATH_RESULT "${_MAKE_LUA_PATH_RESULT}${inc}\;")
endforeach()

if("${_MAKE_LUA_PATH_RESULT}" STREQUAL "")
message(FATAL_ERROR
"No paths are given to <lapi_tests_make_lua_path> helper.")
endif()

# XXX: This is the sentinel semicolon having special meaning
# for LUA_PATH and LUA_CPATH variables. For more info, see the
# link below:
# https://www.lua.org/manual/5.1/manual.html#pdf-LUA_PATH
set(${path} "${_MAKE_LUA_PATH_RESULT}\;" PARENT_SCOPE)
# XXX: Unset the internal variable to not spoil CMake cache.
# Study the case in CheckIPOSupported.cmake, that affected this
# module: https://gitlab.kitware.com/cmake/cmake/-/commit/4b82977
unset(_MAKE_LUA_PATH_RESULT)
endfunction()
21 changes: 20 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
set(DEFAULT_RUNS_NUMBER 5)

string(JOIN " " LIBFUZZER_OPTS
-mutate_depth=20
-print_final_stats=1
-print_pcs=1
-reduce_inputs=1
-reload=1
-report_slow_units=5
-runs=$\{RUNS:-${DEFAULT_RUNS_NUMBER}\}
-use_value_profile=1
-workers=${CMAKE_BUILD_PARALLEL_LEVEL}
)

set(CORPUS_BASE_PATH ${PROJECT_SOURCE_DIR}/corpus)
if(IS_LUAJIT)
set(CORPUS_BASE_PATH ${CORPUS_BASE_PATH}/corpus)
endif()

add_subdirectory(capi)
if (ENABLE_BONUS_TESTS)
if(ENABLE_LAPI_TESTS)
add_subdirectory(lapi)
endif()
24 changes: 3 additions & 21 deletions tests/capi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ target_link_libraries(
>
)

message(STATUS "Add Lua C API test suite")

# The following condition looks unnecessary, it was added to fix
# an issue for Sydr: in the Lua external project in the build
# system the explicit build command is used:
Expand All @@ -52,25 +54,6 @@ if (ENABLE_COV)
AppendFlags(LDFLAGS -fprofile-instr-generate -fcoverage-mapping)
endif()

set(DEFAULT_RUNS_NUMBER 5)

string(JOIN " " LIBFUZZER_OPTS
-mutate_depth=20
-print_final_stats=1
-print_pcs=1
-reduce_inputs=1
-reload=1
-report_slow_units=5
-workers=${CMAKE_BUILD_PARALLEL_LEVEL}
-runs=$\{RUNS:-${DEFAULT_RUNS_NUMBER}\}
-use_value_profile=1
)

set(CORPUS_BASE_PATH ${PROJECT_SOURCE_DIR}/corpus)
if(USE_LUAJIT)
set(CORPUS_BASE_PATH ${CORPUS_BASE_PATH}/corpus)
endif()

function(create_test)
cmake_parse_arguments(
FUZZ
Expand All @@ -96,7 +79,7 @@ function(create_test)
endif ()
set(dict_path ${CORPUS_BASE_PATH}/${test_name}.dict)
set(corpus_path ${CORPUS_BASE_PATH}/${test_prefix})
if(USE_LUAJIT)
if(IS_LUAJIT)
set(corpus_path ${CORPUS_BASE_PATH}/${test_name})
endif()
if (EXISTS ${dict_path})
Expand All @@ -108,7 +91,6 @@ function(create_test)
add_test(NAME ${test_name}
COMMAND ${SHELL} -c "$<TARGET_FILE:${test_name}> ${LIBFUZZER_OPTS}"
)
message(STATUS "Creating Lua C API test ${test_name}")
if (USE_LUA)
set_tests_properties(${test_name} PROPERTIES
ENVIRONMENT "ASAN_OPTIONS='detect_invalid_pointer_pairs=2'"
Expand Down
57 changes: 57 additions & 0 deletions tests/lapi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
include(BuildLuzer)
include(MakeLuaPath)

if(NOT LUA_EXECUTABLE)
message(FATAL_ERROR "${LUA_EXECUTABLE} is not found.")
endif()

lapi_tests_make_lua_path(LUA_CPATH
PATHS
${LUZER_LUA_CPATH}
)

lapi_tests_make_lua_path(LUA_PATH
PATHS
${LUZER_LUA_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/?.lua
)

function(create_test)
cmake_parse_arguments(
FUZZ
""
"FILENAME"
""
${ARGN}
)
get_filename_component(test_name ${FUZZ_FILENAME} NAME_WE)
string(REPLACE "_test" "" test_prefix ${test_name})
set(dict_path ${PROJECT_SOURCE_DIR}/corpus/${test_prefix}.dict)
set(corpus_path ${PROJECT_SOURCE_DIR}/corpus/${test_prefix})
set(dict_path ${CORPUS_BASE_PATH}/${test_name}.dict)
set(corpus_path ${CORPUS_BASE_PATH}/${test_prefix})
if(IS_LUAJIT)
set(corpus_path ${CORPUS_BASE_PATH}/${test_name})
endif()
if (EXISTS ${dict_path})
set(LIBFUZZER_OPTS "${LIBFUZZER_OPTS} -dict=${dict_path}")
endif ()
if (EXISTS ${corpus_path})
set(LIBFUZZER_OPTS "${LIBFUZZER_OPTS} ${corpus_path}")
endif ()
add_test(NAME ${test_name}
COMMAND ${SHELL} -c "${LUA_EXECUTABLE} ${FUZZ_FILENAME} ${LIBFUZZER_OPTS}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_tests_properties(${test_name} PROPERTIES
LABELS "lapi"
ENVIRONMENT "LUA_PATH=${LUA_PATH};LUA_CPATH=${LUA_CPATH};ASAN_OPTIONS=detect_odr_violation=0;LD_DYNAMIC_WEAK=1"
DEPENDS ${LUA_EXECUTABLE} ${LUZER_LIBRARY}
)
endfunction()

message(STATUS "Add Lua API test suite")
file(GLOB tests LIST_DIRECTORIES false ${CMAKE_CURRENT_SOURCE_DIR}/*_test.lua)
foreach(filename ${tests})
create_test(FILENAME ${filename})
endforeach()
37 changes: 37 additions & 0 deletions tests/lapi/bitop_arshift_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--[[
SPDX-License-Identifier: ISC
Copyright (c) 2023-2025, Sergey Bronnikov.

Synopsis: bit.arshift(x, n)
]]

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

if test_lib.lua_version() ~= "LuaJIT" then
print("Unsupported version.")
os.exit(0)
end

local arshift = bit.arshift
local bxor = bit.bxor

local function is_opposite_sign(a, b)
return bxor(a, b) < 0
end

local function TestOneInput(buf)
local fdp = luzer.FuzzedDataProvider(buf)
local MAX_INT = test_lib.MAX_INT
local MIN_INT = test_lib.MIN_INT
local x = fdp:consume_integer(MIN_INT, MAX_INT)
local n = fdp:consume_integer(MIN_INT, MAX_INT)
local res = arshift(x, n)
assert(type(res) == "number")
assert(is_opposite_sign(x, res) == false)
end

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