commit - /dev/null
commit + 78cf7a7b194e6cc517614cd52b19048398ef655d
blob - /dev/null
blob + 46e85f75ea7f7425395f19b1083060c05f036950 (mode 644)
--- /dev/null
+++ .gitignore
+build
+.ccls-cache
+crash-*
blob - /dev/null
blob + b9f0ed8b598a692286c51c667a4f7789a2c9ca83 (mode 644)
--- /dev/null
+++ CMakeLists.txt
+cmake_minimum_required(VERSION 3.10.2)
+
+project(libc-tests
+ DESCRIPTION "Fuzzing libc"
+ LANGUAGES C CXX
+ VERSION "1.0.0"
+)
+
+set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")
+
+if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR
+ NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ message(FATAL_ERROR
+ "\n"
+ "Building is supported with Clang compiler only.\n"
+ " $ rm -rf build\n"
+ " $ cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -S . -B build\n"
+ " $ cmake --build build --parallel\n"
+ "\n")
+endif()
+
+enable_testing()
+add_subdirectory(tests)
blob - /dev/null
blob + ba6be8c10afc083c5b067d6db8632d733c695c6a (mode 644)
--- /dev/null
+++ CMakePresets.json
+{
+ "version": 6,
+ "cmakeMinimumRequired": {
+ "major": 3,
+ "minor": 20,
+ "patch": 0
+ },
+ "configurePresets": [
+ {
+ "name": "default",
+ "displayName": "Default Config (Unix Makefile)",
+ "description": "Default build using Unix Makefile generator",
+ "binaryDir": "${sourceDir}/build",
+ "cacheVariables": {
+ "CMAKE_BUILD_TYPE": "Debug",
+ "CMAKE_C_COMPILER": "clang",
+ "CMAKE_CXX_COMPILER": "clang++",
+ "CMAKE_EXPORT_COMPILE_COMMANDS": {
+ "type": "BOOL",
+ "value": "ON"
+ }
+ }
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default",
+ "jobs": 10
+ }
+ ],
+ "testPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default",
+ "output": {"outputOnFailure": true},
+ "execution": {"noTestsAction": "error", "stopOnFailure": true}
+ }
+ ],
+ "workflowPresets": [
+ {
+ "name": "default",
+ "steps": [
+ {
+ "type": "configure",
+ "name": "default"
+ },
+ {
+ "type": "build",
+ "name": "default"
+ },
+ {
+ "type": "test",
+ "name": "default"
+ }
+ ]
+ }
+ ]
+}
blob - /dev/null
blob + d2da6a20a19cfaac69323cfa0b291e751b8a1455 (mode 644)
--- /dev/null
+++ LICENSE
+MIT License
+
+Copyright (c) 2022-2023 Sergey Bronnikov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
blob - /dev/null
blob + 7396966529584e30e59b60b465e191f8e689c18a (mode 644)
--- /dev/null
+++ README.md
+## Fuzzing libc
+
+is a set of fuzzing tests intended for testing standard C library.
+By default system C library is used.
+
+### Building
+
+```sh
+git clone --jobs $(nproc) --recursive https://github.com/ligurio/libc-tests
+CC=clang CXX=clang++ cmake -S . -B build
+cmake --build build --parallel
+```
+
+or
+
+```
+$ cmake --workflow --preset default
+```
+
+### Running
+
+```sh
+cmake --build build --target test
+cd build && ctest -R strptime_test --verbose
+```
+
+### License
+
+MIT License, [Sergey Bronnikov](https://bronevichok.ru/)
blob - /dev/null
blob + 3139149b680de48abb641abc25bef247679b78be (mode 644)
--- /dev/null
+++ tests/CMakeLists.txt
+add_library(fuzzer_config INTERFACE)
+
+target_compile_options(
+ fuzzer_config
+ INTERFACE
+ $<$<NOT:$<BOOL:${OSS_FUZZ}>>:
+ -fsanitize=fuzzer
+ >
+ $<$<BOOL:${OSS_FUZZ}>:
+ ${CXX}
+ ${CXXFLAGS}
+ >
+)
+target_link_libraries(
+ fuzzer_config
+ INTERFACE
+ $<$<NOT:$<BOOL:${OSS_FUZZ}>>:
+ -fsanitize=fuzzer
+ >
+ $<$<BOOL:${OSS_FUZZ}>:
+ $ENV{LIB_FUZZING_ENGINE}
+ >
+)
+
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(LDFLAGS "${LDFLAGS} ${CMAKE_C_FLAGS_DEBUG}")
+endif (CMAKE_BUILD_TYPE STREQUAL "Debug")
+
+set(FUZZ_TEST_TARGETS "")
+
+include(CheckFunctionExists)
+
+function(create_test)
+ cmake_parse_arguments(
+ FUZZ
+ ""
+ "FILENAME"
+ "SOURCES;LIBRARIES"
+ ${ARGN}
+ )
+
+ check_function_exists(${FUZZ_FILENAME} HAVE_${FUZZ_FILENAME})
+ if (NOT ${HAVE_${FUZZ_FILENAME}})
+ message(WARNING "Function ${FUZZ_FILENAME} is missed")
+ return()
+ endif ()
+
+ get_filename_component(test_name ${FUZZ_FILENAME} NAME_WE)
+ add_executable(${test_name} ${FUZZ_SOURCES})
+
+ target_link_libraries(${test_name} PUBLIC fuzzer_config ${FUZZ_LIBRARIES} ${LDFLAGS})
+ target_compile_options(${test_name} PRIVATE -Wall -Wextra -Wpedantic -Wno-unused-parameter -g)
+ string(REPLACE "_test" "" test_prefix ${test_name})
+ add_test(NAME ${test_name}
+ COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${test_name}
+ -use_value_profile=1
+ -report_slow_units=5
+ -reload=1
+ -reduce_inputs=1
+ -print_pcs=1
+ -print_final_stats=1
+ -mutate_depth=20
+ -runs=5
+ -artifact_prefix=${test_name}_
+ )
+endfunction()
+
+file(GLOB tests LIST_DIRECTORIES false ${CMAKE_CURRENT_SOURCE_DIR} *.c *.cc)
+foreach(filename ${tests})
+ get_filename_component(test_name ${filename} NAME_WE)
+ create_test(FILENAME ${test_name}
+ SOURCES ${filename}
+ LIBRARIES "")
+endforeach()
blob - /dev/null
blob + 6de8978d644f94501eddaec87e6d66bf8a1241a9 (mode 644)
--- /dev/null
+++ tests/strptime_test.cc
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+extern "C" int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ FuzzedDataProvider fdp(data, size);
+
+ auto buf = fdp.ConsumeRandomLengthString();
+ auto fmt = fdp.ConsumeRandomLengthString();
+
+ struct tm tm = {};
+ char *res = strptime(buf.c_str(), fmt.c_str(), &tm);
+ if (!res)
+ return 0;
+
+ assert(tm.tm_sec >= 0 && tm.tm_sec <= 60);
+ assert(tm.tm_min >= 0 && tm.tm_min <= 59);
+ assert(tm.tm_hour >= 0 && tm.tm_hour <= 23);
+ assert(tm.tm_mday >= 0 && tm.tm_mday <= 28);
+ assert(tm.tm_mon >= 0 && tm.tm_mon <= 11);
+ assert(tm.tm_year >= 0);
+ assert(tm.tm_wday >= 0 && tm.tm_wday <= 6);
+ assert(tm.tm_yday >= 0 && tm.tm_yday <= 365);
+ assert(tm.tm_isdst >= 0);
+
+ return 0;
+}