From 1791e30e4276deffb471375ccf023764b4245de2 Mon Sep 17 00:00:00 2001 From: Sascha Brawer Date: Mon, 12 Mar 2018 21:30:34 +0100 Subject: [PATCH] Add a fuzz target for SSML input https://github.com/espeak-ng/espeak-ng/issues/407 --- .gitignore | 4 ++ Makefile.am | 24 ++++++++ tests/fuzzrunner.c | 56 +++++++++++++++++++ tests/ssml-fuzzer.c | 52 +++++++++++++++++ ...e74d96310ff38a0747812810a713d21dab708.ssml | 6 ++ ...3d4601ced9346305e5b66b1e3d2012395ab25.ssml | 1 + ...9484e6a29123590ba3400bb1d4d834e2f3d03.ssml | 2 + 7 files changed, 145 insertions(+) create mode 100644 tests/fuzzrunner.c create mode 100644 tests/ssml-fuzzer.c create mode 100644 tests/ssml-fuzzer/100e74d96310ff38a0747812810a713d21dab708.ssml create mode 100644 tests/ssml-fuzzer/ca53d4601ced9346305e5b66b1e3d2012395ab25.ssml create mode 100644 tests/ssml-fuzzer/cf29484e6a29123590ba3400bb1d4d834e2f3d03.ssml diff --git a/.gitignore b/.gitignore index d974d4d9..0c7d9b55 100644 --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,10 @@ libespeak-ng-test.a libespeak-ng-test.la libespeak-ng-test.so* +tests/libfuzzrunner.a +tests/libfuzzrunner.la +tests/libfuzzrunner.so* + # build output *.html diff --git a/Makefile.am b/Makefile.am index 3946f322..4760f731 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,6 +66,7 @@ install-exec-hook: clean-local: cd src && rm -f *.o *~ && cd .. cd src/libespeak-ng/ && rm -f *.o *.lo && cd ../.. + cd tests && rm -f *.o *.lo && cd .. if HAVE_GRADLE cd android && $(GRADLE) clean endif @@ -252,10 +253,33 @@ check: tests/encoding.check \ tests/readclause.check \ tests/translate.check \ tests/ssml.check \ + tests/ssml-fuzzer.check \ tests/api.check \ tests/language-phonemes.check \ tests/language-pronunciation.check + +##### fuzzer: + +# When OSS-Fuzz [https://github.com/google/oss-fuzz] runs our fuzzer, it sets +# LIB_FUZZING_ENGINE to libFuzzer [http://llvm.org/docs/LibFuzzer.html]. +# When running outside OSS-Fuzz, we link against our own stub fuzzrunner. +LIB_FUZZING_ENGINE ?= tests/libfuzzrunner.la + +lib_LTLIBRARIES += tests/libfuzzrunner.la +tests_libfuzzrunner_la_CFLAGS = -Isrc/libespeak-ng ${AM_CFLAGS} +tests_libfuzzrunner_la_SOURCES = tests/fuzzrunner.c + +noinst_bin_PROGRAMS += tests/ssml-fuzzer.test +tests_ssml_fuzzer_test_LDADD = src/libespeak-ng.la ${LIB_FUZZING_ENGINE} +tests_ssml_fuzzer_test_SOURCES = tests/ssml-fuzzer.c +tests_ssml_fuzzer_test_DEPENDENCIES = src/libespeak-ng.la tests/libfuzzrunner.la + +tests/ssml-fuzzer.check: tests/ssml-fuzzer.test + @echo " TEST $<" + @ESPEAK_DATA_PATH=$(PWD) $< tests/ssml/*.ssml tests/ssml-fuzzer/*.ssml && echo " PASSED $<" + + ##### phoneme data: espeak-ng-data/phondata: phsource/phonemes.stamp diff --git a/tests/fuzzrunner.c b/tests/fuzzrunner.c new file mode 100644 index 00000000..680d2cb2 --- /dev/null +++ b/tests/fuzzrunner.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2018 Sascha Brawer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write see: + * . + */ + +#include "config.h" +#include "speech.h" + +#include +#include +#include +#include + +#include + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); + +int main(int argc, char **argv) { + int i; + + for (i = 1; i < argc; i++) { + size_t filesize = GetFileLength(argv[i]); + FILE *stream = fopen(argv[i], "r"); + unsigned char *text = NULL; + if (stream == NULL) { + perror(argv[i]); + exit(EXIT_FAILURE); + } + + text = (unsigned char *) malloc(filesize + 1); + if (text == NULL) { + espeak_ng_PrintStatusCodeMessage(ENOMEM, stderr, NULL); + exit(EXIT_FAILURE); + } + + fread(text, 1, filesize, stream); + text[filesize] = 0; + fclose(stream); + LLVMFuzzerTestOneInput(text, filesize); + } + + return EXIT_SUCCESS; +} diff --git a/tests/ssml-fuzzer.c b/tests/ssml-fuzzer.c new file mode 100644 index 00000000..d5bea200 --- /dev/null +++ b/tests/ssml-fuzzer.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 Sascha Brawer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write see: + * . + */ + +#include "config.h" + +#include +#include + +#include + +static int initialized = 0; + +static int SynthCallback(short *wav, int numsamples, espeak_EVENT *events) { + /* prevent warning for unused arguments */ + (void) wav; + (void) numsamples; + (void) events; + + return 0; +} + + +/* See http://llvm.org/docs/LibFuzzer.html */ +extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (!initialized) { + espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, 0, NULL, 0); + espeak_SetSynthCallback(SynthCallback); + initialized = 1; + } + + int synth_flags = espeakCHARS_UTF8 | espeakPHONEMES | espeakSSML; + espeak_Synth((char*) data, size + 1, 0, POS_CHARACTER, 0, + synth_flags, NULL, NULL); + + return 0; +} diff --git a/tests/ssml-fuzzer/100e74d96310ff38a0747812810a713d21dab708.ssml b/tests/ssml-fuzzer/100e74d96310ff38a0747812810a713d21dab708.ssml new file mode 100644 index 00000000..eae9e8b3 --- /dev/null +++ b/tests/ssml-fuzzer/100e74d96310ff38a0747812810a713d21dab708.ssml @@ -0,0 +1,6 @@ + + +

Test

+
diff --git a/tests/ssml-fuzzer/ca53d4601ced9346305e5b66b1e3d2012395ab25.ssml b/tests/ssml-fuzzer/ca53d4601ced9346305e5b66b1e3d2012395ab25.ssml new file mode 100644 index 00000000..fb8345ff --- /dev/null +++ b/tests/ssml-fuzzer/ca53d4601ced9346305e5b66b1e3d2012395ab25.ssml @@ -0,0 +1 @@ +B"!"";"ó.<<<