diff --git a/CMakeLists.txt b/CMakeLists.txt index 1aca238..3130487 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,22 +1,12 @@ cmake_minimum_required (VERSION 3.11) -set(git_version 0) -find_package(Git) -if (Git_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-list --count HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE git_version - OUTPUT_STRIP_TRAILING_WHITESPACE - ) -endif() -message(STATUS "diagon git_version: ${git_version}") - project(Diagon LANGUAGES C CXX VERSION 1.0.127 ) +option(DIAGON_BUILD_TESTS_FUZZER "Set to ON to enable fuzzing" OFF) + include(FetchContent) set(FETCHCONTENT_QUIET FALSE) @@ -224,3 +214,7 @@ set(CPACK_DEBIAN_PACKAGE_VERSION ${PROJECT_VERSION}) set(CPACK_RPM_PACKAGE_LICENSE MIT) include(CPack) + +if (DIAGON_BUILD_TESTS_FUZZER) + include(cmake/diagon_fuzzer.cmake) +endif() diff --git a/cmake/diagon_fuzzer.cmake b/cmake/diagon_fuzzer.cmake new file mode 100644 index 0000000..8c42b3f --- /dev/null +++ b/cmake/diagon_fuzzer.cmake @@ -0,0 +1,8 @@ +set(CMAKE_C_COMPILER clang) +set(CMAKE_CXX_COMPILER clang++) + +add_executable(fuzzer src/fuzzer.cpp) +target_compile_options(fuzzer PRIVATE -fsanitize=fuzzer,address) +target_link_libraries(fuzzer PRIVATE -fsanitize=fuzzer,address) +target_link_libraries(fuzzer PRIVATE diagon_lib) +target_set_common(fuzzer) diff --git a/src/fuzzer.cpp b/src/fuzzer.cpp new file mode 100644 index 0000000..1acaf77 --- /dev/null +++ b/src/fuzzer.cpp @@ -0,0 +1,42 @@ +#include +#include +#include "translator/Factory.h" + +int GeneratorInt(const char* data, size_t& size) { + if (size == 0) + return 0; + auto out = int(data[0]); + data++; + size--; + return out; +} + +std::string GeneratorString(const char*& data, size_t& size) { + int index = 0; + while (index < size && data[index]) + ++index; + + auto out = std::string(data, data + index); + data += index; + size -= index; + + return out; +} + +extern "C" int LLVMFuzzerTestOneInput(const char* data, size_t size) { + auto& translators = TranslatorList(); + auto& translator = translators[GeneratorInt(data, size) % translators.size()]; + std::string input = GeneratorString(data, size); + std::string options = GeneratorString(data, size); + if (translator->Name()) + return 0; + try { + translator->Translate(input, options); + } catch (...) { + } + return 0; // Non-zero return values are reserved for future use. +} + +// Copyright 2021 Arthur Sonzogni. All rights reserved. +// Use of this source code is governed by the MIT license that can be found in +// the LICENSE file. diff --git a/src/translator/sequence/Sequence.cpp b/src/translator/sequence/Sequence.cpp index fc69691..bc86ac2 100644 --- a/src/translator/sequence/Sequence.cpp +++ b/src/translator/sequence/Sequence.cpp @@ -286,6 +286,8 @@ std::string Sequence::Translate(const std::string& input, ComputeInternalRepresentation(input); UniformizeInternalRepresentation(); + if (actors.size() == 0) + return ""; SplitByBackslashN(); Layout(); return Draw(); @@ -537,7 +539,8 @@ void Sequence::LayoutComputeActorsPositions() { spaces.push_back(space); } - actors[0].center = actors[0].name.size() / 2 + 1; + if (actors.size() != 0) + actors[0].center = actors[0].name.size() / 2 + 1; bool modified = true; int i = 0; diff --git a/test/Sequence/empty/input b/test/Sequence/empty/input new file mode 100644 index 0000000..e69de29 diff --git a/test/Sequence/empty/output b/test/Sequence/empty/output new file mode 100644 index 0000000..e69de29