diff --git a/meson.build b/meson.build index f5b7ad88a..fe37628a1 100644 --- a/meson.build +++ b/meson.build @@ -112,6 +112,13 @@ if get_option('buildtype') != 'debug' ] endif +if get_option('fuzzer') + fuzzer_flags = ['-fsanitize=fuzzer,address,undefined'] + add_global_arguments(fuzzer_flags, language: 'cpp') + add_global_arguments(fuzzer_flags, language: 'c') + add_global_link_arguments(fuzzer_flags, language: 'cpp') +endif + add_global_arguments(common_cxxflags + compiler.get_supported_arguments(test_cxxflags), language: 'cpp') add_global_arguments(common_cflags + c_compiler.get_supported_arguments(test_cflags), language: 'c') add_global_link_arguments(compiler.get_supported_link_arguments(test_ldflags), language: 'cpp') @@ -502,6 +509,7 @@ mpd = build_target( chromaprint_dep, ], link_args: link_args, + build_by_default: not get_option('fuzzer'), install: not is_android and not is_haiku, ) @@ -542,3 +550,7 @@ subdir('doc') if get_option('test') subdir('test') endif + +if get_option('fuzzer') + subdir('test/fuzzer') +endif diff --git a/meson_options.txt b/meson_options.txt index 992cffd36..a1c5ec1ed 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,6 +17,7 @@ option('systemd_user_unit_dir', type: 'string', description: 'systemd user servi # option('test', type: 'boolean', value: false, description: 'Build the unit tests and debug programs') +option('fuzzer', type: 'boolean', value: false, description: 'Build fuzzers (requires libFuzzer)') # # Android diff --git a/test/fuzzer/FuzzCueParser.cxx b/test/fuzzer/FuzzCueParser.cxx new file mode 100644 index 000000000..912cabf6a --- /dev/null +++ b/test/fuzzer/FuzzCueParser.cxx @@ -0,0 +1,26 @@ +#include "playlist/cue/CueParser.hxx" +#include "util/IterableSplitString.hxx" + +#include +#include + +extern "C" { +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + CueParser parser; + + const std::string_view src{(const char *)data, size}; + + for (const auto line : IterableSplitString(src, '\n')) { + parser.Feed(std::string(line).c_str()); + parser.Get(); + } + + parser.Finish(); + parser.Get(); + + return 0; +} diff --git a/test/fuzzer/meson.build b/test/fuzzer/meson.build new file mode 100644 index 000000000..6a87f99ea --- /dev/null +++ b/test/fuzzer/meson.build @@ -0,0 +1,9 @@ +executable( + 'FuzzCueParser', + 'FuzzCueParser.cxx', + '../../src/playlist/cue/CueParser.cxx', + include_directories: inc, + dependencies: [ + tag_dep, + ], +)