diff --git a/.github/fuzz/makefile b/.github/fuzz/makefile new file mode 100644 index 0000000..ac2b770 --- /dev/null +++ b/.github/fuzz/makefile @@ -0,0 +1,7 @@ +EXE=ssp_fuzz + +all: + clang++ ${CXXFLAGS} ssp_fuzz.cpp -fsanitize=fuzzer -std=c++17 -o ${EXE} + +run: + ./${EXE} -max_total_time=900 diff --git a/.github/fuzz/ssp_fuzz.cpp b/.github/fuzz/ssp_fuzz.cpp new file mode 100644 index 0000000..599cd30 --- /dev/null +++ b/.github/fuzz/ssp_fuzz.cpp @@ -0,0 +1,81 @@ +#include "../../ssp.hpp" +#include +#include +#include + +template +void test_ssp_file_mode(const uint8_t* data, size_t size, + std::string delim = ss::default_delimiter) { + std::string file_name = std::filesystem::temp_directory_path().append( + "ss_fuzzer" + std::to_string(getpid()) + ".csv"); + FILE* file = std::fopen(file_name.c_str(), "wb"); + if (!file) { + std::exit(1); + } + std::fwrite(data, size, 1, file); + std::fclose(file); + + ss::parser p{file_name.c_str(), delim}; + while (!p.eof()) { + try { + const auto& [s0, s1] = + p.template get_next(); + if (s0.size() == 10000) { + std::cout << s0.size() << std::endl; + } + } catch (ss::exception& e) { + continue; + } + } + + std::remove(file_name.c_str()); +} + +template +void test_ssp_buffer_mode(const uint8_t* data, size_t size, + std::string delim = ss::default_delimiter) { + ss::parser p{(const char*)data, size, delim}; + while (!p.eof()) { + try { + const auto& [s0, s1] = + p.template get_next(); + if (s0.size() == 10000) { + std::cout << s0.size() << std::endl; + } + } catch (ss::exception& e) { + continue; + } + } +} + +template +void test_ssp(const uint8_t* data, size_t size) { + test_ssp_file_mode(data, size); + test_ssp_file_mode(data, size); + + test_ssp_file_mode(data, size, ":::"); + test_ssp_file_mode(data, size, ":::"); + + test_ssp_buffer_mode(data, size); + test_ssp_buffer_mode(data, size); + + test_ssp_buffer_mode(data, size, ":::"); + test_ssp_buffer_mode(data, size, ":::"); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + using escape = ss::escape<'\\'>; + using quote = ss::quote<'"'>; + using trim = ss::trim<' ', '\t'>; + using multiline_r = ss::multiline_restricted<5>; + + test_ssp<>(data, size); + test_ssp(data, size); + test_ssp(data, size); + test_ssp(data, size); + test_ssp(data, size); + test_ssp(data, size); + test_ssp(data, size); + + return 0; +} diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml new file mode 100644 index 0000000..8ebb126 --- /dev/null +++ b/.github/workflows/fuzz.yml @@ -0,0 +1,43 @@ +name: fuzz-ci + +on: + workflow_dispatch: + + push: + branches: + - master + - feature/** + - improvement/** + - bugfix/** + + pull_request: + branches: + - master + - feature/** + - improvement/** + - bugfix/** + +jobs: + clang_tests: + if: >- + ! contains(toJSON(github.event.commits.*.message), '[skip ci]') && + ! contains(toJSON(github.event.commits.*.message), '[skip github]') + + runs-on: ubuntu-latest + + name: "Fuzzing" + + container: + image: silkeh/clang:15 + options: -v /usr/local:/host_usr_local + + steps: + - uses: actions/checkout@v1 + + - name: Build + working-directory: .github/fuzz + run: make + + - name: Run + working-directory: .github/fuzz + run: make run diff --git a/README.md b/README.md index 2cc63f5..ec3a76c 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![coverage](https://coveralls.io/repos/github/red0124/ssp/badge.svg?branch=master)](https://coveralls.io/github/red0124/ssp?branch=master) +[![fuzz](https://github.com/red0124/ssp/workflows/fuzz-ci/badge.svg)](https://github.com/red0124/ssp/actions/workflows/fuzz.yml) [![single-header](https://github.com/red0124/ssp/workflows/single-header-ci/badge.svg)](https://github.com/red0124/ssp/actions/workflows/single-header.yml) [![ubuntu-latest-gcc](https://github.com/red0124/ssp/workflows/ubuntu-latest-gcc-ci/badge.svg)](https://github.com/red0124/ssp/actions/workflows/ubuntu-latest-gcc.yml) [![ubuntu-latest-clang](https://github.com/red0124/ssp/workflows/ubuntu-latest-clang-ci/badge.svg)](https://github.com/red0124/ssp/actions/workflows/ubuntu-latest-clang.yml)