diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6c08706..8e349b16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,27 +16,27 @@ jobs: strategy: fail-fast: false matrix: - arch: [x86-32, x86-64] + arch: [x86-64, x86-32] sanitizer: [no, address, leak, memory, thread, undefined, valgrind] include: - sanitizer: "no" deps: "" - configflags: "" + configflags: "-g -Og -fno-omit-frame-pointer" config: "" build_env: "" check_env: "" - sanitizer: "address" deps: "" - configflags: "-fsanitize=address -g -Og" + configflags: "-fsanitize=address -g -Og -fno-omit-frame-pointer" config: "" build_env: "ASAN_OPTIONS=detect_leaks=0" check_env: "ASAN_OPTIONS=detect_leaks=0" - sanitizer: "leak" deps: "" - configflags: '-fsanitize=leak -g -Og' + configflags: '-fsanitize=leak -g -Og -fno-omit-frame-pointer' config: "" build_env: "LSAN_OPTIONS=fast_unwind_on_malloc=0" check_env: "LSAN_OPTIONS=fast_unwind_on_malloc=0" @@ -44,28 +44,28 @@ jobs: - sanitizer: "memory" deps: "clang" configenv: "CC=clang CXX=clang++" - configflags: "-fsanitize=memory -fsanitize-memory-track-origins=2 -g -Og" + configflags: "-fsanitize=memory -fsanitize-memory-track-origins=2 -g -Og -fno-omit-frame-pointer" config: "--without-pcaudiolib" build_env: "MSAN_OPTIONS=exitcode=42" check_env: "MSAN_OPTIONS=exitcode=42" - sanitizer: "thread" deps: "" - configflags: "-fsanitize=thread -g -Og" + configflags: "-fsanitize=thread -g -Og -fno-omit-frame-pointer" config: "" build_env: "" check_env: "" - sanitizer: "undefined" deps: "" - configflags: "-fsanitize=undefined -g -Og" + configflags: "-fsanitize=undefined -g -Og -fno-omit-frame-pointer" config: "" build_env: "UBSAN_OPTIONS=halt_on_error=1" check_env: "UBSAN_OPTIONS=halt_on_error=1" - sanitizer: "valgrind" deps: "libtool-bin valgrind" - configflags: '' + configflags: '-g -Og -fno-omit-frame-pointer' config: "" build_env: 'VALGRIND="libtool --mode=execute valgrind --track-origins=yes --leak-check=full --error-exitcode=1" ' check_env: 'VALGRIND="libtool --mode=execute valgrind --track-origins=yes --leak-check=full --error-exitcode=1" ' @@ -119,7 +119,7 @@ jobs: strategy: fail-fast: false matrix: - arch: [x86-32, x86-64] + arch: [x86-64, x86-32] include: - arch: x86-32 @@ -140,7 +140,7 @@ jobs: - name: autoconf run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 - name: run - run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" ./configure && make clean && make && make check && touch success' success + run: reprotest 'CFLAGS="${{ matrix.archconfigflags }}" CXXFLAGS="${{ matrix.archconfigflags }}" ./configure --without-gradle && make clean && make && make check && touch success' success distcheck: diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml new file mode 100644 index 00000000..c4cfd424 --- /dev/null +++ b/.github/workflows/fuzzing.yml @@ -0,0 +1,64 @@ +name: fuzzing + +on: + workflow_dispatch: + schedule: + - cron: "0 4 * * 1" + +jobs: + fuzzing: + + runs-on: ubuntu-latest + name: Fuzz synth_espeak on ${{ matrix.arch }} for ${{ matrix.lang }} + strategy: + fail-fast: false + matrix: + arch: [x86-64, x86-32] + lang: [af, am, an, ar, as, az, ba, be, bg, bn, bpy, bs, ca, chr, cmn, cs, cv, cy, da, de, el, en, eo, es, et, eu, fa, fi, fr, ga, gd, gn, grc, gu, hak, haw, he, hi, hr, ht, hu, hy, ia, id, io, is, it, ja, jbo, ka, kk, kl, kn, ko, kok, ku, ky, la, lb, lfn, lt, lv, mi, mk, ml, mr, ms, mt, my, nci, ne, nl, no, nog, om, or, pa, pap, piqd, pl, pt, py, qdb, qu, quc, qya, ro, ru, sd, shn, si, sjn, sk, sl, smj, sq, sr, sv, sw, ta, te, th, tk, tn, tr, tt, ug, uk, ur, uz, vi, yue] + include: + - arch: x86-32 + archdeps: "gcc-multilib g++-multilib libpcaudio-dev:i386 libsonic-dev:i386 libc6-dbg:i386" + archconfigflags: "-m32" + + - arch: x86-64 + archdeps: "" + archconfigflags: '' + steps: + - uses: actions/checkout@v2 + - name: enable 32bit architecture + run: sudo dpkg --add-architecture i386 + if: matrix.arch == 'x86-32' + - name: dependencies + run: sudo apt-get update && sudo apt-get install libpcaudio-dev libsonic-dev ronn kramdown clang llvm ${{ matrix.archdeps }} + - name: autoconf + run: ./autogen.sh ; chmod -x INSTALL m4/*.m4 + - name: configure + run: CC=clang CXX=clang++ + CFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer" + CXXFLAGS="${{ matrix.archconfigflags }} -fsanitize=address,undefined -fstack-protector-strong -g -Og -fno-omit-frame-pointer" + LDFLAGS="-fsanitize=address,undefined -lubsan" + ./configure --with-libfuzzer + - name: Store the fuzzer config + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: config-${{ matrix.arch }}-${{ matrix.lang }}.log + path: config.log + - name: make + run: make -j + - name: Fuzz function synth_espeak() + run: mkdir tests/fuzzing/CORPUS_DIR ; FUZZ_VOICE=${{ matrix.lang }} tests/fuzzing/synth_fuzzer.test -seed=1 -runs=10000 -max_len=4096 tests/fuzzing/CORPUS_DIR + - name: Store the crash POC + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: crash-${{ matrix.arch }}-${{ matrix.lang }}.1 + path: crash-* + - name: Fuzz function synth_espeak() with language-specific input + run: cp dictsource/${{ matrix.lang }}_* tests/fuzzing/CORPUS_DIR/ ; FUZZ_VOICE=${{ matrix.lang }} tests/fuzzing/synth_fuzzer.test -seed=1 -runs=10000 -max_len=4096 tests/fuzzing/CORPUS_DIR + - name: Store the crash POC + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: crash-${{ matrix.arch }}-${{ matrix.lang }}.2 + path: crash-* diff --git a/.gitignore b/.gitignore index fe6bbdae..73dd7f93 100644 --- a/.gitignore +++ b/.gitignore @@ -123,10 +123,19 @@ espeak-ng.pc espeak-ng-*.tar.gz espeak-ng-*.*/ +# /tests/fuzzing/ +/tests/fuzzing/crash-* +/tests/fuzzing/oom-* +/tests/fuzzing/leak-* +/tests/fuzzing/fuzz-*.log +/tests/fuzzing/*.profdata +/tests/fuzzing/*.profraw +/tests/fuzzing/.deps/*.Po +/tests/fuzzing/.dirstamp +!tests/fuzzing/CORPUS*/*.txt # Windows builds src/pcaudiolib/ - !src/windows/config.h *.obj diff --git a/CHANGELOG.md b/CHANGELOG.md index aa303e8e..08f875c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,20 @@ The espeak-ng project is a fork of the espeak project. ### 1.52 (In Development) updated languages: +* ba (Bashkir) -- Andiv06 * be (Belarusian) -- Andiv06 * en (English) -- Bill Dengler * es (Spanish) -- Sukil Etxenike +* fa (Persian) -- MH +* he (Hebrew) -- Omer I.S +* it (Italian) -- Christian Leo Mameli +* ro (Romanian) -- Andiv06 +* be (Belarusian) -- Andiv06 +* en (English) -- Bill Dengler +* es (Spanish) -- Sukil Etxenike +* kl (Greenlandic) -- Andiv06 +* qdb (Lang Belta) -- Andiv06 +* quc (K'iche') -- Andiv06 ### 1.51 diff --git a/Makefile.am b/Makefile.am index f8f1f910..0ba39b90 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,6 +18,12 @@ MKDIR=mkdir -p AM_CFLAGS = \ -Isrc/include -Isrc/include/compat -I$(srcdir)/src/speechPlayer/include -I$(srcdir)/src/ucd-tools/src/include \ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L +AM_CXXFLAGS = + +if USE_COVERAGE +AM_CFLAGS += -fprofile-instr-generate -fcoverage-mapping +AM_CXXFLAGS += -fprofile-instr-generate -fcoverage-mapping +endif EXTRA_DIST= CLEANFILES = dictsource/ru_listx dictsource/cmn_listx dictsource/yue_listx @@ -321,6 +327,8 @@ tests_libfuzzrunner_la_CFLAGS = -Isrc/libespeak-ng ${AM_CFLAGS} tests_libfuzzrunner_la_SOURCES = tests/fuzzrunner.c endif + + check_PROGRAMS += tests/ssml-fuzzer.test tests_ssml_fuzzer_test_CFLAGS = ${AM_CFLAGS} tests_ssml_fuzzer_test_SOURCES = tests/ssml-fuzzer.c @@ -333,9 +341,16 @@ tests_readclause_test_SOURCES += tests/dummy.cpp tests_ssml_fuzzer_test_SOURCES += tests/dummy.cpp endif + if HAVE_LIBFUZZER tests_ssml_fuzzer_test_CFLAGS += -fsanitize=fuzzer tests_ssml_fuzzer_test_LDFLAGS = -fsanitize=fuzzer + +noinst_PROGRAMS = tests/fuzzing/synth_fuzzer.test +tests_fuzzing_synth_fuzzer_test_SOURCES = tests/fuzzing/synth_fuzzer.c +tests_fuzzing_synth_fuzzer_test_LDADD = src/libespeak-ng.la +tests_fuzzing_synth_fuzzer_test_CFLAGS= ${AM_CFLAGS} -fsanitize=fuzzer -DPATH_ESPEAK_DATA=\"$(abs_top_srcdir)/espeak-ng-data\" -Isrc/libespeak-ng +tests_fuzzing_synth_fuzzer_test_LDFLAGS= ${AM_LDFLAGS} -fsanitize=fuzzer -static -lm -Wl,-z,relro ${PCAUDIOLIB_LIBS} else tests_ssml_fuzzer_test_LDADD += tests/libfuzzrunner.la endif @@ -488,6 +503,7 @@ dictionaries: \ espeak-ng-data/mr_dict \ espeak-ng-data/ms_dict \ espeak-ng-data/mt_dict \ + espeak-ng-data/mto_dict \ espeak-ng-data/my_dict \ espeak-ng-data/nci_dict \ espeak-ng-data/ne_dict \ @@ -750,6 +766,9 @@ espeak-ng-data/ms_dict: dictsource/ms_list dictsource/ms_rules dictsource/ms_ext mt: espeak-ng-data/mt_dict espeak-ng-data/mt_dict: dictsource/mt_list dictsource/mt_rules dictsource/mt_extra +mto: espeak-ng-data/mto_dict +espeak-ng-data/mto_dict: dictsource/mto_list dictsource/mto_rules + my: espeak-ng-data/my_dict espeak-ng-data/my_dict: dictsource/my_list dictsource/my_rules dictsource/my_extra dictsource/my_emoji diff --git a/android/build.gradle b/android/build.gradle index 13e09910..809c950e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -70,7 +70,7 @@ android { defaultConfig { minSdkVersion 14 targetSdkVersion 26 - versionCode 20 + versionCode 22 versionName "1.52-dev" } diff --git a/configure.ac b/configure.ac index 05a4a402..ed5c97ff 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,10 @@ AC_ARG_WITH([libfuzzer], [AS_HELP_STRING([--with-libfuzzer], [enable libFuzzer in the fuzzer tests @<:@default=no@:>@])], []) +AC_ARG_WITH([coverage], + [AS_HELP_STRING([--with-coverage], [enable clang coverage in the fuzzer tests (also add coverage to lib sources) @<:@default=no@:>@])], + []) + dnl ================================================================ dnl Program checks. dnl ================================================================ @@ -79,13 +83,13 @@ dnl gradle checks. dnl ================================================================ AC_MSG_CHECKING([for gradle]) -if test -e ${GRADLE} ; then - AC_MSG_RESULT([${GRADLE}]) - AM_CONDITIONAL(HAVE_GRADLE, [test 1 = 1]) +if command -v "$GRADLE" >/dev/null; then + AC_MSG_RESULT([$GRADLE]) else + GRADLE= AC_MSG_RESULT([no]) - AM_CONDITIONAL(HAVE_GRADLE, [test 1 = 0]) fi +AM_CONDITIONAL(HAVE_GRADLE, [test x"$GRADLE" != x]) AC_SUBST(GRADLE) @@ -131,6 +135,19 @@ else AC_MSG_ERROR([C99 is not supported by $CC.]) fi + +AC_LANG_PUSH(C) +TEMP_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -fsanitize=fuzzer" +AC_MSG_CHECKING([if $CC supports fuzzer with the -fsanitize=fuzzer flag]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( [[]], [[]])], + [have_fuzzer_fuzzer=yes], + [have_fuzzer_fuzzer=no]) +AC_MSG_RESULT($have_fuzzer_fuzzer) +CFLAGS="$TEMP_CFLAGS" +AC_LANG_POP(C) + dnl ================================================================ dnl FreeBSD check. dnl ================================================================ @@ -330,7 +347,19 @@ else have_libfuzzer=no fi -AM_CONDITIONAL(HAVE_LIBFUZZER, [test x"$have_libfuzzer" = xyes]) +AM_CONDITIONAL(HAVE_LIBFUZZER, [test x"$have_libfuzzer" = xyes -a x"$have_fuzzer_fuzzer" = xyes]) + +dnl ================================================================ +dnl clang-coverage checks. +dnl ================================================================ + +if test "$with_coverage" = "yes" ; then + use_coverage=yes +else + use_coverage=no +fi + +AM_CONDITIONAL(USE_COVERAGE, [test x"$use_coverage" = xyes]) dnl ================================================================ dnl Generate output. diff --git a/dictsource/ba_list b/dictsource/ba_list index 6e3e60e9..aa7a5033 100644 --- a/dictsource/ba_list +++ b/dictsource/ba_list @@ -49,32 +49,23 @@ _0 n'ul? _1 b'er _2 ik'e -_3 'WS; +_3 'Ws _4 d'yrt _5 b'iS _6 Alt'V -_7 Z;id'e -_8 sig'ez -_9 tug'Vz -_10 'un -_11 unb'er -_12 unik'e -_13 un'WS; -_14 und'yrt -_15 unb'iS -_16 unAlt'V -_17 unZ;id'e -_18 unsig'ez -_19 untug'Vz +_7 et'e +_8 hig'eD +_9 tug'VD +_1X 'un _2X egerm'e -_3X ut'Vz -_4X kVr'Vk +_3X ut'VD +_4X qVr'q _5X ill'e _6X Altm'VS -_7X Z;itm'eS -_8X siks'&n -_9X tuks'An -_0C j'Wz +_7X etm'eS +_8X hikh'&n +_9X tukh'An +_0C j'WD _0M1 m'eN _0M2 milli'on _1M2 milli'on diff --git a/dictsource/be_list b/dictsource/be_list index 23b57e1e..2f4eae30 100644 --- a/dictsource/be_list +++ b/dictsource/be_list @@ -45,10 +45,10 @@ _4 ts.ati"ri" _5 p;at; _6 s.Es;t; _7 s;Em -_8 vOs;jEm -_9 dz;Ev;at; -_10 dz;Es;at; -_11 adz;inats:at; +_8 vOs;E2m +_9 d;Ev;at; +_10 d;Es;at; +_11 ad;inats:at; _12 dvanats:at; _13 tri"nats:at; _14 ts.ati"rnats:at; @@ -56,7 +56,7 @@ _15 p;atnats:at; _16 s.asnats:at; _17 s;amnats:at; _18 vas;amnats:at; -_19 dz;Ev;atnats:at; +_19 d;Ev;atnats:at; _2X dvats:at; _3X tri"ts:at; _4X sorak diff --git a/dictsource/en_list b/dictsource/en_list index e253fa4a..7759e3fd 100644 --- a/dictsource/en_list +++ b/dictsource/en_list @@ -1129,6 +1129,7 @@ blurry bl3:ri boardmember $1 bobsled $alt1 boing bOIN +boise 'bOIsi $only bologna b@loUni bolognese b0l@n'eIz bombard $2 @@ -2295,6 +2296,7 @@ irises aIrIsI#z iron aI3n isochronous aIs'0kr@n@s isosceles aIs'0s@li:z +issaquah 'Is@kwA: ?3 issuance ISu:@ns invalidity I2nv@lIdI#ti @@ -3034,6 +3036,7 @@ psychosis saIk'oUsIs psychotic saIk'0tIk pud pUd // and pudding pueblo pwEbloU +puget pju:dZIt punative pju:n@tIv puny pju:ni purist pjU@Ist @@ -3258,6 +3261,7 @@ saliva s@laIv@ salmon sam@n ?3 salon $alt3 saloon $alt3 +sammamish s@'m'amIS san ,san $only sanguine $alt2 santoor $alt3 @@ -3403,6 +3407,7 @@ slough slVf $verb slugabed slVg@bEd snafu snafu: snafus snafu:z +snohomish snoU'hoUmIS snooker snu:k3 sociopath soUsI@paT sofa soUf@ diff --git a/dictsource/es_list b/dictsource/es_list index b4850644..b8c11bdc 100644 --- a/dictsource/es_list +++ b/dictsource/es_list @@ -335,7 +335,7 @@ Uds ustedes $text $capital $dot // pronunciation exceptions ser s'e@-* $only // it's not a abbrev vilmente $1 -deprimente $3 +depri $u $stem // Proper Names and countries amsterdam $3 bardem $2 diff --git a/dictsource/he_list b/dictsource/he_list index 08c8ebbe..81086e43 100644 --- a/dictsource/he_list +++ b/dictsource/he_list @@ -3,32 +3,47 @@ בּ bet ב vet ג 'gimel +גּ 'gimel ד 'dalet +דּ 'dalet ה he ו vav ז 'zajin +זּ 'zajin ח Xet ט tet +טּ tet י jod +יּ jod כּ kaf כ Xaf -ךּ kaf sofit -ך Xaf sofit +ךּ kaf so'fit +ך kaf so'fit ל 'lamed +לּ 'lamed מ mem -ם mem sofit +מּ mem +ם mem so'fit נ nun -ן nun sofit +נּ nun +ן nun so'fit ס 'sameX +סּ 'sameX ע ?ajin פּ pe פ fe ף pe sofit צ 'tsadi +צּ 'tsadi ץ 'tsadi sofit -ק kof -ר Q"eS +ק kof +קּ kof +ר Q"ejS +ש Sin +שּ Sin שׁ Sin +שּׁ Sin שׂ sin +שּׂ sin תּ tav -ת Tav +ת tav diff --git a/dictsource/he_listx b/dictsource/he_listx index cc731c0f..22fcd81c 100644 --- a/dictsource/he_listx +++ b/dictsource/he_listx @@ -9,8 +9,8 @@ בדיקה bdi'ka אנגלית ang'lit אני a'ni -הוא hu היא hi +הוא hu הם hem (את רוצה) at||Q"o'tsa באנגלית be?ang'lit @@ -135,3 +135,6 @@ אמת e'met נכון na'Xon ישר ja'SaQ" +בה ba +תה te +שה se diff --git a/dictsource/he_rules b/dictsource/he_rules index cd6d25e1..c936d5c3 100644 --- a/dictsource/he_rules +++ b/dictsource/he_rules @@ -17,6 +17,7 @@ אוּי ui אָ o אָ a + אה a .group ב ב v @@ -41,19 +42,34 @@ בּוּ bu בׇּ bo בָּ ba + בה va .group ג ג g + גּ g גַ ga + גַּ ga גֵ ge + גֵּ ge גֶ ge + גֶּ ge גְ g + גְּ g גִ gi + גִּ gi גוֹ go + גּוֹ go גי gi + גִּי gi גוּ gu + גּוּ gu + גֻ gu + גֻּ gu גׇ go + גׇּ go גָ ga + גָּ ga + גה ga ג' dZ גַ' dZa גֵ' dZe @@ -76,6 +92,8 @@ דוֹ do די di דוּ du + דו du + דה da דׇ do דָ da דּ d @@ -92,17 +110,19 @@ דָ' Da .group ה - ה ? - הַ a - הֵ e - הֶ e + ה h + הַ ha + הֵ he + הֶ he + הֱ he הְ h - הִ i - הוֹ o - הי i - הוּ u - הׇ o - הָ a + הִ hi + הוֹ ho + הי hi + הוּ hu + הׇ ho + הָ ha + הּ h .group ו ו v @@ -148,6 +168,7 @@ חוּ Xu חׇ Xo חָ Xa + חה Xa .group ט ט t @@ -161,6 +182,7 @@ טוּ tu טׇ to טָ ta + טה ta .group י י j @@ -195,6 +217,8 @@ ך X ךָ Xa ךְ X + ךָּ ka + ךְּ k .group ל ל l @@ -208,6 +232,7 @@ לוּ lu לׇ lo לָ la + לה la .group מ מ m @@ -221,6 +246,7 @@ מוּ mu מׇ mo מָ ma + מה ma .group ם ם m @@ -237,6 +263,7 @@ נוּ nu נׇ no נָ na + נה na נג N .group ן @@ -254,11 +281,13 @@ סוּ su סׇ so סָ sa + סה sa .group ע ע ? עַ aa עַי ai + עיי ai עֵ e עֶ e עֶי ei @@ -271,6 +300,7 @@ עוּי ui עָ o עָ a + עה a .group פ פ f @@ -298,6 +328,7 @@ .group ף ף f + ףּ p .group צ צ ts @@ -309,6 +340,7 @@ צוֹ tso צי tsi צוּ tsu + צה tsa צׇ tso צָ tsa צ' tS @@ -322,6 +354,7 @@ צ'וּ tSu צׇ' tSo צָ' tSa + צ'ה tSa .group ץ ץ ts @@ -339,6 +372,7 @@ קוּ ku קׇ ko קָ ka + קה ka .group ר ר Q" @@ -352,6 +386,7 @@ רוּ Q"u רׇ Q"o רָ Q"a + רה Q"a .group ש ש S @@ -377,6 +412,7 @@ שׂוּ su שׇׂ so שָׂ sa + שה Sa .group ת ת t @@ -402,6 +438,7 @@ ת'וּ Tu תׇ' To תָ' Ta + תה ta .group ׇ ׇ o diff --git a/dictsource/it_list b/dictsource/it_list index 65e51b6b..50767a5f 100644 --- a/dictsource/it_list +++ b/dictsource/it_list @@ -1,6 +1,6 @@ // This file is UTF-8 encoded -// Updated 2021 December 22 by Christian Leo M, +// Updated 2022 april 30 by Christian Leo Mameli, // $alt change [e] or [o] in the stressed syllable to [E] or [O] // $alt2 change [E] or [O] in the stressed syllable to [e] or [o] @@ -740,7 +740,7 @@ abbiamo $u+ $verbf abbiate $u+ abbiano $1 $verbf avessi av'es:i $verbf -avesse av'es:i $verbf +avesse av'es:e $verbf avessimo $u+ $verbf aveste av'este $verbf avessero $u+ $verbf @@ -2343,6 +2343,7 @@ beatle b'i:tol beccaria $3 beethoven be:t'o:ven benetton $3 +benjamin $1 bergomi $1 behringer b'e:RiNg,E@-* bertold $alt @@ -2367,6 +2368,7 @@ carey _^_en carmel $2 cassano $2 casula $2 +catherine _^_EN catia k'a:tia celentano $3 cesare $1 @@ -2696,6 +2698,7 @@ vainer v'aIne@-* $only valeria $2 $alt2 valter $1 $onlys van $u $capital $only +vanzetti vandz'Et:i vazquez vask'Ets vedder $1 $onlys vermouth v'E@-*mut @@ -3022,6 +3025,7 @@ avvalere $3 avvantaggiano $3 avvantaggino $3 avvelenino $3 +avventurano $3 avver $2 avverano $2 avverino $2 @@ -3068,7 +3072,7 @@ boccino $1 boicottino $3 bombardano $2 bombardino $2 -brahmano $1 +bramano $1 bramino $1 brancolano $1 brancolino $1 @@ -4111,6 +4115,7 @@ preoccupano $2 preoccupino $2 preordin $2 preparano $2 +prescegliere $2 presentino $2 presenziano $2 pressino $1 @@ -4132,9 +4137,10 @@ producano $2 profilano $2 programmano $2 proiettino $3 +prolunghino $2 pronuncino $2 propinino $2 - proponere $3 $alt +proponere $3 $alt propugnano $2 prorogano $1 prosciughino $2 @@ -4194,7 +4200,7 @@ ravvedere $3 ravvisano $2 ravvisino $2 razziano $1 -razziavano $3 +razziavano $2 reagii @-*eadZ'i:j realizzino $3 recano $1 @@ -4442,6 +4448,8 @@ scannino $1 scantono $2 scappano $1 scappino $1 +scarcer $1 +scarcerano $1 scardin $1 scaricano $1 scarichino $1 @@ -5041,6 +5049,7 @@ dirigiti $2 disabilital $3 disconnettiti $3 disegnaci $2 +dissolversi $2 distintasi $2 distintosi $2 domandatel $3 diff --git a/dictsource/it_listx b/dictsource/it_listx index 311796ee..21e839b9 100644 --- a/dictsource/it_listx +++ b/dictsource/it_listx @@ -3783,6 +3783,7 @@ stereotip $3 stesicor $2 stigmate $1 stilobate $2 +stipiti $1 stom $alt stomaci $1 stop $alt @@ -4045,6 +4046,7 @@ travesi $alt tre t@-*'e trenta $alt2 trebaseleghe $3 $alt2 +treccine $2 tredicesim $alt tredici $alt2 tremil $2 diff --git a/dictsource/kl_list b/dictsource/kl_list index 8db1c6a8..fbe27836 100644 --- a/dictsource/kl_list +++ b/dictsource/kl_list @@ -28,10 +28,10 @@ z zE // ø // å -// Native numbers 0-10 +// Native numbers 0-20 _0n n'u:lu -_1n at'a:sEq -_2n m'arluk +_1n at'a:s@q +_2n m'arl#uk _3n p'iNasut _4n s'isamat _5n t'al#imat @@ -40,6 +40,16 @@ _7n arfinEqm'arluk _8n arfinEqp'iNasut _9n quliNil'uat _10n q'ulit +_11n aqqanEq +_12n aqqanEqm'arl#uk +_13n aqqanEqp'iNasut +_14n aqqanEqs'isamat +_15n aqqanEqt'al#imat +_16n arfErs'anil#it +_17n arfErsanEqm'arl#uk +_18n arfErsanEqp'iNasut +_19n arfErsanEqs'isamat +_20n inukn'a:l#uQu // Danish numbers _0 'nOl diff --git a/dictsource/mto_list b/dictsource/mto_list new file mode 100644 index 00000000..969d17bc --- /dev/null +++ b/dictsource/mto_list @@ -0,0 +1,214 @@ +// This file is UTF8 encoded + +// letters + +_cap m'aJ^us +_?? s'imbolo +_#32 Esp'aTjo + +// accent names +_lig liQaD'ura +_acu aQ'uDo +_ac2 d'oble||aQ'uDo +_brv br'eBe +_ced seD'iJ^a +_cir sirkumfl'exo +_dia dj'Eresis +_dac d'oble||aQ'uDo +_dot p'unto +_grv gr'aBe +_hac kar'on +_mcn makr'on +_ogo kol'ita +_rng an'iJ^o +_stk b'aRR2a +_tld t'ilde +_sup supE**'indiTe +_sub suB'indiTe + + +// names of symbols +° grados +_. punto +_, koma +_; p,untoik'oma +_: d,osp'untos +_! TERR2'araDmiraTj'on +_? TERR2'arintERR2,oQaTj'on +_¡ aBr'iraDmiraTj'on +_¿ aBr'irintERR2,oQaTj'on +_< men'orke +_> maJ^'orke +_' apostr'ofo +ꞌ salt'il^o $only +_" kom'iJ^as +_- gJ^on +__ suBraJ^'aDo +_/ baRR2a +_\ b'aRR2aimbErt'iDa +_` aT'Ento||gr'aBe +_´ aT'Ento||aQ'uDo +_( ,aBrepar'Entesis +_) Tj,ERR2apar'Entesis +_[ ,aBrekortS'ete +_] Tj,ERR2akortS'ete +_{ ,aBreJ^'aBe +_} Tj,ERR2aJ^'aBe +_« kom'iJ^as||iTkJ^'ErDas +_» kom'iJ^as||dEr'EtSas += iQw'al ++ m'as +# almoaD'iJ^a +* astEr'isko +. punto +^ Tirkumfl'exo +₠ 'eU*o +€ eUro +% porTj'Ento +& ampErs'ant +@ aRR2'oBa +/ baRR2a +© kopiRR2'aIt +£ liBras +¶ p'aRR2afo +§ sEkTj'on +¬ n'ot +· p'unto||m'edjo + +// Language names + +_cyr Ti*'iliko_ +_hy arm'enjo +_he eB@-*'Eo +_ar 'a*aBe +_hi 'i:ndi +_bn beNg,al'i_ +_ta t'amil +_te tel'ugu +_si TiNgal'es +_th t'a:i +_my birm'ano +_ja x,apon'Es +_zh tS'ino + +// numbers +_0 nitija +_1 toU?k# +_2 mahtsk# +_3 toUoUhk# +_4 mAktAAz.k# +_5 mugooz.k# +_6 toUht8k# +_7 vuz.toUht8k# +_8 toUtoUht8k# +_9 tAz.toUht8k# +_1X mAhk# +_2x ii?p +_3X mAhk#ii?p +_4X v8htkup +_5X v8htkupmAhk# +_6X toUoUhk#ii?p +_7X toUoUhk#ii?pmAhk# +_8X mAktAAz.k#ii?p +_9X mAktAAz.k#ii?pmAhk# +_0C mugooz.k#ii?p +_dpt koma +_roman Rom'ano + +// ordinal numbers +_#º o +_#ª a +_ord mu +ºc gr'ados||T'e +ºf gr'ados||'Efe +ºk gr'ados||k'a + +// Letters (names taken from Spanish) +// If a letter has a "word" pronunciation which is different from its +// "letter" name, then include the letter name here, with the letter +// prefixed by a _ character. + +_b be +_c Te +_d de +_f Efe +_g xe +_h atSe +_j xota +_k ka +_l Ele +_m Eme +_n Ene +_ñ En^e +_p pe +_q ku +_r Ere +_s Ese +_t te +_v uBe +_w uBe||d'oBle +_x Ekis +_z TEta + +_a a +_e e +_o o +_y igri'eQa +_á 'a||aTEntw'aDa +_é 'e||aTEntw'aDa +_í 'i||aTEntw'aDa +_ó 'o||aTEntw'aDa +_ú 'u||aTEntw'aDa +_ü 'u||kon||dj'ErEsis +_ç $accent + +// Proper Names and countries +amsterdam $3 +bardem $2 +jerusalem $4 +méxico m'Exiko +vietnam $2 + +// foreign words + +android 'androId +apple 'ap@l +copyright k'opiRR2,aIt +chrome kr'owm +curriculum $2 +diem d'i:em $only +eloquence 'elokwens +english ínglish $text +espeak 'isp'ik +eyes 'aIs +facebook f'eIsbuk +firefox f'aIrfoks +free fr'i +google g'ug@l +hardware h'ardwer +iphone 'aIfon +ipod 'aIpod +jaws dZ'os +jazz dZ'as +linux $1 +live l'aIB +messenger m'esendZer +microsoft m'aIkrosoft +mozilla moT'ila +office 'ofis +platform pl'atfom +power p'awer +service s'erBis +skype sk'aIp +snapshot sn'apS,ot // _^_en +software s'oftwer +spanish sp'aniS +speech sp'itS +thunderbird t'anderbird +twit tw'it +twitter tw'iter +window w'indow + +(e speak) 'isp'ik +(i phone) 'aIfon +(i pod) 'aIpod diff --git a/dictsource/mto_rules b/dictsource/mto_rules new file mode 100644 index 00000000..d75ee175 --- /dev/null +++ b/dictsource/mto_rules @@ -0,0 +1,107 @@ +// Translation rules for mto +// This file is UTF-8 encoded + +.L01 a e i o u ä ë ï ö ü +.L02 m n + +.group a + a a + +.group ä + ä A + +.group e + e e + +.group ë + ë @ + +.group i + i i + +.group ï + ï 8 + +.group o + o o + +.group ö + ö oU + +.group u + u u + +.group v + v(_ f + _)v(o b + j)v vj + v(j vj + v v + +.group s + s s + +.group x + L01)x z. + L02)x z. + j)x s.j + x(j s.j + x s. + +.group j + j h + +.group ts + %L01)ts dz + L02)ts dz + j)ts tsj + ts(j tsj + ts ts + +.group p + L01)p(L01 b + L02)p(L01 b + p(_ p# + j)p pj + p(j pj + p p + +.group t + L01)t(L01 d + L02)t(L01 d + j)t tj + t(j tj + t(_ t# + t t + +.group k + L01)k(L01 g + L02)k(L01 g + k(_ k# + j)k kj + k(j kj + k k + +.group ꞌ + ꞌ ? + +.group m + j)m mj + m(j mj + m m + +.group n + n(p m + n(k N + j)n nj + n(j nj + n n + +.group r + r r + +.group l + l l + +.group y + y j diff --git a/dictsource/quc_list b/dictsource/quc_list index 8e5f29a6..4aa982c2 100644 --- a/dictsource/quc_list +++ b/dictsource/quc_list @@ -1,11 +1,11 @@ -// numbers -_1 jun -_2 keb' -_3 oxib' -_4 kajib' -_5 job' -_6 waqib' -_7 wuqub' -_8 wajxaqib' -_9 b'elejeb' -_10 lajuj +// Native numbers 1-10 +_1n jun +_2n keb' +_3n oxib' +_4n kajib' +_5n job' +_6n waqib' +_7n wuqub' +_8n wajxaqib' +_9n b'elejeb' +_10n lajuj diff --git a/espeak-ng-data/lang/art/qdb b/espeak-ng-data/lang/art/qdb index c4fff975..eb5ea363 100644 --- a/espeak-ng-data/lang/art/qdb +++ b/espeak-ng-data/lang/art/qdb @@ -1,4 +1,4 @@ -name Lang_Belta +name Lang Belta language qdb numbers 4 3 diff --git a/espeak-ng-data/lang/miz/mto b/espeak-ng-data/lang/miz/mto new file mode 100644 index 00000000..eb0f75ff --- /dev/null +++ b/espeak-ng-data/lang/miz/mto @@ -0,0 +1,8 @@ +name Totontepec Mixe +language mto + +maintainer Bill Dengler and Elizabeth Resendiz +status testing + +lowercaseSentence +tunes s6 c6 q6 e6 diff --git a/phsource/ph_mixe_mto b/phsource/ph_mixe_mto new file mode 100644 index 00000000..f7c8c490 --- /dev/null +++ b/phsource/ph_mixe_mto @@ -0,0 +1,216 @@ + +//==================================================== +// Totontepec Mixe +//==================================================== + + +phoneme a + ipa a + vwl starttype #a endtype #a + length 190 + FMT(vowel/a_4) +endphoneme + +phoneme A + ipa ɑ + vwl starttype #a endtype #a + length 220 + unr bck low + FMT(vowel/aa_8) +endphoneme + +phoneme e + ipa e + vwl starttype #e endtype #e + length 190 + FMT(vowel/e_mid2) +endphoneme + +phoneme @ + ipa ə + vwl starttype #@ endtype #@ + unstressed + length 140 + unr cnt mid + IF thisPh(isWordEnd) THEN + FMT(vowel/@_6, 90) + ENDIF + FMT(vowel/@) +endphoneme + +phoneme i + ipa i + vwl starttype #i endtype #i + length 190 + IfNextVowelAppend(;) + FMT(vowel/i) +endphoneme + +phoneme 8 + ipa ɘ + vwl starttype #@ endtype #@ + length 165 + FMT(vowel/8_7) +endphoneme + +phoneme o + ipa o + vwl starttype #o endtype #o + length 195 + FMT(vowel/oo) +endphoneme + +phoneme oU + ipa əʊ + vwl starttype #@ endtype #u + length 220 + FMT(vdiph/@u_en) +endphoneme + +phoneme u + vwl starttype #u endtype #u + length 200 + FMT(vowel/u_bck2) +endphoneme + +phoneme k + import_phoneme consonants/k- +endphoneme + +phoneme k# + import_phoneme consonants/k# +endphoneme + +phoneme g + ipa g + vcd vel stp + lengthmod 5 + voicingswitch k + Vowelin f1=2 f2=2300 200 300 f3=-300 80 + Vowelout f1=2 f2=2300 250 300 f3=-300 80 brk + + FMT(g/g) addWav(x/g2) // weaker [g] +endphoneme + +phoneme t + import_phoneme base1/t[ +endphoneme + +phoneme T // Used in Spanish words + import_phoneme base1/T +endphoneme + +phoneme t# + ipa tʰ + vls dnt stp + lengthmod 2 + voicingswitch d + Vowelin f1=0 f2=1500 -300 300 f3=-100 80 amp=16 + Vowelout f1=0 f2=1500 -300 250 f3=-100 80 rms=20 + IF nextPh(isPause2) THEN + WAV(ustop/t_dnt, 35) + ENDIF + WAV(ustop/t_dnt, 50) +endphoneme + +phoneme d + import_phoneme base2/d +endphoneme + +phoneme p + import_phoneme consonants/p- +endphoneme + +phoneme p# + import_phoneme consonants/ph +endphoneme + +phoneme b + import_phoneme base1/b +endphoneme + +phoneme v + ipa v + vcd lbd frc + FMT(voc/v) addWav(vocw/v, 90) +endphoneme + +phoneme f + ipa f + vls lbd frc + WAV(ufric/f, 80) +endphoneme + +phoneme s + ipa s + vls alv frc sib + lengthmod 3 + voicingswitch z + Vowelin f1=0 f2=1700 -300 300 f3=-100 80 + Vowelout f1=0 f2=1700 -300 250 f3=-100 80 rms=20 + + IF nextPh(isPause) THEN + WAV(ufric/s_, 60) // quieter 's' at end of word + ELIF nextPh(p) OR nextPh(t) OR nextPh(k) THEN + WAV(ufric/s!) + ENDIF + WAV(ufric/s, 80) +endphoneme + +phoneme s. + import_phoneme base1/s. +endphoneme + +phoneme z. + import_phoneme base1/z. +endphoneme + +phoneme ts + import_phoneme consonants/ts +endphoneme + +phoneme dz + import_phoneme consonants/dz +endphoneme + +phoneme m + import_phoneme base1/m- +endphoneme + +phoneme n + import_phoneme base1/n- +endphoneme + +phoneme N + import_phoneme base1/N- +endphoneme + +phoneme r + import_phoneme base1/* +endphoneme + +phoneme l + import_phoneme base1/l +endphoneme + +phoneme j + import_phoneme base1/j +endphoneme + +phoneme C + import_phoneme base1/C +endphoneme + +phoneme ? + ipa ʔ + vls glt stp + lengthmod 1 // 5? longer preceding vowel + nolink + Vowelin glstop + Vowelout glstop + WAV(ustop/null) +endphoneme + +phoneme h + import_phoneme base1/h +endphoneme diff --git a/phsource/ph_romanian b/phsource/ph_romanian index e3598f8e..697005f0 100644 --- a/phsource/ph_romanian +++ b/phsource/ph_romanian @@ -150,7 +150,8 @@ endphoneme phoneme r liquid trl - lengthmod 7 + lengthmod 6 + IF nextPh(isNotVowel) THEN ChangePhoneme(r/) ENDIF @@ -172,6 +173,9 @@ phoneme r FMT(r/trr) ENDIF FMT(r/rr) + Vowelin f1=0 f2=1600 -300 300 f3=-200 80 + Vowelout f1=2 f2=1600 -300 300 f3=-200 80 brk + FMT(r3/r_trill2) addWav(r3/r_trill2.wav, 65) endphoneme diff --git a/phsource/phonemes b/phsource/phonemes index 66b17c26..4a13d66e 100644 --- a/phsource/phonemes +++ b/phsource/phonemes @@ -1852,6 +1852,9 @@ include ph_kurdish phonemetable mi base2 include ph_maori +phonemetable mto base2 +include ph_mixe_mto + phonemetable nci base2 include ph_nahuatl @@ -2058,3 +2061,5 @@ include ph_langbelta phonemetable be ru include ph_belarusian + +phonemetable ms id diff --git a/src/espeak-ng.c b/src/espeak-ng.c index 1634cc1d..0891a24f 100644 --- a/src/espeak-ng.c +++ b/src/espeak-ng.c @@ -143,7 +143,7 @@ static void DisplayVoices(FILE *f_out, char *language) const espeak_VOICE **voices; espeak_VOICE voice_select; - static char genders[4] = { '-', 'M', 'F', '-' }; + static const char genders[4] = { '-', 'M', 'F', '-' }; if ((language != NULL) && (language[0] != 0)) { // display only voices for the specified language, in order of priority @@ -201,7 +201,7 @@ static void Write4Bytes(FILE *f, int value) static int OpenWavFile(char *path, int rate) { - static unsigned char wave_hdr[44] = { + static const unsigned char wave_hdr[44] = { 'R', 'I', 'F', 'F', 0x24, 0xf0, 0xff, 0x7f, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', 0x10, 0, 0, 0, 1, 0, 1, 0, 9, 0x3d, 0, 0, 0x12, 0x7a, 0, 0, 2, 0, 0x10, 0, 'd', 'a', 't', 'a', 0x00, 0xf0, 0xff, 0x7f @@ -304,7 +304,7 @@ static void PrintVersion() int main(int argc, char **argv) { - static struct option long_options[] = { + static const struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "stdin", no_argument, 0, 0x100 }, { "compile-debug", optional_argument, 0, 0x101 }, diff --git a/src/libespeak-ng/compiledata.c b/src/libespeak-ng/compiledata.c index 319d23b8..772f10e1 100644 --- a/src/libespeak-ng/compiledata.c +++ b/src/libespeak-ng/compiledata.c @@ -1559,7 +1559,7 @@ static void CompileSound(int keyword, int isvowel) int addr = 0; int value = 0; char path[N_ITEM_STRING]; - static int sound_instns[] = { i_FMT, i_WAV, i_VWLSTART, i_VWLENDING, i_WAVADD }; + static const int sound_instns[] = { i_FMT, i_WAV, i_VWLSTART, i_VWLENDING, i_WAVADD }; NextItemBrackets(tSTRING, 2); strcpy(path, item_string); diff --git a/src/libespeak-ng/compiledict.c b/src/libespeak-ng/compiledict.c index 26ece6fe..cfe31c69 100644 --- a/src/libespeak-ng/compiledict.c +++ b/src/libespeak-ng/compiledict.c @@ -223,14 +223,16 @@ char *DecodeRule(const char *group_chars, int group_length, char *rule, int cont char suffix[20]; static char output[80]; - static char symbols[] = { + MAKE_MEM_UNDEFINED(&output, sizeof(output)); + + static const char symbols[] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '&', '%', '+', '#', 'S', 'D', 'Z', 'A', 'L', '!', ' ', '@', '?', 'J', 'N', 'K', 'V', '?', 'T', 'X', '?', 'W' }; - static char symbols_lg[] = { 'A', 'B', 'C', 'H', 'F', 'G', 'Y' }; + static const char symbols_lg[] = { 'A', 'B', 'C', 'H', 'F', 'G', 'Y' }; match_type = 0; buf_pre[0] = 0; @@ -766,8 +768,8 @@ static int isHexDigit(int c) static void copy_rule_string(char *string, int *state_out) { // state 0: conditional, 1=pre, 2=match, 3=post, 4=phonemes - static char *outbuf[5] = { rule_cond, rule_pre, rule_match, rule_post, rule_phonemes }; - static int next_state[5] = { 2, 2, 4, 4, 4 }; + static char * const outbuf[5] = { rule_cond, rule_pre, rule_match, rule_post, rule_phonemes }; + static const int next_state[5] = { 2, 2, 4, 4, 4 }; char *output; char *p; int ix; diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c index a98caf54..4cd87ded 100644 --- a/src/libespeak-ng/dictionary.c +++ b/src/libespeak-ng/dictionary.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -1060,7 +1061,7 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, char vowel_length[N_WORD_PHONEMES/2]; unsigned char phonetic[N_WORD_PHONEMES]; - static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; + static const char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; stressflags = tr->langopts.stress_flags; @@ -1226,9 +1227,9 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags, // LANG=Russian if (stressed_syllable == 0) { // no explicit stress - guess the stress from the number of syllables - static char guess_ru[16] = { 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11 }; - static char guess_ru_v[16] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10 }; // for final phoneme is a vowel - static char guess_ru_t[16] = { 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 10 }; // for final phoneme is an unvoiced stop + static const char guess_ru[16] = { 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11 }; + static const char guess_ru_v[16] = { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 10 }; // for final phoneme is a vowel + static const char guess_ru_t[16] = { 0, 0, 1, 2, 3, 3, 3, 4, 5, 6, 7, 7, 7, 8, 9, 10 }; // for final phoneme is an unvoiced stop stressed_syllable = vowel_count - 3; if (vowel_count < 16) { @@ -2228,7 +2229,7 @@ int TranslateRules(Translator *tr, char *p_start, char *phonemes, int ph_size, c int dict_flags0 = 0; MatchRecord match1; MatchRecord match2; - char ph_buf[40]; + char ph_buf[N_PHONEME_BYTES]; char word_copy[N_WORD_BYTES]; static const char str_pause[2] = { phonPAUSE_NOLINK, 0 }; @@ -2660,8 +2661,9 @@ static const char *LookupDict2(Translator *tr, const char *word, const char *wor phonetic[0] = 0; phoneme_len = 0; } else { - strcpy(phonetic, p); phoneme_len = strlen(p); + assert(phoneme_len < N_PHONEME_BYTES); + strcpy(phonetic, p); p += (phoneme_len + 1); } @@ -2875,6 +2877,8 @@ int LookupDictList(Translator *tr, char **wordptr, char *ph_out, unsigned int *f char word[N_WORD_BYTES]; static char word_replacement[N_WORD_BYTES]; + MAKE_MEM_UNDEFINED(&word_replacement, sizeof(word_replacement)); + length = 0; word2 = word1 = *wordptr; @@ -3008,12 +3012,14 @@ int Lookup(Translator *tr, const char *word, char *ph_out) if (flags[0] & FLAG_TEXTMODE) { say_as = option_sayas; option_sayas = 0; // don't speak replacement word as letter names - // NOTE: TranslateRoman checks text[-2], so pad the start of text to prevent + // NOTE: TranslateRoman checks text[-2] and IsLetterGroup looks + // for a heading \0, so pad the start of text to prevent // it reading data on the stack. - text[0] = ' '; + text[0] = 0; text[1] = ' '; - strncpy0(text+2, word1, sizeof(text)-2); - flags0 = TranslateWord(tr, text+2, NULL, NULL); + text[2] = ' '; + strncpy0(text+3, word1, sizeof(text)-3); + flags0 = TranslateWord(tr, text+3, NULL, NULL); strcpy(ph_out, word_phonemes); option_sayas = say_as; } @@ -3052,11 +3058,11 @@ int RemoveEnding(Translator *tr, char *word, int end_type, char *word_copy) char ending[50] = {0}; // these lists are language specific, but are only relevant if the 'e' suffix flag is used - static const char *add_e_exceptions[] = { + static const char * const add_e_exceptions[] = { "ion", NULL }; - static const char *add_e_additions[] = { + static const char * const add_e_additions[] = { "c", "rs", "ir", "ur", "ath", "ns", "u", "spong", // sponge "rang", // strange diff --git a/src/libespeak-ng/intonation.c b/src/libespeak-ng/intonation.c index 4c9d54d9..d5e9092d 100644 --- a/src/libespeak-ng/intonation.c +++ b/src/libespeak-ng/intonation.c @@ -539,10 +539,10 @@ static int calc_pitch_segment(SYLLABLE *syllable_tab, int ix, int end_ix, TONE_H int pitch_range; int pitch_range_abs; int *drops; - signed char *overflow_tab; + const signed char *overflow_tab; SYLLABLE *syl; - static signed char continue_tab[5] = { -26, 32, 20, 8, 0 }; + static const signed char continue_tab[5] = { -26, 32, 20, 8, 0 }; drops = th->body_drops; pitch_range = (th->body_end - th->body_start) * 256; diff --git a/src/libespeak-ng/klatt.c b/src/libespeak-ng/klatt.c index b4f41059..29bf9d05 100644 --- a/src/libespeak-ng/klatt.c +++ b/src/libespeak-ng/klatt.c @@ -483,7 +483,7 @@ void KlattFini(void) static void frame_init(klatt_frame_ptr frame) { double amp_par[7]; - static double amp_par_factor[7] = { 0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03 }; + static const double amp_par_factor[7] = { 0.6, 0.4, 0.15, 0.06, 0.04, 0.022, 0.03 }; long Gain0_tmp; int ix; @@ -552,7 +552,7 @@ static void frame_init(klatt_frame_ptr frame) static double impulsive_source() { - static double doublet[] = { 0.0, 13000000.0, -13000000.0 }; + static const double doublet[] = { 0.0, 13000000.0, -13000000.0 }; static double vwave; if (kt_globals.nper < 3) @@ -623,7 +623,7 @@ static void pitch_synch_par_reset(klatt_frame_ptr frame) long temp; double temp1; static long skew; - static short B0[224] = { + static const short B0[224] = { 1200, 1142, 1088, 1038, 991, 948, 907, 869, 833, 799, 768, 738, 710, 683, 658, 634, 612, 590, 570, 551, 533, 515, 499, 483, 468, 454, 440, 427, 415, 403, 391, 380, 370, 360, 350, 341, 332, 323, 315, 307, 300, 292, 285, 278, 272, @@ -836,7 +836,7 @@ static double gen_noise(double noise) static double DBtoLIN(long dB) { - static short amptable[88] = { + static const short amptable[88] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 32, 35, 40, 45, 51, 57, 64, 71, 80, 90, 101, 114, 128, @@ -1076,10 +1076,10 @@ static void SetSynth_Klatt(int length, frame_t *fr1, frame_t *fr2, voice_t *wvoi void KlattInit() { - static short formant_hz[10] = { 280, 688, 1064, 2806, 3260, 3700, 6500, 7000, 8000, 280 }; - static short bandwidth[10] = { 89, 160, 70, 160, 200, 200, 500, 500, 500, 89 }; - static short parallel_amp[10] = { 0, 59, 59, 59, 59, 59, 59, 0, 0, 0 }; - static short parallel_bw[10] = { 59, 59, 89, 149, 200, 200, 500, 0, 0, 0 }; + static const short formant_hz[10] = { 280, 688, 1064, 2806, 3260, 3700, 6500, 7000, 8000, 280 }; + static const short bandwidth[10] = { 89, 160, 70, 160, 200, 200, 500, 500, 500, 89 }; + static const short parallel_amp[10] = { 0, 59, 59, 59, 59, 59, 59, 0, 0, 0 }; + static const short parallel_bw[10] = { 59, 59, 89, 149, 200, 200, 500, 0, 0, 0 }; int ix; diff --git a/src/libespeak-ng/numbers.c b/src/libespeak-ng/numbers.c index 4c46768e..04f95913 100644 --- a/src/libespeak-ng/numbers.c +++ b/src/libespeak-ng/numbers.c @@ -479,7 +479,7 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b // control, bit 0: not the first letter of a word int len; - static char single_letter[10] = { 0, 0 }; + char single_letter[10] = { 0, 0 }; unsigned int dict_flags[2]; char ph_buf3[40]; @@ -500,8 +500,8 @@ void LookupLetter(Translator *tr, unsigned int letter, int next_byte, char *ph_b if (tr->translator_name == L('e', 'n')) return; // we are already using English - SetTranslator2(ESPEAKNG_DEFAULT_VOICE); - if (Lookup(translator2, &single_letter[2], ph_buf3) != 0) { + SetTranslator3(ESPEAKNG_DEFAULT_VOICE); + if (Lookup(translator3, &single_letter[2], ph_buf3) != 0) { // yes, switch to English and re-translate the word sprintf(ph_buf1, "%c", phonSWITCH); } @@ -691,7 +691,7 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP char ph_buf2[80]; char ph_alphabet[80]; char hexbuf[12]; - static char pause_string[] = { phonPAUSE, 0 }; + static const char pause_string[] = { phonPAUSE, 0 }; ph_buf[0] = 0; ph_alphabet[0] = 0; @@ -719,8 +719,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP // don't say "superscript" during normal text reading Lookup(tr, modifier, capital); if (capital[0] == 0) { - capital[2] = SetTranslator2(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator2 - Lookup(translator2, modifier, &capital[3]); + capital[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 + Lookup(translator3, modifier, &capital[3]); if (capital[3] != 0) { capital[0] = phonPAUSE; capital[1] = phonSWITCH; @@ -763,8 +763,8 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP ph_buf2[0] = 0; if (Lookup(translator, alphabet->name, ph_alphabet) == 0) { // the original language for the current voice // Can't find the local name for this alphabet, use the English name - ph_alphabet[2] = SetTranslator2(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator2 - Lookup(translator2, alphabet->name, ph_buf2); + ph_alphabet[2] = SetTranslator3(ESPEAKNG_DEFAULT_VOICE); // overwrites previous contents of translator3 + Lookup(translator3, alphabet->name, ph_buf2); } else if (translator != tr) { phontab_1 = tr->phoneme_tab_ix; strcpy(ph_buf2, ph_alphabet); @@ -801,9 +801,9 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP char hangul_buf[12]; // speak in the language for this alphabet (or English) - ph_buf[2] = SetTranslator2(WordToString2(language)); + ph_buf[2] = SetTranslator3(WordToString2(language)); - if (translator2 != NULL) { + if (translator3 != NULL) { if (((code = letter - 0xac00) >= 0) && (letter <= 0xd7af)) { // Special case for Korean letters. // break a syllable hangul into 2 or 3 individual jamo @@ -818,15 +818,15 @@ int TranslateLetter(Translator *tr, char *word, char *phonemes, int control, ALP p3[6] = ' '; p3[7] = 0; ph_buf[3] = 0; - TranslateRules(translator2, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); - SetWordStress(translator2, &ph_buf[3], NULL, -1, 0); + TranslateRules(translator3, &hangul_buf[1], &ph_buf[3], sizeof(ph_buf)-3, NULL, 0, NULL); + SetWordStress(translator3, &ph_buf[3], NULL, -1, 0); } else - LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1); + LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); if (ph_buf[3] == phonSWITCH) { // another level of language change - ph_buf[2] = SetTranslator2(&ph_buf[4]); - LookupLetter(translator2, letter, word[n_bytes], &ph_buf[3], control & 1); + ph_buf[2] = SetTranslator3(&ph_buf[4]); + LookupLetter(translator3, letter, word[n_bytes], &ph_buf[3], control & 1); } SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table @@ -1039,7 +1039,7 @@ int TranslateRoman(Translator *tr, char *word, char *ph_out, WORD_TAB *wtab) char number_chars[N_WORD_BYTES]; static const char *roman_numbers = "ixcmvld"; - static int roman_values[] = { 1, 10, 100, 1000, 5, 50, 500 }; + static const int roman_values[] = { 1, 10, 100, 1000, 5, 50, 500 }; acc = 0; prev = 0; diff --git a/src/libespeak-ng/phonemelist.c b/src/libespeak-ng/phonemelist.c index 2860bf3a..3628c4ca 100644 --- a/src/libespeak-ng/phonemelist.c +++ b/src/libespeak-ng/phonemelist.c @@ -291,6 +291,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) } } + SelectPhonemeTable(tr->phoneme_tab_ix); n_ph_list3 = SubstitutePhonemes(ph_list3) - 2; for (j = 0; (j < n_ph_list3) && (ix < N_PHONEME_LIST-3);) { @@ -321,6 +322,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) ph_list3[0].ph = ph; word_start = 1; + SelectPhonemeTable(tr->phoneme_tab_ix); for (j = 0; insert_ph || ((j < n_ph_list3) && (ix < N_PHONEME_LIST-3)); j++) { plist3 = &ph_list3[j]; @@ -461,7 +463,7 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) } if ((plist3+1)->synthflags & SFLAG_LENGTHEN) { - static char types_double[] = { phFRICATIVE, phVFRICATIVE, phNASAL, phLIQUID, 0 }; + static const char types_double[] = { phFRICATIVE, phVFRICATIVE, phNASAL, phLIQUID, 0 }; if ((j > 0) && (strchr(types_double, next->type))) { // lengthen this consonant by doubling it // BUT, can't insert a phoneme at position plist3[0] because it crashes PrevPh() @@ -589,4 +591,6 @@ void MakePhonemeList(Translator *tr, int post_pause, bool start_sentence) phlist[ix++].ph = phoneme_tab[phonPAUSE_SHORT]; n_phoneme_list = ix; + + SelectPhonemeTable(tr->phoneme_tab_ix); } diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c index e8dbc57d..c126f4f4 100644 --- a/src/libespeak-ng/readclause.c +++ b/src/libespeak-ng/readclause.c @@ -187,6 +187,8 @@ const char *WordToString2(unsigned int word) static char buf[5]; char *p; + MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); + p = buf; for (ix = 3; ix >= 0; ix--) { if ((*p = word >> (ix*8)) != 0) @@ -227,6 +229,8 @@ static const char *LookupCharName(Translator *tr, int c, int only) char *string; static char buf[60]; + MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); + buf[0] = 0; flags[0] = 0; flags[1] = 0; @@ -335,7 +339,7 @@ static int AnnouncePunctuation(Translator *tr, int c1, int *c2_ptr, char *output if ((*bufix == 0) || (end_clause == 0) || (tr->langopts.param[LOPT_ANNOUNCE_PUNCT] & 2)) { punct_count = 1; - while ((c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags + while (!Eof() && (c2 == c1) && (c1 != '<')) { // don't eat extra '<', it can miss XML tags punct_count++; c2 = GetC(); } @@ -541,8 +545,10 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ c1 = c2; if (ungot_string_ix >= 0) { - if (ungot_string[ungot_string_ix] == 0) + if (ungot_string[ungot_string_ix] == 0) { + MAKE_MEM_UNDEFINED(&ungot_string, sizeof(ungot_string)); ungot_string_ix = -1; + } } if ((ungot_string_ix == 0) && (ungot_char2 == 0)) @@ -647,7 +653,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ // an embedded command. If it's a voice change, end the clause if (c2 == 'V') { buf[ix++] = 0; // end the clause at this point - while (!iswspace(c1 = GetC()) && !Eof() && (ix < (n_buf-1))) + while (!Eof() && !iswspace(c1 = GetC()) && (ix < (n_buf-1))) buf[ix++] = c1; // add voice name to end of buffer, after the text buf[ix++] = 0; return CLAUSE_VOICE; @@ -657,7 +663,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ strcpy(&buf[ix], " "); ix += 3; - if ((c2 = GetC()) == '0') + if (!Eof() && (c2 = GetC()) == '0') option_punctuation = 0; else { option_punctuation = 1; @@ -665,7 +671,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ if (c2 != '1') { // a list of punctuation characters to be spoken, terminated by space j = 0; - while (!iswspace(c2) && !Eof()) { + while (!Eof() && !iswspace(c2)) { option_punctlist[j++] = c2; c2 = GetC(); buf[ix++] = ' '; @@ -674,7 +680,8 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ option_punctuation = 2; } } - c2 = GetC(); + if (!Eof()) + c2 = GetC(); continue; } } @@ -791,7 +798,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ } if ((c1 == '.') && (c2 == '.')) { - while ((c_next = GetC()) == '.') { + while (!Eof() && (c_next = GetC()) == '.') { // 3 or more dots, replace by elipsis c1 = 0x2026; c2 = ' '; @@ -808,7 +815,7 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ // Handling of sequences of ? and ! like ??!?, !!??!, ?!! etc // Use only first char as determinant if(punct_data & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { - while(clause_type_from_codepoint(c2) & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { + while(!Eof() && clause_type_from_codepoint(c2) & (CLAUSE_QUESTION | CLAUSE_EXCLAMATION)) { c_next = GetC(); c2 = c_next; } diff --git a/src/libespeak-ng/speech.h b/src/libespeak-ng/speech.h index 5e2433b5..bf37aa96 100644 --- a/src/libespeak-ng/speech.h +++ b/src/libespeak-ng/speech.h @@ -35,7 +35,7 @@ # include # define MAKE_MEM_UNDEFINED(addr, len) VALGRIND_MAKE_MEM_UNDEFINED(addr, len) # else -# define MAKE_MEM_UNDEFINED(addr, len) ((void) (addr, len)) +# define MAKE_MEM_UNDEFINED(addr, len) ((void) ((void) addr, len)) # endif #endif diff --git a/src/libespeak-ng/ssml.c b/src/libespeak-ng/ssml.c index 3696f87a..c6c2bd15 100644 --- a/src/libespeak-ng/ssml.c +++ b/src/libespeak-ng/ssml.c @@ -47,6 +47,7 @@ #include "synthesize.h" // for SPEED_FACTORS, speed #include "translate.h" // for CTRL_EMBEDDED, IsDigit09, utf8_out #include "voice.h" // for SelectVoice, SelectVoiceByName +#include "speech.h" // for MAKE_MEM_UNDEFINED static const MNEM_TAB ssmltags[] = { { "speak", SSML_SPEAK }, @@ -214,6 +215,8 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe char language[40]; char buf[80]; + MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name)); + strcpy(voice_name, ssml_stack[0].voice_name); strcpy(language, ssml_stack[0].language); voice_select.age = ssml_stack[0].voice_age; @@ -275,13 +278,13 @@ static const char *VoiceFromStack(SSML_STACK *ssml_stack, int n_ssml_stack, espe } -static wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name) +static const wchar_t *GetSsmlAttribute(wchar_t *pw, const char *name) { // Gets the value string for an attribute. // Returns NULL if the attribute is not present int ix; - static wchar_t empty[1] = { 0 }; + static const wchar_t empty[1] = { 0 }; while (*pw != 0) { if (iswspace(pw[-1])) { @@ -315,11 +318,11 @@ static int GetVoiceAttributes(wchar_t *pw, int tag_type, SSML_STACK *ssml_sp, SS // a voice change. // Returns CLAUSE_TYPE_VOICE_CHANGE if there is a voice change - wchar_t *lang; - wchar_t *gender; - wchar_t *name; - wchar_t *age; - wchar_t *variant; + const wchar_t *lang; + const wchar_t *gender; + const wchar_t *name; + const wchar_t *age; + const wchar_t *variant; int value; const char *new_voice_id; @@ -384,7 +387,7 @@ static void ProcessParamStack(char *outbuf, int *outix, int n_param_stack, PARAM int value; char buf[20]; int new_parameters[N_SPEECH_PARAM]; - static char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters + static const char cmd_letter[N_SPEECH_PARAM] = { 0, 'S', 'A', 'P', 'R', 0, 'C', 0, 0, 0, 0, 0, 'F' }; // embedded command letters for (param = 0; param < N_SPEECH_PARAM; param++) new_parameters[param] = -1; @@ -482,7 +485,7 @@ static int ReplaceKeyName(char *outbuf, int index, int *outix) return 0; } -static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters) +static void SetProsodyParameter(int param_type, const wchar_t *attr1, PARAM_STACK *sp, PARAM_STACK *param_stack, int *speech_parameters) { int value; int sign; @@ -528,7 +531,7 @@ static void SetProsodyParameter(int param_type, wchar_t *attr1, PARAM_STACK *sp, { NULL, -1 } }; - static const MNEM_TAB *mnem_tabs[5] = { + static const MNEM_TAB * const mnem_tabs[5] = { NULL, mnem_rate, mnem_volume, mnem_pitch, mnem_range }; @@ -564,9 +567,9 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con int value3; int voice_change_flag; wchar_t *px; - wchar_t *attr1; - wchar_t *attr2; - wchar_t *attr3; + const wchar_t *attr1; + const wchar_t *attr2; + const wchar_t *attr3; int terminator; char *uri; int param_type; @@ -581,7 +584,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con } // these tags have no effect if they are self-closing, eg. - static char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; + static const char ignore_if_self_closing[] = { 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 }; bool self_closing = false; int len; @@ -645,7 +648,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con { NULL, -1 } }; - static const char *prosody_attr[5] = { + static const char * const prosody_attr[5] = { NULL, "rate", "volume", "pitch", "range" }; @@ -711,13 +714,13 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con value = attrlookup(attr1, mnem_emphasis); if (translator->langopts.tone_language == 1) { - static unsigned char emphasis_to_pitch_range[] = { 50, 50, 40, 70, 90, 100 }; - static unsigned char emphasis_to_volume[] = { 100, 100, 70, 110, 135, 150 }; + static const unsigned char emphasis_to_pitch_range[] = { 50, 50, 40, 70, 90, 100 }; + static const unsigned char emphasis_to_volume[] = { 100, 100, 70, 110, 135, 150 }; // tone language (eg.Chinese) do emphasis by increasing the pitch range. sp->parameter[espeakRANGE] = emphasis_to_pitch_range[value]; sp->parameter[espeakVOLUME] = emphasis_to_volume[value]; } else { - static unsigned char emphasis_to_volume2[] = { 100, 100, 75, 100, 120, 150 }; + static const unsigned char emphasis_to_volume2[] = { 100, 100, 75, 100, 120, 150 }; sp->parameter[espeakVOLUME] = emphasis_to_volume2[value]; sp->parameter[espeakEMPHASIS] = value; } @@ -855,7 +858,7 @@ int ProcessSsmlTag(wchar_t *xml_buf, char *outbuf, int *outix, int n_outbuf, con terminator = CLAUSE_NONE; if ((attr1 = GetSsmlAttribute(px, "strength")) != NULL) { - static int break_value[6] = { 0, 7, 14, 21, 40, 80 }; // *10mS + static const int break_value[6] = { 0, 7, 14, 21, 40, 80 }; // *10mS value = attrlookup(attr1, mnem_break); if (value < 3) { // adjust prepause on the following word diff --git a/src/libespeak-ng/synth_mbrola.c b/src/libespeak-ng/synth_mbrola.c index 151f38ea..68e1f5e2 100644 --- a/src/libespeak-ng/synth_mbrola.c +++ b/src/libespeak-ng/synth_mbrola.c @@ -253,6 +253,8 @@ static char *WritePitch(int env, int pitch1, int pitch2, int split, int final) char buf[50]; static char output[50]; + MAKE_MEM_UNDEFINED(&output, sizeof(output)); + output[0] = 0; pitch_env = envelope_data[env]; diff --git a/src/libespeak-ng/synthdata.c b/src/libespeak-ng/synthdata.c index 128073a4..272fec74 100644 --- a/src/libespeak-ng/synthdata.c +++ b/src/libespeak-ng/synthdata.c @@ -208,6 +208,8 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, int which, FMT_PARAMS *fmt_params, frame_t *frame; static frameref_t frames_buf[N_SEQ_FRAMES]; + MAKE_MEM_UNDEFINED(&frames_buf, sizeof(frames_buf)); + seq = (SPECT_SEQ *)(&phondata_ptr[fmt_params->fmt_addr]); seqk = (SPECT_SEQK *)seq; nf = seq->n_frames; @@ -428,7 +430,7 @@ static bool StressCondition(Translator *tr, PHONEME_LIST *plist, int condition, { int stress_level; PHONEME_LIST *pl; - static int condition_level[4] = { 1, 2, 4, 15 }; + static const int condition_level[4] = { 1, 2, 4, 15 }; if (phoneme_tab[plist[0].phcode]->type == phVOWEL) pl = plist; diff --git a/src/libespeak-ng/synthesize.c b/src/libespeak-ng/synthesize.c index 561de991..5414871c 100644 --- a/src/libespeak-ng/synthesize.c +++ b/src/libespeak-ng/synthesize.c @@ -43,6 +43,7 @@ #include "translate.h" // for translator, LANGUAGE_OPTIONS, Trans... #include "voice.h" // for voice_t, voice, LoadVoiceVariant #include "wavegen.h" // for WcmdqInc, WcmdqFree, WcmdqStop +#include "speech.h" // for MAKE_MEM_UNDEFINED static void SmoothSpect(void); @@ -77,6 +78,8 @@ const char *WordToString(unsigned int word) int ix; static char buf[5]; + MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); + for (ix = 0; ix < 4; ix++) buf[ix] = word >> (ix*8); buf[4] = 0; @@ -388,6 +391,8 @@ static frame_t *AllocFrame() ix++; if (ix >= N_FRAME_POOL) ix = 0; + + MAKE_MEM_UNDEFINED(&frame_pool[ix], sizeof(frame_pool[ix])); return &frame_pool[ix]; } @@ -553,7 +558,7 @@ int FormantTransition2(frameref_t *seq, int *n_frames, unsigned int data1, unsig #define N_VCOLOUR 2 // percentage change for each formant in 256ths - static short vcolouring[N_VCOLOUR][5] = { + static const short vcolouring[N_VCOLOUR][5] = { { 243, 272, 256, 256, 256 }, // palatal consonant follows { 256, 256, 240, 240, 240 }, // retroflex }; diff --git a/src/libespeak-ng/tr_languages.c b/src/libespeak-ng/tr_languages.c index 78d28952..d02d6c5a 100644 --- a/src/libespeak-ng/tr_languages.c +++ b/src/libespeak-ng/tr_languages.c @@ -1210,7 +1210,7 @@ Translator *SelectTranslator(const char *name) break; case L('m', 'k'): // Macedonian { - static wchar_t vowels_cyrillic[] = { + static const wchar_t vowels_cyrillic[] = { // also include 'р' [R] 0x440, 0x430, 0x435, 0x438, 0x439, 0x43e, 0x443, 0x44b, 0x44d, 0x44e, 0x44f, 0x450, 0x451, 0x456, 0x457, 0x45d, 0x45e, 0 @@ -1558,7 +1558,7 @@ Translator *SelectTranslator(const char *name) { static const short stress_lengths_vi[8] = { 150, 150, 180, 180, 210, 230, 230, 240 }; static const unsigned char stress_amps_vi[] = { 16, 16, 16, 16, 22, 22, 22, 22 }; - static wchar_t vowels_vi[] = { + static const wchar_t vowels_vi[] = { 0x61, 0xe0, 0xe1, 0x1ea3, 0xe3, 0x1ea1, // a 0x103, 0x1eb1, 0x1eaf, 0x1eb3, 0x1eb5, 0x1eb7, // ă 0xe2, 0x1ea7, 0x1ea5, 0x1ea9, 0x1eab, 0x1ead, // â diff --git a/src/libespeak-ng/translate.c b/src/libespeak-ng/translate.c index 0db80fd4..19f95051 100644 --- a/src/libespeak-ng/translate.c +++ b/src/libespeak-ng/translate.c @@ -47,6 +47,8 @@ Translator *translator = NULL; // the main translator Translator *translator2 = NULL; // secondary translator for certain words static char translator2_language[20] = { 0 }; +Translator *translator3 = NULL; // tertiary translator for certain words +static char translator3_language[20] = { 0 }; FILE *f_trans = NULL; // phoneme output text int option_tone_flags = 0; // bit 8=emphasize allcaps, bit 9=emphasize penultimate stress @@ -342,7 +344,7 @@ int utf8_out(unsigned int c, char *buf) int n_bytes; int j; int shift; - static char unsigned code[4] = { 0, 0xc0, 0xe0, 0xf0 }; + static const char unsigned code[4] = { 0, 0xc0, 0xe0, 0xf0 }; if (c < 0x80) { buf[0] = c; @@ -1206,35 +1208,45 @@ static void Word_EmbeddedCmd() } while (((embedded_cmd & 0x80) == 0) && (embedded_read < embedded_ix)); } -int SetTranslator2(const char *new_language) +static int SetAlternateTranslator(const char *new_language, Translator **translator, char translator_language[20]) { - // Set translator2 to a second language + // Set alternate translator to a second language int new_phoneme_tab; if ((new_phoneme_tab = SelectPhonemeTableName(new_language)) >= 0) { - if ((translator2 != NULL) && (strcmp(new_language, translator2_language) != 0)) { + if ((*translator != NULL) && (strcmp(new_language, translator_language) != 0)) { // we already have an alternative translator, but not for the required language, delete it - DeleteTranslator(translator2); - translator2 = NULL; + DeleteTranslator(*translator); + *translator = NULL; } - if (translator2 == NULL) { - translator2 = SelectTranslator(new_language); - strcpy(translator2_language, new_language); + if (*translator == NULL) { + *translator = SelectTranslator(new_language); + strcpy(translator_language, new_language); - if (LoadDictionary(translator2, translator2->dictionary_name, 0) != 0) { + if (LoadDictionary(*translator, (*translator)->dictionary_name, 0) != 0) { SelectPhonemeTable(voice->phoneme_tab_ix); // revert to original phoneme table new_phoneme_tab = -1; - translator2_language[0] = 0; + translator_language[0] = 0; } - translator2->phoneme_tab_ix = new_phoneme_tab; + (*translator)->phoneme_tab_ix = new_phoneme_tab; } } - if (translator2 != NULL) - translator2->phonemes_repeat[0] = 0; + if (*translator != NULL) + (*translator)->phonemes_repeat[0] = 0; return new_phoneme_tab; } +int SetTranslator2(const char *new_language) +{ + return SetAlternateTranslator(new_language, &translator2, translator2_language); +} + +int SetTranslator3(const char *new_language) +{ + return SetAlternateTranslator(new_language, &translator3, translator3_language); +} + static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pause) { int flags = 0; @@ -1574,6 +1586,7 @@ static int TranslateWord2(Translator *tr, char *word, WORD_TAB *wtab, int pre_pa if (ph_code == phonSWITCH) { ph_list2[n_ph_list2].phcode = ph_code; + ph_list2[n_ph_list2].stresslevel = 0; ph_list2[n_ph_list2].sourceix = 0; ph_list2[n_ph_list2].synthflags = 0; ph_list2[n_ph_list2++].tone_ph = *p; @@ -1988,6 +2001,8 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change) if (tr == NULL) return; + MAKE_MEM_UNDEFINED(&voice_change_name, sizeof(voice_change_name)); + embedded_ix = 0; embedded_read = 0; pre_pause = 0; diff --git a/src/libespeak-ng/translate.h b/src/libespeak-ng/translate.h index 7af96608..dfa5e118 100644 --- a/src/libespeak-ng/translate.h +++ b/src/libespeak-ng/translate.h @@ -39,6 +39,7 @@ extern "C" #define N_WORD_PHONEMES 200 // max phonemes in a word #define N_WORD_BYTES 160 // max bytes for the UTF8 characters in a word +#define N_PHONEME_BYTES 160 // max bytes for a phoneme #define N_CLAUSE_WORDS 300 // max words in a clause #define N_TR_SOURCE 800 // the source text of a single clause (UTF8 bytes) @@ -649,6 +650,7 @@ extern wchar_t option_punctlist[N_PUNCTLIST]; // which punctuation characters t extern Translator *translator; extern Translator *translator2; +extern Translator *translator3; extern char dictionary_name[40]; extern espeak_ng_TEXT_DECODER *p_decoder; extern int dictionary_skipwords; @@ -679,6 +681,7 @@ ALPHABET *AlphabetFromChar(int c); Translator *SelectTranslator(const char *name); int SetTranslator2(const char *name); +int SetTranslator3(const char *name); void DeleteTranslator(Translator *tr); void ProcessLanguageOptions(LANGUAGE_OPTIONS *langopts); diff --git a/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c index a7603d47..c96e326c 100644 --- a/src/libespeak-ng/voices.c +++ b/src/libespeak-ng/voices.c @@ -356,10 +356,10 @@ void VoiceReset(int tone_only) // Set voice to the default values int pk; - static unsigned char default_heights[N_PEAKS] = { 130, 128, 120, 116, 100, 100, 128, 128, 128 }; // changed for v.1.47 - static unsigned char default_widths[N_PEAKS] = { 140, 128, 128, 160, 171, 171, 128, 128, 128 }; + static const unsigned char default_heights[N_PEAKS] = { 130, 128, 120, 116, 100, 100, 128, 128, 128 }; // changed for v.1.47 + static const unsigned char default_widths[N_PEAKS] = { 140, 128, 128, 160, 171, 171, 128, 128, 128 }; - static int breath_widths[N_PEAKS] = { 0, 200, 200, 400, 400, 400, 600, 600, 600 }; + static const int breath_widths[N_PEAKS] = { 0, 200, 200, 400, 400, 400, 600, 600, 600 }; // default is: pitch 80,118 voice->pitch_base = 0x47000; @@ -554,6 +554,12 @@ voice_t *LoadVoice(const char *vname, int control) static char voice_name[40]; // voice name for current_voice_selected static char voice_languages[100]; // list of languages and priorities for current_voice_selected + if (!tone_only) { + MAKE_MEM_UNDEFINED(&voice_identifier, sizeof(voice_identifier)); + MAKE_MEM_UNDEFINED(&voice_name, sizeof(voice_name)); + MAKE_MEM_UNDEFINED(&voice_languages, sizeof(voice_languages)); + } + strncpy0(voicename, vname, sizeof(voicename)); if (control & 0x10) { strcpy(buf, vname); @@ -959,6 +965,9 @@ voice_t *LoadVoice(const char *vname, int control) return NULL; // no dictionary loaded } } + + /* Terminate languages list with a zero-priority entry */ + voice_languages[langix] = 0; } return voice; @@ -973,6 +982,7 @@ static char *ExtractVoiceVariantName(char *vname, int variant_num, int add_dir) static char variant_name[40]; char variant_prefix[5]; + MAKE_MEM_UNDEFINED(&variant_name, sizeof(variant_name)); variant_name[0] = 0; sprintf(variant_prefix, "!v%c", PATHSEP); if (add_dir == 0) @@ -1310,6 +1320,9 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found) static espeak_VOICE voice_variants[N_VOICE_VARIANTS]; static char voice_id[50]; + MAKE_MEM_UNDEFINED(&voice_variants, sizeof(voice_variants)); + MAKE_MEM_UNDEFINED(&voice_id, sizeof(voice_id)); + *found = 1; memcpy(&voice_select2, voice_select, sizeof(voice_select2)); @@ -1320,6 +1333,8 @@ char const *SelectVoice(espeak_VOICE *voice_select, int *found) // no language is specified. Get language from the named voice static char buf[60]; + MAKE_MEM_UNDEFINED(&buf, sizeof(buf)); + if (voice_select2.name == NULL) { if ((voice_select2.name = voice_select2.identifier) == NULL) voice_select2.name = ESPEAKNG_DEFAULT_VOICE; @@ -1510,7 +1525,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByFile(const char *filename) int ix; espeak_VOICE voice_selector; char *variant_name; - static char buf[60]; + char buf[60]; strncpy0(buf, filename, sizeof(buf)); @@ -1547,7 +1562,7 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_SetVoiceByName(const char *name) int ix; espeak_VOICE voice_selector; char *variant_name; - static char buf[60]; + char buf[60]; strncpy0(buf, name, sizeof(buf)); diff --git a/src/libespeak-ng/wavegen.c b/src/libespeak-ng/wavegen.c index 9441f201..271aa90c 100644 --- a/src/libespeak-ng/wavegen.c +++ b/src/libespeak-ng/wavegen.c @@ -1172,8 +1172,8 @@ static void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t * int length4; int qix; int cmd; - static int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256 - static int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256 + static const int glottal_reduce_tab1[4] = { 0x30, 0x30, 0x40, 0x50 }; // vowel before [?], amp * 1/256 + static const int glottal_reduce_tab2[4] = { 0x90, 0xa0, 0xb0, 0xc0 }; // vowel after [?], amp * 1/256 end_wave = 1; diff --git a/tests/fuzzing/README.md b/tests/fuzzing/README.md new file mode 100644 index 00000000..122bd688 --- /dev/null +++ b/tests/fuzzing/README.md @@ -0,0 +1,61 @@ +All fuzzers here are run continously through OSS-fuzz. + +Link to OSS-fuzz integration: Pending + +# Translation fuzzers + +Currently, there is a fuzzer related to synthetizer, **synth_fuzzer** that will target **espak_Synth**. The following sections will explain how to configure the fuzzers, how to use them and how to get a coverage report of the fuzzing result. + +## Configure the project for fuzzing + +We have added some switchs to configure.ac for fuzzing and coverage. The `--with-fuzzer` switch will check if your are actually using clang and clang++ as compilers (by looking at CC and CXX) and allows generation of compilation instructions for fuzzer targets. The `--with-coverage` will add `-fprofile-instr-generate -fcoverage-mapping` to AM_CPPFLAGS in espeak/Makefile.am. + +To configure and build the project with coverage and fuzzer. +```./autogen.sh +CC=clang CXX=clang++ ./configure --with-coverage --with-fuzzer +make -j8 +``` + +## Run the fuzzers + +You are now able to run the fuzzer and will have to give 2 parameters to it. First, you need to choose a language to fuzz and set the `FUZZ_VOICE` environment variable to them. Then, you need to provide a corpus with files containing sample inputs that will be used by libfuzzer to craft the data passed to the fuzzing function (the idea is to keep corpus as minimal as possible). If you don't provide any corpus directory, libfuzzer just generates random inputs. + +Here is how you can start fuzzing `espeak_Synth` function. +``` + +# first we move to tests/fuzzing directory +cd tests/fuzzing +#to have interesting file in the corpus , there is a simple python script that allows you to do that +./create_dict_corpus_file.py -c CORPUS/ + +# we consider here you have added corpus files into tests/fuzzing/CORPUS directory +FUZZ_VOICE=en ./synth_fuzzer CORPUS/ + +# to run the fuzzer using parallelization +# you can even set more jobs than workers (the ones that just stopped will be instantly replaced by a new fuzzer process) +FUZZ_VOICE=en ./synth_fuzzer CORPUS/ -workers=8 -jobs=8 +``` +After running the fuzzer multiple times with the same corpus directory, it might be possible that many corpus files added by the fuzzer explores the same paths. Hopefully, libfuzzer allows you to minimize a corpus. There is a simple bash script in tests/fuzzing that allows you to do that. +``` +./minimize-corpus.sh CORPUS/ + + +# if you have added a POC file in the corpus directory and you want to keep it intact, change his extension to .txt and use --preserve-txt switch that keep .txt files intact in the directory +./minimize-corpus.sh --preserve-txt CORPUS/ +``` +## Look at fuzzer coverage + +If you want to see what are the source code parts that are explored by the fuzzer, you can use clang coverage. So, you have to configure with coverage switch, run the fuzzer and show coverage data from the run with llvm tools. +To be able to use the coverage data, you need first to compile the raw profile data file of the run. By default, this file is created after execution under the name of default.profraw but you can specify it with `LLVM_PROFILE_FILE`. +Here is how to do that. +``` +LLVM_PROFILE_FILE=synth_fuzzer.profraw FUZZ_VOICE=en ./synth_fuzzer CORPUS/ -workers=8 -jobs=8 + +# wait for a bit and press CTRL+C + +# compile raw profile +llvm-profdata merge -sparse synth_fuzzer.profraw -o synth_fuzzer.profdata + +# show coverage (redlines are the one wich are reached) +llvm-cov show ./synth_fuzzer -instr-profile=synth_fuzzer.profdata +``` diff --git a/tests/fuzzing/create_dict_corpus_file.py b/tests/fuzzing/create_dict_corpus_file.py new file mode 100755 index 00000000..a27c1f39 --- /dev/null +++ b/tests/fuzzing/create_dict_corpus_file.py @@ -0,0 +1,68 @@ +#!/bin/python3 +# /* +# * Copyright (C) 2022 Anna Stan , Mamaodou Dramé Kalilou , Nicolas Morel +# * +# * 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, see: . +# */ +import sys +import mmap +import argparse +import shutil +import os +from os import O_RDONLY, O_RDWR, O_WRONLY, O_TRUNC, O_CREAT, SEEK_END, SEEK_CUR, SEEK_SET + +def main(argc, argv): + if argc < 2: + print('Summary: add file to the corpus ', file=sys.stderr) + print(f'Usage: {argv[0]} -c ', file=sys.stderr) + exit(1) + + ap = argparse.ArgumentParser() + + # Add the arguments to the parser + ap.add_argument("-c", "--corpus_dir", required=True, + help="corpus directory where to add the file") + args = vars(ap.parse_args()) + + + lang_list=os.getenv("FUZZ_VOICE") + if(lang_list): + list=lang_list+"_list" + else: + list="en_list" + output_name = list+"_dict_corpus.txt" + output_path=args['corpus_dir']+output_name + output= open(output_path, "w") + + path="../../dictsource/"+list + + + file = open( path, "r") + lines=file.readlines() + index=1 + for line in lines: + if line[0]=='/' and line[1]=='/': + continue + res = line.split() + if len(res): + output.write("kw") + output.write(str(index)) + index=index+1 + output.write("=") + output.write(res[0]) + output.write('\n') + file.close() + output.close() +if __name__ == "__main__": + main(len(sys.argv), sys.argv) diff --git a/tests/fuzzing/minimize-corpus.sh b/tests/fuzzing/minimize-corpus.sh new file mode 100755 index 00000000..82e21826 --- /dev/null +++ b/tests/fuzzing/minimize-corpus.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +if [[ $# -lt 1 ]] +then + echo "Usage: $0 " + echo "Usage: $0 --preserve-txt (minimize corpus but keep .txt files intact)" + exit 1 +fi + +preserve_txt=0 +if [[ "$1" == "--preserve-txt" ]] +then + preserve_txt=1 + CORPUS_DIR=$2 +else + CORPUS_DIR=$1 +fi + + +export FUZZ_VOICE=en +FUZZER=./synth_fuzzer + +TMP_DIR=$(mktemp -d) +echo "Merging..." +`$FUZZER -merge=1 $TMP_DIR $CORPUS_DIR` +echo "Removing old files..." +if [[ $preserve_txt -eq 1 ]] +then + echo " => Preserve .txt files" + rm -rvf $(find $CORPUS_DIR | grep -vE "*.txt|$CORPUS_DIR") 2>/dev/null +else + rm -rf $CORPUS_DIR/* 2>/dev/null +fi +cp $TMP_DIR/* $CORPUS_DIR 2>/dev/null +rm -rf $TMP_DIR +echo "Merging done !" diff --git a/tests/fuzzing/synth_fuzzer.c b/tests/fuzzing/synth_fuzzer.c new file mode 100644 index 00000000..ca3dddac --- /dev/null +++ b/tests/fuzzing/synth_fuzzer.c @@ -0,0 +1,80 @@ +/* + * 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 +#include +#include + +#include +#define BOLDRED(x) "\x1b[31m\x1b[1m" x "\x1b[0m" + +static int initialized = 0; + +static int +espeak_callback(short *data, int samples, espeak_EVENT *events) +{ + (void)data; + (void)samples; + (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) + +{ + int buflength = size+1; + if (!initialized) + { + int options = espeakINITIALIZE_DONT_EXIT; + espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS, buflength, PATH_ESPEAK_DATA, options); + espeak_SetSynthCallback(espeak_callback); + const char *lang = getenv("FUZZ_VOICE"); + if (lang == NULL) + { + fprintf(stderr, "\n" BOLDRED("[Please set up FUZZ_VOICE env var before starting fuzzer]") "\n\n"); + exit(1); + } + if (espeak_SetVoiceByName(lang) != EE_OK) + { + fprintf(stderr, "\n" BOLDRED("[Please supply a valid voice in FUZZ_VOICE]") "\n\n"); + exit(1); + } + initialized = 1; + fprintf(stderr, "VOICE FUZZED = %s\n", lang); + } + char *mutable_data = strndup((char *)data, size); + if (!mutable_data) + { + perror("malloc"); + exit(1); + } + unsigned int position = 0, position_type = POS_CHARACTER, end_position = 0 , synth_flags = espeakCHARS_AUTO; + espeak_Synth(mutable_data, buflength, position, position_type, end_position, + synth_flags, NULL, NULL); + free(mutable_data); + + return 0; +} diff --git a/tests/language-phonemes.test b/tests/language-phonemes.test index 36e0eff7..0fe7e13b 100755 --- a/tests/language-phonemes.test +++ b/tests/language-phonemes.test @@ -97,6 +97,7 @@ test_phwav mk 072d0a74acf54bea528e7dde427eb04808d38364 "ma na n^a Na pa ta xa k^ test_phwav mr 5238ba08fba349fea6c00bdd8f1672ede229b8ec "ma na n.a n^a pa t#a t.a tSa ka qa p#a t.#a c#a k#a ba d#a d.a dZa ga b#a d.#a J#a g#a fa sa Sa xa va za Za Qa Ha ra r.a la ja _:_ mI mU me m@ mo mE mV mO ma mi: mu: me: mo: mE: mO: ma: m&: mI~ mi~ mU~ mu~ mU~ me~ mo~ mE~ mV~ mO~ ma~ mAI maU" test_phwav ms 75a57a020af2b62e3448792d3f6a945a9b2c6b75 "ma na n^a Na pa ba ta da ka ga ?a tSa dZa fa va Ta Da sa za Sa xa Qa ha ja wa la Ra R2a _:_ ma mE mO m@ me mo mi mu maI meI mOI maU m@U" test_phwav mt 03231022bb750335042309d6d2acd55f214a8967 "ma na Na pa ta ka ?a ba da ga p\`a t\`a k\`a tSa dZa tS\`a Ba sa za Sa Za xa ha la ja wa ra _:_ mi me my ma m@ mo mu" +test_phwav mto bd45ab06741222328c2068f5a14a08b052dbdaa6 "a A e @ i 8 o oU u k k# ga t T t# da p p# b v f s s. z. ts dz m n N ra la j C a?e ha" test_phwav my 77eeafb213bfd0756319b2766be8364a2bff46ad "na Na la ja pa pha fa ta tha ka kha tS;a tS;ha S;a s.a tsa tsha ts.a ts.ha N-a _:_ ma mA mai mAu m@ m@r mE mei mi mi[ mi. miA miAu miE mio miou mo mo- mou mong mu muA mua muai mu@ mei muo my myu my& myE my@ myi _:_ ma11 ma21 ma214 ma22 ma33 ma35 ma44 ma51 ma53 ma55" test_phwav nb adbf0b2e74a76ff7bd2463223f648d479515a314 "m#a ma n#a na n^#a n^a N#a Na pa ta ca ka fa va Ta Da sa Ca J^a xa Qa ha l#a la tl#a r#a ra _:_ mi mi: mI mI: mE mE: ma ma: mO mO: mu mu: my my: mW mW: maI maI: meI meI: maU maU: moU moU: mYy mOI myI" test_phwav nci 8c578e588c4f0a283359d62754fde039b14c8aef "ma na Na pa ta ka ba da ga fa Ta sa Sa xa ha va Da za Za tSa dZa la ra ja wa t2a t#a d#a z#a r-a z/2a w#a m- n- N- _:_ mI mE ma m0 mV mU mi: mA: mO: mu: m3: mA@ mO@ mo@ mU@ mi@3 mIR mVR mi@ me@ mi m@ m3 me# mI# mI2 meI maI mOI moU maU maa mO2 maI@ maI3 maU@" diff --git a/tests/non-executable-files-with-executable-bit.test b/tests/non-executable-files-with-executable-bit.test index d1edfc99..d88cab00 100755 --- a/tests/non-executable-files-with-executable-bit.test +++ b/tests/non-executable-files-with-executable-bit.test @@ -4,10 +4,12 @@ echo -n "testing files for executable bits that shouldn't be executable ... " find * -executable -type f | \ grep -vE "compile|config\.(guess|status|sub)|configure|depcomp|install-sh|libtool|missing" | # Ignore autotools output \ - grep -vE "*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ - grep -vE "*.\.sh|tools/emoji" | # Ignore helper scripts \ + grep -vE ".*\.test|tests/common|src(/\.libs)?/(e?speak-ng|.*\.so\..*)|src/\.libs/lt-espeak-ng|android" | # Ignore built programs and libraries \ + grep -vE ".*\.sh|tools/emoji" | # Ignore helper scripts \ grep -vE "src/ucd-tools/tools/(.*\.py|mkencodingtable)" | # Ignore ucd-tools helper scripts \ grep -vE "tests/.libs|src/ucd-tools/tests/print(ucd|c)data(_cpp)?" | # Ignore ucd-tools test programs \ + grep -vE "tests/fuzzing/.*\.py" | #Ignore fuzzing python helper script + grep -vE "tests/fuzzing/.*\.sh" | #Ignore fuzzing python helper script tee tests/non-executable-files-with-executable-bit.check > /dev/null if [ -s tests/non-executable-files-with-executable-bit.check ] ; then