espeak-ng/espeak-ng-1.51-CVE-2023-49990-4.patch

250 lines
9.2 KiB
Diff
Raw Normal View History

diff --git a/tests/crash.test b/tests/crash.test
new file mode 100755
index 0000000000..184faf6eb8
--- /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
diff --git a/tests/crash_vectors/cve-2023-49990.txt b/tests/crash_vectors/cve-2023-49990.txt
new file mode 100644
index 0000000000..6708ca8895
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49990.txt
@@ -0,0 +1 @@
+<2B><><EFBFBD><EFBFBD>V<><56><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>V <0A><>V<><07><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>eeeeeeeeseee<65><65><EFBFBD><EFBFBD><EFBFBD>
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49991.txt b/tests/crash_vectors/cve-2023-49991.txt
new file mode 100644
index 0000000000..118f5b6131
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49991.txt
@@ -0,0 +1 @@
+<2B><>V<> <EFBFBD><EFBFBD>V<><56>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD>VD<56>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><10><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECBBBB>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><08><>ֻ<EFBFBD><D6BB><EFBFBD>ժ<EFBFBD><D5AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`v
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49992.txt b/tests/crash_vectors/cve-2023-49992.txt
new file mode 100644
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49992.txt
@@ -0,0 +1 @@
+<2B><><EFBFBD><EFBFBD><EFBFBD><03>!<21><><EFBFBD><EFBFBD><EFBFBD>bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbIbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb<62> !<00><18><><EFBFBD>
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49993.txt b/tests/crash_vectors/cve-2023-49993.txt
new file mode 100644
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49993.txt
@@ -0,0 +1,5 @@
+hV
+$
+V
+$
+B:\\lA:\@\<5C>\<5C>\H<>\\<5C>???T??%?\<5C>\<5C>\\<5C>\000000000000000000000000000000000000000000000000000000000@000000000000000000000000000000??0$? <09>#???<14> ?-0?<0F>000000L00<30>??<3F>?\H<>\\<5C>???T?? ?\<5C>\<5C>\\<5C>\<>\u\D:\@\000L00<30>?<3F>\<5C>\H<>\\<5C>???T??%?\<5C>\<5C>\\<5C>\0000000000000000200000000000000000000000000000000000000000000000000000000??0$? ? <09>????<14> ?-0?-<2D>00000L00<30>???000E+0%!!?
\ No newline at end of file
diff --git a/tests/crash_vectors/cve-2023-49994.txt b/tests/crash_vectors/cve-2023-49994.txt
new file mode 100644
index 0000000000..72c0813d49
--- /dev/null
+++ b/tests/crash_vectors/cve-2023-49994.txt
@@ -0,0 +1 @@
+"[[-#,- -1-2. r--<2D>#--O)C--!<21>E-1<>@5-!-V-1--
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index 0f4ba7a..354518f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -289,7 +289,8 @@ check: tests/encoding.check \
tests/windows-installer.check \
tests/bom.check \
tests/voices.check \
- tests/cmd_options.check
+ tests/cmd_options.check \
+ tests/crash.check
##### fuzzer:
diff --git a/src/libespeak-ng/dictionary.c b/src/libespeak-ng/dictionary.c
index a98caf5..43f9f6f 100644
--- a/src/libespeak-ng/dictionary.c
+++ b/src/libespeak-ng/dictionary.c
@@ -1062,6 +1062,9 @@ void SetWordStress(Translator *tr, char *output, unsigned int *dictionary_flags,
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 *word, int end_type, char *word_copy)
*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);
diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c
index de6cea5..5af40eb 100644
--- a/src/libespeak-ng/readclause.c
+++ b/src/libespeak-ng/readclause.c
@@ -665,7 +665,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) && (j < N_PUNCTLIST-1)) {
option_punctlist[j++] = c2;
c2 = GetC();
buf[ix++] = ' ';
diff --git a/src/libespeak-ng/synthdata.c b/src/libespeak-ng/synthdata.c
index 3870edf..e990912 100644
--- a/src/libespeak-ng/synthdata.c
+++ b/src/libespeak-ng/synthdata.c
@@ -75,8 +75,15 @@ static espeak_ng_STATUS ReadPhFile(void **ptr, const char *fname, int *size, esp
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 **ptr, const char *fname, int *size, esp
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, espeak_ng_ERROR_CONTEXT *context)
// 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)
diff --git a/src/libespeak-ng/translate.c b/src/libespeak-ng/translate.c
index 0914619..9cf9503 100644
--- a/src/libespeak-ng/translate.c
+++ b/src/libespeak-ng/translate.c
@@ -2630,6 +2630,7 @@ void TranslateClause(Translator *tr, int *tone_out, char **voice_change)
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/src/libespeak-ng/voices.c b/src/libespeak-ng/voices.c
index add6b94..c8dd5aa 100644
--- a/src/libespeak-ng/voices.c
+++ b/src/libespeak-ng/voices.c
@@ -557,6 +557,10 @@ 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 ((vname == NULL || vname[0] == 0) && !(control & 8)) {
+ return NULL;
+ }
+
strncpy0(voicename, vname, sizeof(voicename));
if (control & 0x10) {
strcpy(buf, vname);
@@ -940,14 +944,14 @@ voice_t *LoadVoice(const char *vname, int control)
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;
}
diff --git a/src/libespeak-ng/wavegen.c b/src/libespeak-ng/wavegen.c
index 17d65f7..9d3b1ee 100644
--- 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) {