diff --git a/CVE-2023-49990~CVE-2023-49994.patch b/CVE-2023-49990~CVE-2023-49994.patch new file mode 100644 index 0000000000000000000000000000000000000000..bddbe6f12f5578b4a611184591096be02bcf7b71 --- /dev/null +++ b/CVE-2023-49990~CVE-2023-49994.patch @@ -0,0 +1,328 @@ +Origin: https://sources.debian.org/data/main/e/espeak-ng/1.51%2Bdfsg-12/debian/patches/CVE + +commit 58f1e0b6a4e6aa55621c6f01118994d01fd6f68c +Merge: f983e445 e7bcd3cc +Author: Alexander Epaneshnikov +Date: Sun Dec 17 15:29:30 2023 +0300 + + tests: fix CVE crashes (#1846) + + Fixes: #1823, #1824, #1825, #1826, #1827 + + - Add crash test and vectors provided by @SEU-SSL + - Disallow dummy/null voice load (that causes incorrect translator + initialization) + - Fix empty `phondata` file load (that causes unitialized memory access) + - Limit max word length for RemoveEnding (causes buffer overflow) + - Limit punctlist initialization from embedded commands (buffer + overflow) + - Fix unitialized pitch in wavegen (DBZ and indexing problems) + - Properly zeroize stack variables before use in TranslateClause and + SetWordStress + + TODO (in nextup PR): add & fix more vectors from fuzzer. + +commit 9decedb8c229e1a4219baceaab7a3d656e889e31 +Author: Samuel Thibault +Date: Thu Jun 30 00:50:18 2022 +0200 + + Fix missing checks for EOF + +commit c4c05820c4a47369d5a81e4a506fe7abb2fa7ed6 +Author: Yury Popov +Date: Sat Dec 16 19:24:51 2023 +0300 + + tests: add CVE crash vectors + +commit e79405772cecf47053116aeaad10e64606292b14 +Author: Yury Popov +Date: Sat Dec 16 23:55:03 2023 +0300 + + voices: disallow dummy voice when not compiling + +commit 7d4ad3c2ae063cb08bfd606021bc323dfbadaba9 +Author: Yury Popov +Date: Sat Dec 16 21:50:07 2023 +0300 + + synthdata: fix empty file load + +commit b99f332c576eb49839613a55cfd3e0e1b5487191 +Author: Yury Popov +Date: Sat Dec 16 22:45:15 2023 +0300 + + dictionary: limit word length + +commit 1a7ecfc2f202438b17e742368f910e6099ce02b7 +Author: Yury Popov +Date: Sat Dec 16 22:50:01 2023 +0300 + + readclause: limit embedded punctlist length + +commit a5eb246debb51ba328ef399350dfcd5d87782245 +Author: Yury Popov +Date: Sat Dec 16 23:03:16 2023 +0300 + + wavegen: fix unitialized pitch + +commit 5f7db763e2eff1d8174d2b65a4bbe4b2a85c8a0c +Author: Yury Popov +Date: Sat Dec 16 23:17:45 2023 +0300 + + translate: fix number_buf initialization + +commit e7bcd3cc1599ebb531bb62fc3007d3ce1dade167 +Author: Yury Popov +Date: Sat Dec 16 23:26:07 2023 +0300 + + dictionary: fix stack initialization + +--- + src/libespeak-ng/dictionary.c | 4 ++++ + src/libespeak-ng/readclause.c | 12 ++++++------ + src/libespeak-ng/synthdata.c | 18 ++++++++++++++---- + src/libespeak-ng/translate.c | 1 + + src/libespeak-ng/voices.c | 20 ++++++++++++-------- + src/libespeak-ng/wavegen.c | 9 ++++++--- + tests/crash.test | 17 +++++++++++++++++ + tests/crash_vectors/cve-2023-49990.txt | 1 + + tests/crash_vectors/cve-2023-49991.txt | 1 + + tests/crash_vectors/cve-2023-49994.txt | 1 + + 10 files changed, 63 insertions(+), 21 deletions(-) + +--- a/src/libespeak-ng/readclause.c ++++ b/src/libespeak-ng/readclause.c +@@ -335,7 +335,7 @@ static int AnnouncePunctuation(Translato + + 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(); + } +@@ -647,7 +647,7 @@ int ReadClause(Translator *tr, char *buf + // 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 +657,7 @@ int ReadClause(Translator *tr, char *buf + strcpy(&buf[ix], " "); + ix += 3; + +- if ((c2 = GetC()) == '0') ++ if (!Eof() && (c2 = GetC()) == '0') + option_punctuation = 0; + else { + option_punctuation = 1; +@@ -665,7 +665,7 @@ int ReadClause(Translator *tr, char *buf + if (c2 != '1') { + // a list of punctuation characters to be spoken, terminated by space + j = 0; +- while (!iswspace(c2) && !Eof()) { ++ while (!Eof() && !iswspace(c2) && (j < N_PUNCTLIST-1)) { + option_punctlist[j++] = c2; + c2 = GetC(); + buf[ix++] = ' '; +@@ -791,7 +791,7 @@ int ReadClause(Translator *tr, char *buf + } + + if ((c1 == '.') && (c2 == '.')) { +- while ((c_next = GetC()) == '.') { ++ while (!Eof() && (c_next = GetC()) == '.') { + // 3 or more dots, replace by elipsis + c1 = 0x2026; + c2 = ' '; +@@ -808,7 +808,7 @@ int ReadClause(Translator *tr, char *buf + // 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; + } +--- /dev/null ++++ b/tests/crash.test +@@ -0,0 +1,17 @@ ++#!/bin/sh ++# include common script ++. "`dirname $0`/common" ++ ++test_crash() { ++ TEST_NAME=$1 ++ ++ echo "testing CVE-${TEST_NAME}" ++ ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} \ ++ $VALGRIND src/espeak-ng -f "$(dirname $0)/crash_vectors/${TEST_NAME}.txt" -w /dev/null || exit 1 ++} ++ ++test_crash cve-2023-49990 ++test_crash cve-2023-49991 ++test_crash cve-2023-49992 ++test_crash cve-2023-49993 ++test_crash cve-2023-49994 +--- /dev/null ++++ b/tests/crash_vectors/cve-2023-49990.txt +@@ -0,0 +1 @@ ++ã¦à»Vñ€¦ñ €¦V €äVñ€ãÂà¦æsññâñþâññà¶æØØsññâñþâññeeeeeeeeseee€ññûñ +\ No newline at end of file +--- /dev/null ++++ b/tests/crash_vectors/cve-2023-49991.txt +@@ -0,0 +1 @@ ++€¦Vñ €ñVðÕhñùâÿñVDíZ»»ÕöÖÖÖÖÖÖÖÖÖì»»º»Ö¾ÖÖÖÖÖÖ´ÖÖÖ»þþ÷ÜÖÖÖ»»º»Õª»»®îÿÿ€ê`v +\ No newline at end of file +--- /dev/null ++++ b/tests/crash_vectors/cve-2023-49994.txt +@@ -0,0 +1 @@ ++"[[-#,- -1-2. r--ª#--O)C--!ÿE-1‹@5-!-V-1-- +\ No newline at end of file +--- a/src/libespeak-ng/voices.c ++++ b/src/libespeak-ng/voices.c +@@ -554,6 +554,10 @@ voice_t *LoadVoice(const char *vname, in + 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 ((vname == NULL || vname[0] == 0) && !(control & 8)) { ++ return NULL; ++ } ++ + strncpy0(voicename, vname, sizeof(voicename)); + if (control & 0x10) { + strcpy(buf, vname); +@@ -937,14 +941,14 @@ voice_t *LoadVoice(const char *vname, in + + if (!tone_only) { + if (!!(control & 8/*compiling phonemes*/)) { +- /* Set by espeak_ng_CompilePhonemeDataPath when it +- * calls LoadVoice("", 8) to set up a dummy(?) voice. +- * As phontab may not yet exist this avoids the spurious +- * error message and guarantees consistent results by +- * not actually reading a potentially bogus phontab... +- */ +- ix = 0; +- } else if ((ix = SelectPhonemeTableName(phonemes_name)) < 0) { ++ /* Set by espeak_ng_CompilePhonemeDataPath when it ++ * calls LoadVoice("", 8) to set up a dummy(?) voice. ++ * As phontab may not yet exist this avoids the spurious ++ * error message and guarantees consistent results by ++ * not actually reading a potentially bogus phontab... ++ */ ++ ix = 0; ++ } else if ((ix = SelectPhonemeTableName(phonemes_name)) < 0) { + fprintf(stderr, "Unknown phoneme table: '%s'\n", phonemes_name); + ix = 0; + } +--- a/src/libespeak-ng/synthdata.c ++++ b/src/libespeak-ng/synthdata.c +@@ -75,8 +75,15 @@ static espeak_ng_STATUS ReadPhFile(void + if ((f_in = fopen(buf, "rb")) == NULL) + return create_file_error_context(context, errno, buf); + +- if (*ptr != NULL) ++ if (*ptr != NULL) { + free(*ptr); ++ *ptr = NULL; ++ } ++ ++ if (length == 0) { ++ *ptr = NULL; ++ return 0; ++ } + + if ((*ptr = malloc(length)) == NULL) { + fclose(f_in); +@@ -86,6 +93,7 @@ static espeak_ng_STATUS ReadPhFile(void + int error = errno; + fclose(f_in); + free(*ptr); ++ *ptr = NULL; + return create_file_error_context(context, error, buf); + } + +@@ -119,9 +127,11 @@ espeak_ng_STATUS LoadPhData(int *srate, + // read the version number and sample rate from the first 8 bytes of phondata + version = 0; // bytes 0-3, version number + rate = 0; // bytes 4-7, sample rate +- for (ix = 0; ix < 4; ix++) { +- version += (wavefile_data[ix] << (ix*8)); +- rate += (wavefile_data[ix+4] << (ix*8)); ++ if (wavefile_data) { ++ for (ix = 0; ix < 4; ix++) { ++ version += (wavefile_data[ix] << (ix*8)); ++ rate += (wavefile_data[ix+4] << (ix*8)); ++ } + } + + if (version != version_phdata) +--- a/src/libespeak-ng/dictionary.c ++++ b/src/libespeak-ng/dictionary.c +@@ -1062,6 +1062,9 @@ void SetWordStress(Translator *tr, char + + static char consonant_types[16] = { 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; + ++ memset(syllable_weight, 0, sizeof(syllable_weight)); ++ memset(vowel_length, 0, sizeof(vowel_length)); ++ + stressflags = tr->langopts.stress_flags; + + if (dictionary_flags != NULL) +@@ -3070,6 +3073,7 @@ int RemoveEnding(Translator *tr, char *w + *word_end = 'e'; + } + i = word_end - word; ++ if (i >= N_WORD_BYTES) i = N_WORD_BYTES-1; + + if (word_copy != NULL) { + memcpy(word_copy, word, i); +--- a/src/libespeak-ng/wavegen.c ++++ b/src/libespeak-ng/wavegen.c +@@ -537,14 +537,14 @@ static void AdvanceParameters() + if (wvoice == NULL) + return; + +- int x; ++ int x = 0; + int ix; + static int Flutter_ix = 0; + + // advance the pitch + wdata.pitch_ix += wdata.pitch_inc; + if ((ix = wdata.pitch_ix>>8) > 127) ix = 127; +- x = wdata.pitch_env[ix] * wdata.pitch_range; ++ if (wdata.pitch_env) x = wdata.pitch_env[ix] * wdata.pitch_range; + wdata.pitch = (x>>8) + wdata.pitch_base; + + +@@ -560,7 +560,7 @@ static void AdvanceParameters() + + if(const_f0) + wdata.pitch = (const_f0<<12); +- ++ + if (wdata.pitch < 102400) + wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12) + +@@ -1268,6 +1268,9 @@ static int WavegenFill2() + static bool resume = false; + static int echo_complete = 0; + ++ if (wdata.pitch < 102400) ++ wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12) ++ + while (out_ptr < out_end) { + if (WcmdqUsed() <= 0) { + if (echo_complete > 0) { +--- a/src/libespeak-ng/translate.c ++++ b/src/libespeak-ng/translate.c +@@ -2630,6 +2630,7 @@ void TranslateClause(Translator *tr, int + if (dict_flags & FLAG_SPELLWORD) { + // redo the word, speaking single letters + for (pw = word; *pw != ' ';) { ++ memset(number_buf, 0, sizeof(number_buf)); + memset(number_buf, ' ', 9); + nx = utf8_in(&c_temp, pw); + memcpy(&number_buf[2], pw, nx); diff --git a/Compare-variant_name-with-vimonly-if-long-enough.patch b/Compare-variant_name-with-vimonly-if-long-enough.patch deleted file mode 100644 index 9e3e5b3c88955a9b42ba32865c5f764a88e8e36f..0000000000000000000000000000000000000000 --- a/Compare-variant_name-with-vimonly-if-long-enough.patch +++ /dev/null @@ -1,26 +0,0 @@ -From c9ca77a4d415b838810fb22f85c728d211433197 Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Wed, 21 Mar 2018 21:16:08 +0000 -Subject: [PATCH] Compare variant_name with "!v" only if long enough - -Various places call SetVoiceStack with "" for the variant_name. This -causes -fsanitize=address to fail with an overflow as the call to -memcmp is checking the first 2 bytes, and there is only 1 byte -available. ---- - src/libespeak-ng/readclause.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c -index 52362de44..26bc35b96 100644 ---- a/src/libespeak-ng/readclause.c -+++ b/src/libespeak-ng/readclause.c -@@ -599,7 +599,7 @@ void SetVoiceStack(espeak_VOICE *v, const char *variant_name) - sp->voice_age = v->age; - sp->voice_gender = v->gender; - -- if (memcmp(variant_name, "!v", 2) == 0) -+ if (strlen(variant_name) >= 2 && memcmp(variant_name, "!v", 2) == 0) - variant_name += 3; // strip variant directory name, !v plus PATHSEP - strncpy0(base_voice_variant_name, variant_name, sizeof(base_voice_variant_name)); - memcpy(&base_voice, ¤t_voice_selected, sizeof(base_voice)); diff --git a/Copy-name-in-LoadDictionary-if-not-dictionary_name.patch b/Copy-name-in-LoadDictionary-if-not-dictionary_name.patch deleted file mode 100644 index 4294a2bef1af4e9649be52a3324efbe1b8235f4d..0000000000000000000000000000000000000000 --- a/Copy-name-in-LoadDictionary-if-not-dictionary_name.patch +++ /dev/null @@ -1,30 +0,0 @@ -From b60d2452c34ac6ebf01a3c09c17193b8c8e2a3fd Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Wed, 21 Mar 2018 20:37:44 +0000 -Subject: [PATCH] Copy name in LoadDictionary if not dictionary_name - -compiledict.c sets dict_name to dictionary_name if dict_name is -not set, and passes that to LoadDictionary. LoadDictionary then -copies the passed in name to dictionary_name. - -This causes -fsanitize=address to fail with overlapping memory -addresses passed to strncpy (copying the string to itself). As -such, don't copy the name in this case. ---- - src/libespeak-ng/dictionary.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c -index f6bdf1823..5d1f44ba0 100644 ---- a/src/libespeak-ng/dictionary.c -+++ b/src/libespeak-ng/dictionary.c -@@ -201,7 +201,8 @@ int LoadDictionary(Translator *tr, const char *name, int no_error) - int size; - char fname[sizeof(path_home)+20]; - -- strncpy(dictionary_name, name, 40); // currently loaded dictionary name -+ if (dictionary_name != name) -+ strncpy(dictionary_name, name, 40); // currently loaded dictionary name - strncpy(tr->dictionary_name, name, 40); - - // Load a pronunciation data file into memory diff --git a/Fix-running-the-tests-with-fsanitize-address.patch b/Fix-running-the-tests-with-fsanitize-address.patch deleted file mode 100644 index fbd523dc4a6f4ec5c4c638f6e21855eedfbccf4d..0000000000000000000000000000000000000000 --- a/Fix-running-the-tests-with-fsanitize-address.patch +++ /dev/null @@ -1,184 +0,0 @@ -From da95f5d5c7275f6ea72110cf768939351424f18a Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Mon, 20 Aug 2018 18:48:51 +0100 -Subject: [PATCH 1/4] Update the Unicode Data Files license. - ---- - COPYING.UCD | 40 +++++++++++++++++++++++++++++----------- - 1 file changed, 29 insertions(+), 11 deletions(-) - -diff --git a/COPYING.UCD b/COPYING.UCD -index 51608df18..38ff09a13 100644 ---- a/COPYING.UCD -+++ b/COPYING.UCD -@@ -1,8 +1,29 @@ -+Unicode Data Files include all data files under the directories -+http://www.unicode.org/Public/, http://www.unicode.org/reports/, -+http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and -+http://www.unicode.org/utility/trac/browser/. -+ -+Unicode Data Files do not include PDF online code charts under the -+directory http://www.unicode.org/Public/. -+ -+Software includes any source code published in the Unicode Standard -+or under the directories -+http://www.unicode.org/Public/, http://www.unicode.org/reports/, -+http://www.unicode.org/cldr/data/, http://source.icu-project.org/repos/icu/, and -+http://www.unicode.org/utility/trac/browser/. -+ -+NOTICE TO USER: Carefully read the following legal agreement. -+BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S -+DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), -+YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE -+TERMS AND CONDITIONS OF THIS AGREEMENT. -+IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE -+THE DATA FILES OR SOFTWARE. -+ - COPYRIGHT AND PERMISSION NOTICE - --Copyright © 1991-2014 Unicode, Inc. All rights reserved. --Distributed under the Terms of Use in --http://www.unicode.org/copyright.html. -+Copyright © 1991-2018 Unicode, Inc. All rights reserved. -+Distributed under the Terms of Use in http://www.unicode.org/copyright.html. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of the Unicode data files and any associated documentation -@@ -11,14 +32,11 @@ a copy of the Unicode data files and any associated documentation - without restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, and/or sell copies of - the Data Files or Software, and to permit persons to whom the Data Files --or Software are furnished to do so, provided that --(a) this copyright and permission notice appear with all copies --of the Data Files or Software, --(b) this copyright and permission notice appear in associated --documentation, and --(c) there is clear notice in each modified Data File or in the Software --as well as in the documentation associated with the Data File(s) or --Software that the data or software has been modified. -+or Software are furnished to do so, provided that either -+(a) this copyright and permission notice appear with all copies -+of the Data Files or Software, or -+(b) this copyright and permission notice appear in associated -+Documentation. - - THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE - -From 1a895f37b9cb868234a2278a410a234259b08905 Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Tue, 4 May 2021 17:51:28 +0100 -Subject: [PATCH 2/4] Fix running the tests with -fsanitize=address. - ---- - src/case.c | 8 ++++---- - tools/case.py | 6 +++--- - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/src/ucd-tools/src/case.c b/src/ucd-tools/src/case.c -index 04c9736af..b11c869c5 100644 ---- a/src/ucd-tools/src/case.c -+++ b/src/ucd-tools/src/case.c -@@ -1,6 +1,6 @@ - /* Unicode Case Conversion - * -- * Copyright (C) 2012-2016 Reece H. Dunn -+ * Copyright (C) 2012-2018, 2021 Reece H. Dunn - * - * This file is part of ucd-tools. - * -@@ -2664,7 +2664,7 @@ static const struct case_conversion_entry case_conversion_data[] = - codepoint_t ucd_toupper(codepoint_t c) - { - int begin = 0; -- int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]); -+ int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]) - 1; - while (begin <= end) - { - int pos = (begin + end) / 2; -@@ -2682,7 +2682,7 @@ codepoint_t ucd_toupper(codepoint_t c) - codepoint_t ucd_tolower(codepoint_t c) - { - int begin = 0; -- int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]); -+ int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]) - 1; - while (begin <= end) - { - int pos = (begin + end) / 2; -@@ -2700,7 +2700,7 @@ codepoint_t ucd_tolower(codepoint_t c) - codepoint_t ucd_totitle(codepoint_t c) - { - int begin = 0; -- int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]); -+ int end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]) - 1; - while (begin <= end) - { - int pos = (begin + end) / 2; -diff --git a/src/ucd-tools/tools/case.py b/src/ucd-tools/tools/case.py -index 9daa57409..33cd54721 100755 ---- a/src/ucd-tools/tools/case.py -+++ b/src/ucd-tools/tools/case.py -@@ -1,6 +1,6 @@ - #!/usr/bin/python - --# Copyright (C) 2012-2016 Reece H. Dunn -+# Copyright (C) 2012-2018, 2021 Reece H. Dunn - # - # This file is part of ucd-tools. - # -@@ -33,7 +33,7 @@ - if __name__ == '__main__': - sys.stdout.write("""/* Unicode Case Conversion - * -- * Copyright (C) 2012-2016 Reece H. Dunn -+ * Copyright (C) 2012-2018, 2021 Reece H. Dunn - * - * This file is part of ucd-tools. - * -@@ -83,7 +83,7 @@ - sys.stdout.write('codepoint_t ucd_to%s(codepoint_t c)\n' % case) - sys.stdout.write('{\n') - sys.stdout.write('\tint begin = 0;\n') -- sys.stdout.write('\tint end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]);\n') -+ sys.stdout.write('\tint end = sizeof(case_conversion_data)/sizeof(case_conversion_data[0]) - 1;\n') - sys.stdout.write('\twhile (begin <= end)\n') - sys.stdout.write('\t{\n') - sys.stdout.write('\t\tint pos = (begin + end) / 2;\n') - -From 2b2eac1d8bede4956b1c2aa51d418a956583801e Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Tue, 4 May 2021 17:54:15 +0100 -Subject: [PATCH 3/4] Fix the note in case.py/case.c. - ---- - src/case.c | 2 +- - tools/case.py | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/ucd-tools/src/case.c b/src/ucd-tools/src/case.c -index b11c869c5..dd17dc4ff 100644 ---- a/src/ucd-tools/src/case.c -+++ b/src/ucd-tools/src/case.c -@@ -19,7 +19,7 @@ - */ - - /* NOTE: This file is automatically generated from the UnicodeData.txt file in -- * the Unicode Character database by the ucd-tools/tools/categories.py script. -+ * the Unicode Character database by the ucd-tools/tools/case.py script. - */ - - #include "ucd/ucd.h" -diff --git a/src/ucd-tools/tools/case.py b/src/ucd-tools/tools/case.py -index 33cd54721..b6d15efd0 100755 ---- a/src/ucd-tools/tools/case.py -+++ b/src/ucd-tools/tools/case.py -@@ -52,7 +52,7 @@ - */ - - /* NOTE: This file is automatically generated from the UnicodeData.txt file in -- * the Unicode Character database by the ucd-tools/tools/categories.py script. -+ * the Unicode Character database by the ucd-tools/tools/case.py script. - */ - - #include "ucd/ucd.h" - diff --git a/Simplify-the-vimcomparison-and-check-PATHSEP.patch b/Simplify-the-vimcomparison-and-check-PATHSEP.patch deleted file mode 100644 index eaba95e652df95a9b05f577a414d8957e3936404..0000000000000000000000000000000000000000 --- a/Simplify-the-vimcomparison-and-check-PATHSEP.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 444e4544d24632d5ba6ce90bb14c12d80fbb006e Mon Sep 17 00:00:00 2001 -From: "Reece H. Dunn" -Date: Wed, 21 Mar 2018 21:24:03 +0000 -Subject: [PATCH] Simplify the !v comparison and check PATHSEP - -SetVoiceStack looks for "!v" in variant_name and skips the first -three characters if "!v" is found. The problem here is that it -does not check that the third character is the path separator, so -may advance into unknown memory if variant_name is exactly "!v". - -This fixes that problem by checking for the path separator. It -also simplifies the logic by checking the bytes explicitly. - -NOTE: This is not strictly needed, as the only code paths this is -relevant for is in espeak_ng_SetVoiceByName, and the variant name -comes from ExtractVoiceVariantName, which sets up the variant name -correctly. ---- - src/libespeak-ng/readclause.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c -index 26bc35b96..aa884d59e 100644 ---- a/src/libespeak-ng/readclause.c -+++ b/src/libespeak-ng/readclause.c -@@ -599,7 +599,7 @@ void SetVoiceStack(espeak_VOICE *v, const char *variant_name) - sp->voice_age = v->age; - sp->voice_gender = v->gender; - -- if (strlen(variant_name) >= 2 && memcmp(variant_name, "!v", 2) == 0) -+ if (variant_name[0] == '!' && variant_name[1] == 'v' && variant_name[2] == PATHSEP) - variant_name += 3; // strip variant directory name, !v plus PATHSEP - strncpy0(base_voice_variant_name, variant_name, sizeof(base_voice_variant_name)); - memcpy(&base_voice, ¤t_voice_selected, sizeof(base_voice)); diff --git a/1.49.2.tar.gz b/espeak-ng-1.51.tar.gz similarity index 52% rename from 1.49.2.tar.gz rename to espeak-ng-1.51.tar.gz index ee64dcea630ba33aba2922f47346cbf22c0590a7..088b2a0561fe2452e63492a33aee1f7f67f29fbe 100644 Binary files a/1.49.2.tar.gz and b/espeak-ng-1.51.tar.gz differ diff --git a/espeak-ng.spec b/espeak-ng.spec index 811ed0f8a8e862f9bdb4f61dbe183def7f7433f9..6d761ae8d85a63c3be360b2f1e5e3a3a95d5994c 100644 --- a/espeak-ng.spec +++ b/espeak-ng.spec @@ -1,19 +1,16 @@ Name: espeak-ng -Version: 1.49.2 -Release: 6 +Version: 1.51 +Release: 2 Summary: eSpeak NG is an open source speech synthesizer -License: GPLv3+ +License: GPLv3+ and Apache-2.0 and BSD-2-Clause URL: https://github.com/espeak-ng/espeak-ng -Source0: https://github.com/espeak-ng/espeak-ng/archive/%{version}.tar.gz +Source0: https://github.com/espeak-ng/espeak-ng/archive/%{name}-%{version}.tar.gz +Patch0: CVE-2023-49990~CVE-2023-49994.patch BuildRequires: make autoconf automake libtool pkgconfig rubygem-ronn rubygem-kramdown pcaudiolib-devel +BuildRequires: gcc-c++ Provides: espeak-ng-vim = %{version}-%{release} Obsoletes: espeak-ng-vim < %{version}-%{release} -Patch0001: Fix-running-the-tests-with-fsanitize-address.patch -Patch0002: Copy-name-in-LoadDictionary-if-not-dictionary_name.patch -Patch0003: Compare-variant_name-with-vimonly-if-long-enough.patch -Patch0004: Simplify-the-vimcomparison-and-check-PATHSEP.patch - %description The eSpeak NG is a compact open source software text-to-speech synthesizer for Linux, Windows, Android and other operating systems. It supports 70 languages @@ -56,7 +53,7 @@ ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} src/espeak-ng ... /sbin/ldconfig %files -%doc COPYING COPYING.IEEE README.md CHANGELOG.md +%doc COPYING COPYING.APACHE COPYING.BSD2 README.md CHANGELOG.md %{_bindir}/{speak-ng,espeak-ng} %{_libdir}/libespeak-ng.so.* %{_datadir}/espeak-ng-data @@ -78,6 +75,12 @@ ESPEAK_DATA_PATH=`pwd` LD_LIBRARY_PATH=src:${LD_LIBRARY_PATH} src/espeak-ng ... %{_mandir}/man1/{speak-ng.1.gz,espeak-ng.1.gz} %changelog +* Thu Dec 28 2023 wangkai <13474090681@163.com> - 1.51-2 +- Fix CVE-2023-49990~CVE-2023-49994 + +* Thu Oct 19 2023 Ge Wang - 1.51-1 +- Update to version 1.51 + * Thu Jun 17 2021 lingsheng - 1.49.2-6 - Fix some errors in oss-fuzz build