Skip to content

Commit 345c082

Browse files
committed
Add fuzz test for parsing YAML inputs
1 parent b0a41e8 commit 345c082

6 files changed

Lines changed: 153 additions & 53 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ endif()
126126
# Build the test apps #
127127
###########################
128128

129-
if(FK_YAML_BUILD_TEST OR FK_YAML_BUILD_ALL_TEST)
129+
if(FK_YAML_BUILD_TEST OR FK_YAML_BUILD_FUZZ_TEST OR FK_YAML_BUILD_ALL_TEST)
130130
include(CTest)
131131
enable_testing()
132132
add_subdirectory(tests)

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ valgrind:
7373
cmake --build build_valgrind --config Debug -j $(JOBS)
7474
ctest -C Debug -T memcheck --test-dir build_valgrind --output-on-failure -j $(JOBS)
7575

76+
# pre-requisites: clang
77+
fuzz-test:
78+
CXX=clang++ cmake -B build_fuzz_test -S . -DCMAKE_BUILD_TYPE=Debug -DFK_YAML_BUILD_FUZZ_TEST=ON
79+
cmake --build build_fuzz_test --target run_fuzz_test
80+
7681
###########################
7782
# Source Amalgamation #
7883
###########################

tests/CMakeLists.txt

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,70 @@
1+
############################################
2+
# configure C++ standard for unit test #
3+
############################################
4+
5+
# determine C++ standard used in unit test app.
6+
if("${FK_YAML_TEST_TARGET_CXX_STANDARD}" STREQUAL "")
7+
# Apply minimum required C++ standard checked by default.
8+
set(FK_YAML_TEST_TARGET_CXX_STANDARD 11)
9+
endif()
10+
11+
# detect C++ standards supported by the compiler.
12+
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
13+
if(${feature} STREQUAL cxx_std_11)
14+
set(FK_YAML_COMPILER_SUPPORTS_CXX_11 ON)
15+
elseif(${feature} STREQUAL cxx_std_14)
16+
set(FK_YAML_COMPILER_SUPPORTS_CXX_14 ON)
17+
elseif(${feature} STREQUAL cxx_std_17)
18+
set(FK_YAML_COMPILER_SUPPORTS_CXX_17 ON)
19+
elseif(${feature} STREQUAL cxx_std_20)
20+
set(FK_YAML_COMPILER_SUPPORTS_CXX_20 ON)
21+
elseif(${feature} STREQUAL cxx_std_23)
22+
set(FK_YAML_COMPILER_SUPPORTS_CXX_23 ON)
23+
endif()
24+
endforeach()
25+
26+
# check if the determined C++ standard is supported by the compiler.
27+
if(NOT FK_YAML_COMPILER_SUPPORTS_CXX_${FK_YAML_TEST_TARGET_CXX_STANDARD})
28+
message(WARNING "The target compiler does not support C++${FK_YAML_TEST_TARGET_CXX_STANDARD}. Stop configuring unit test app.")
29+
return()
30+
endif()
31+
32+
############################################################
33+
# Configure common compile options for unit/fuzz tests #
34+
############################################################
35+
36+
add_library(common_test_config INTERFACE)
37+
target_link_libraries(
38+
common_test_config
39+
INTERFACE
40+
${FK_YAML_TARGET_NAME}
41+
)
42+
target_compile_features(
43+
common_test_config
44+
INTERFACE
45+
cxx_std_${FK_YAML_TEST_TARGET_CXX_STANDARD}
46+
)
47+
set_target_properties(
48+
common_test_config
49+
PROPERTIES
50+
CXX_EXTENSIONS OFF
51+
)
52+
target_compile_definitions(
53+
common_test_config
54+
INTERFACE
55+
$<$<CONFIG:Release>:NDEBUG>
56+
)
57+
58+
#############################
59+
# Register test targets #
60+
#############################
61+
162
add_subdirectory(unit_test)
263

64+
if(FK_YAML_BUILD_FUZZ_TEST)
65+
add_subdirectory(fuzz_test)
66+
endif()
67+
368
if(FK_YAML_BUILD_ALL_TEST)
469
add_subdirectory(cmake_add_subdirectory_test)
570
add_subdirectory(cmake_fetch_content_test)

tests/fuzz_test/CMakeLists.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
############################################
2+
# Download data files for fuzz testing #
3+
############################################
4+
5+
include(FetchContent)
6+
FetchContent_Declare(
7+
fuzz_test_data
8+
GIT_REPOSITORY https://github.com/fktn-k/fkyaml_fuzz_test_data.git
9+
GIT_TAG main
10+
)
11+
FetchContent_MakeAvailable(fuzz_test_data)
12+
13+
#############################################
14+
# Build fuzz test executable for fkYAML #
15+
#############################################
16+
17+
add_executable(
18+
fuzz_test
19+
fuzzer_parse_yaml.cpp
20+
)
21+
target_link_libraries(
22+
fuzz_test
23+
PRIVATE
24+
common_test_config
25+
)
26+
target_compile_options(
27+
fuzz_test
28+
PRIVATE
29+
-fsanitize=fuzzer,address,undefined
30+
-g
31+
-O1
32+
)
33+
target_link_options(
34+
fuzz_test
35+
PRIVATE
36+
-fsanitize=fuzzer,address,undefined
37+
)
38+
39+
#
40+
# Configure custom target to run the fuzz test executable with the corpus data
41+
#
42+
43+
add_custom_command(
44+
TARGET fuzz_test
45+
POST_BUILD
46+
COMMAND ${CMAKE_COMMAND} -E copy_directory
47+
${fuzz_test_data_SOURCE_DIR}/corpus
48+
$<TARGET_FILE_DIR:fuzz_test>/corpus
49+
)
50+
add_custom_target(
51+
run_fuzz_test
52+
COMMAND $<TARGET_FILE:fuzz_test> corpus/generated corpus/seeds -dict=corpus/yaml.dict -artifact_prefix=corpus/findings/ -max_total_time=300
53+
WORKING_DIRECTORY $<TARGET_FILE_DIR:fuzz_test>
54+
DEPENDS fuzz_test
55+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// _______ __ __ __ _____ __ __ __
2+
// | __| |_/ | \_/ |/ _ \ / \/ \| | fkYAML: A C++ header-only YAML library (supporting code)
3+
// | __| _ < \_ _/| ___ | _ | |___ version 0.4.3
4+
// |__| |_| \__| |_| |_| |_|___||___|______| https://github.com/fktn-k/fkYAML
5+
//
6+
// SPDX-FileCopyrightText: 2023-2026 Kensuke Fukutani <fktn.dev@gmail.com>
7+
// SPDX-License-Identifier: MIT
8+
9+
#include <fkYAML/node.hpp>
10+
11+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
12+
try {
13+
const char* data_str = reinterpret_cast<const char*>(data);
14+
fkyaml::node n = fkyaml::node::deserialize(data_str, data_str + size);
15+
(void)n;
16+
}
17+
catch (const fkyaml::exception& e) {
18+
(void)e;
19+
}
20+
return 0;
21+
}

tests/unit_test/CMakeLists.txt

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -40,37 +40,6 @@ FetchContent_Declare(
4040
FetchContent_MakeAvailable(doctest)
4141
include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake)
4242

43-
############################################
44-
# configure C++ standard for unit test #
45-
############################################
46-
47-
# determine C++ standard used in unit test app.
48-
if("${FK_YAML_TEST_TARGET_CXX_STANDARD}" STREQUAL "")
49-
# Apply minimum required C++ standard checked by default.
50-
set(FK_YAML_TEST_TARGET_CXX_STANDARD 11)
51-
endif()
52-
53-
# detect C++ standards supported by the compiler.
54-
foreach(feature ${CMAKE_CXX_COMPILE_FEATURES})
55-
if(${feature} STREQUAL cxx_std_11)
56-
set(FK_YAML_COMPILER_SUPPORTS_CXX_11 ON)
57-
elseif(${feature} STREQUAL cxx_std_14)
58-
set(FK_YAML_COMPILER_SUPPORTS_CXX_14 ON)
59-
elseif(${feature} STREQUAL cxx_std_17)
60-
set(FK_YAML_COMPILER_SUPPORTS_CXX_17 ON)
61-
elseif(${feature} STREQUAL cxx_std_20)
62-
set(FK_YAML_COMPILER_SUPPORTS_CXX_20 ON)
63-
elseif(${feature} STREQUAL cxx_std_23)
64-
set(FK_YAML_COMPILER_SUPPORTS_CXX_23 ON)
65-
endif()
66-
endforeach()
67-
68-
# check if the determined C++ standard is supported by the compiler.
69-
if(NOT FK_YAML_COMPILER_SUPPORTS_CXX_${FK_YAML_TEST_TARGET_CXX_STANDARD})
70-
message(WARNING "The target compiler does not support C++${FK_YAML_TEST_TARGET_CXX_STANDARD}. Stop configuring unit test app.")
71-
return()
72-
endif()
73-
7443
######################################
7544
# Prepare to use test data files #
7645
######################################
@@ -94,26 +63,6 @@ target_include_directories(
9463
"${CMAKE_CURRENT_BINARY_DIR}/include"
9564
"${doctest_SOURCE_DIR}"
9665
)
97-
target_link_libraries(
98-
unit_test_config
99-
INTERFACE
100-
${FK_YAML_TARGET_NAME}
101-
)
102-
target_compile_features(
103-
unit_test_config
104-
INTERFACE
105-
cxx_std_${FK_YAML_TEST_TARGET_CXX_STANDARD}
106-
)
107-
set_target_properties(
108-
unit_test_config
109-
PROPERTIES
110-
CXX_EXTENTIONS OFF
111-
)
112-
target_compile_definitions(
113-
unit_test_config
114-
INTERFACE
115-
$<$<CONFIG:Release>:NDEBUG>
116-
)
11766

11867
# Configure compile options according to the target compiler.
11968
target_compile_options(
@@ -266,7 +215,12 @@ add_executable(
266215
main.cpp
267216
)
268217

269-
target_link_libraries(${TEST_TARGET} PRIVATE unit_test_config)
218+
target_link_libraries(
219+
${TEST_TARGET}
220+
PRIVATE
221+
common_test_config
222+
unit_test_config
223+
)
270224

271225
doctest_discover_tests(${TEST_TARGET})
272226

0 commit comments

Comments
 (0)