Skip to content

Commit 0da7c5d

Browse files
pre-commit-ci[bot]phlptp
authored andcommitted
Add the beginnings of a fuzzing system for CLI11. This commit adds the fuzzing code, a simple test, and two fixes to issues(seg faults) found by the initial round of fuzzing. It also adds a few tests and coverage issues uncovered in the process of developing the fuzz tests. As a side effect adjusts some of the azure tests to specify the vmImage which was being changed on azure.
1 parent 60f0dca commit 0da7c5d

24 files changed

+596
-28
lines changed

.codecov.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ ignore:
44
- "book"
55
- "docs"
66
- "test_package"
7+
- "fuzz"

.github/codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
codecov:
22
notify:
3-
after_n_builds: 4
3+
after_n_builds: 8
44
coverage:
55
status:
66
project:

.github/workflows/fuzz.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Fuzz
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches:
6+
- main
7+
- v*
8+
pull_request:
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
quick_fuzz1:
16+
name: quickfuzz1
17+
runs-on: ubuntu-latest
18+
steps:
19+
- uses: actions/checkout@v3
20+
with:
21+
fetch-depth: 0
22+
23+
- name: Configure
24+
run: |
25+
cmake -S . -B build \
26+
-DCMAKE_CXX_STANDARD=17 \
27+
-DCLI11_SINGLE_FILE_TESTS=OFF \
28+
-DCLI11_BUILD_EXAMPLES=OFF \
29+
-DCLI11_FUZZ_TARGET=ON \
30+
-DCLI11_BUILD_TESTS=OFF \
31+
-DCLI11_BUILD_DOCS=OFF \
32+
-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_COMPILER_FORCED=ON \
33+
-DCMAKE_CXX_FLAGS="-g -O1 -fsanitize=fuzzer,undefined,address"
34+
35+
- name: Build
36+
run: cmake --build build -j4
37+
38+
- name: Test
39+
run: |
40+
cd build
41+
make QUICK_CLI11_APP_FUZZ
42+
43+
- name: Test2
44+
run: |
45+
cd build
46+
make QUICK_CLI11_FILE_FUZZ
47+
48+
49+
- name: artifacts
50+
if: failure()
51+
uses: actions/upload-artifact@v3
52+
with:
53+
name: file_failure
54+
path: ./build/fuzz/cli11_*_fail_artifact.txt

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Prepare coverage
4949
run: |
5050
lcov --directory . --capture --output-file coverage.info
51-
lcov --remove coverage.info '*/tests/*' '*/examples/*' '/usr/*' '*/book/*' --output-file coverage.info
51+
lcov --remove coverage.info '*/tests/*' '*/examples/*' '/usr/*' '*/book/*' '*/fuzz/*' --output-file coverage.info
5252
lcov --list coverage.info
5353
working-directory: build
5454

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
exclude: ^(.github/workflows/|docs/img/)
12
ci:
23
autoupdate_commit_msg: "chore(deps): pre-commit.ci autoupdate"
34
autofix_commit_msg: "style: pre-commit.ci fixes"
45

56
repos:
67
- repo: https://github.com/psf/black
7-
rev: 22.12.0
8+
rev: 23.1.0
89
hooks:
910
- id: black
1011

CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ endif()
132132

133133
include(CLI11Warnings)
134134

135+
# build the fuzzing example or fuzz entry point
136+
add_subdirectory(fuzz)
137+
135138
add_subdirectory(src)
136139

137140
# Allow tests to be run on CUDA

azure-pipelines.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ jobs:
2828
- bash: cpplint --counting=detailed --recursive examples include/CLI tests
2929
displayName: Checking against google style guide
3030

31-
# TODO: Fix macOS error and windows warning in c++17 mode
3231
- job: Native
3332
strategy:
3433
matrix:
@@ -38,13 +37,13 @@ jobs:
3837
vmImage: "ubuntu-latest"
3938
cli11.precompile: ON
4039
macOS17:
41-
vmImage: "macOS-latest"
40+
vmImage: "macOS-12"
4241
cli11.std: 17
4342
macOS11:
44-
vmImage: "macOS-latest"
43+
vmImage: "macOS-11"
4544
cli11.std: 11
4645
macOS11PC:
47-
vmImage: "macOS-latest"
46+
vmImage: "macOS-11"
4847
cli11.std: 11
4948
cli11.precompile: ON
5049
Windows17:

conanfile.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class CLI11Conan(ConanFile):
2828
"README.md",
2929
"include/*",
3030
"src/*",
31+
"fuzz/*",
3132
"extern/*",
3233
"cmake/*",
3334
"CMakeLists.txt",

fuzz/CMakeLists.txt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
if(CMAKE_CXX_STANDARD GREATER 16)
2+
if(CLI11_FUZZ_TARGET)
3+
4+
add_executable(cli11_app_fuzzer cli11_app_fuzz.cpp fuzzApp.cpp fuzzApp.hpp)
5+
target_link_libraries(cli11_app_fuzzer PUBLIC CLI11)
6+
set_property(TARGET cli11_app_fuzzer PROPERTY FOLDER "Tests")
7+
8+
add_executable(cli11_file_fuzzer cli11_file_fuzz.cpp fuzzApp.cpp fuzzApp.hpp)
9+
target_link_libraries(cli11_file_fuzzer PUBLIC CLI11)
10+
set_property(TARGET cli11_file_fuzzer PROPERTY FOLDER "Tests")
11+
12+
if(NOT CLI11_FUZZ_ARTIFACT_PATH)
13+
set(CLI11_FUZZ_ARTIFACT_PATH ${PROJECT_BINARY_DIR}/fuzz)
14+
endif()
15+
16+
if(NOT CLI11_FUZZ_TIME)
17+
set(CLI11_FUZZ_TIME 360)
18+
endif()
19+
add_custom_target(
20+
QUICK_CLI11_APP_FUZZ
21+
COMMAND ${CMAKE_COMMAND} -E make_directory corp
22+
COMMAND
23+
cli11_app_fuzzer corp -max_total_time=${CLI11_FUZZ_TIME} -max_len=2048
24+
-dict=${CMAKE_CURRENT_SOURCE_DIR}/fuzz_dictionary1.txt
25+
-exact_artifact_path=${CLI11_FUZZ_ARTIFACT_PATH}/cli11_app_fail_artifact.txt)
26+
27+
add_custom_target(
28+
QUICK_CLI11_FILE_FUZZ
29+
COMMAND ${CMAKE_COMMAND} -E make_directory corp
30+
COMMAND
31+
cli11_file_fuzzer corp -max_total_time=${CLI11_FUZZ_TIME} -max_len=2048
32+
-dict=${CMAKE_CURRENT_SOURCE_DIR}/fuzz_dictionary2.txt
33+
-exact_artifact_path=${CLI11_FUZZ_ARTIFACT_PATH}/cli11_file_fail_artifact.txt)
34+
35+
else()
36+
if(CLI11_BUILD_EXAMPLES)
37+
add_executable(cli11Fuzz fuzzCommand.cpp fuzzApp.cpp fuzzApp.hpp)
38+
target_link_libraries(cli11Fuzz PUBLIC CLI11)
39+
set_property(TARGET cli11Fuzz PROPERTY FOLDER "Examples")
40+
endif()
41+
endif()
42+
endif()

fuzz/cli11_app_fuzz.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright (c) 2019-2022,
3+
Lawrence Livermore National Security, LLC;
4+
See the top-level NOTICE for additional details. All rights reserved.
5+
SPDX-License-Identifier: BSD-3-Clause
6+
*/
7+
8+
#include "fuzzApp.hpp"
9+
#include <CLI/CLI.hpp>
10+
#include <cstring>
11+
#include <exception>
12+
#include <string>
13+
14+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
15+
if(Size == 0) {
16+
return 0;
17+
}
18+
std::string parseString(reinterpret_cast<const char *>(Data), Size);
19+
20+
CLI::FuzzApp fuzzdata;
21+
22+
auto app = fuzzdata.generateApp();
23+
try {
24+
app->parse(parseString);
25+
} catch(const CLI::ParseError &e) {
26+
//(app)->exit(e);
27+
// this just indicates we caught an error known by CLI
28+
}
29+
30+
return 0; // Non-zero return values are reserved for future use.
31+
}

0 commit comments

Comments
 (0)