From d8ec91e809e92bd8f45c5dee612546343b683b64 Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Sun, 2 May 2021 11:46:19 -0700 Subject: [PATCH 1/2] Fix buffer size calculation when initializing output. With the previous calculation, it was possible for the buffer to be a byte or two too small to hold all of the data. --- src/libespeak-ng/speech.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libespeak-ng/speech.c b/src/libespeak-ng/speech.c index c92c2cbf..13aca0fb 100644 --- a/src/libespeak-ng/speech.c +++ b/src/libespeak-ng/speech.c @@ -280,7 +280,9 @@ ESPEAK_NG_API espeak_ng_STATUS espeak_ng_InitializeOutput(espeak_ng_OUTPUT_MODE buffer_length = min_buffer_length; // allocate 2 bytes per sample - outbuf_size = (buffer_length * samplerate)/500; + // Always round up to the nearest sample and the nearest byte. + int millisamples = buffer_length * samplerate; + outbuf_size = (millisamples + 1000 - millisamples % 1000) / 500; out_start = (unsigned char *)realloc(outbuf, outbuf_size); if (out_start == NULL) return ENOMEM; From 2d7286d5713beda212f539c4bb251253f947811f Mon Sep 17 00:00:00 2001 From: Christopher Brannon Date: Sun, 2 May 2021 17:52:41 -0700 Subject: [PATCH 2/2] Fix out-of-bounds read when processing malformed SSML. --- CHANGELOG.md | 4 ++++ src/libespeak-ng/readclause.c | 23 +++++++++++++++-------- tests/ssml/badly-escaped1.expected | 1 + tests/ssml/badly-escaped1.ssml | 1 + tests/ssml/badly-escaped2.expected | 1 + tests/ssml/badly-escaped2.ssml | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) create mode 100644 tests/ssml/badly-escaped1.expected create mode 100644 tests/ssml/badly-escaped1.ssml create mode 100644 tests/ssml/badly-escaped2.expected create mode 100644 tests/ssml/badly-escaped2.ssml diff --git a/CHANGELOG.md b/CHANGELOG.md index 865bd02b..542b87e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ The espeak-ng project is a fork of the espeak project. * New Language option: "lowercaseSentence" for ending a sentence if a period is followed by a lower case letter. * Added voice variants +bug fixes: +* Fix reading malformed SSML (Christopher Brannon) +* Fix memory allocation (Christopher Brannon) + documentation: * Add documentation about voice and language options. * Add documentation about dictionary flags. diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c index f3d2b4e8..25d51896 100644 --- a/src/libespeak-ng/readclause.c +++ b/src/libespeak-ng/readclause.c @@ -510,10 +510,13 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ tr->clause_lower_count = 0; *tone_type = 0; - if (ungot_char2 != 0) + if (ungot_char2 != 0) { c2 = ungot_char2; - else + } else if (Eof()) { + c2 = 0; + } else { c2 = GetC(); + } while (!Eof() || (ungot_char != 0) || (ungot_char2 != 0) || (ungot_string_ix >= 0)) { if (!iswalnum(c1)) { @@ -542,14 +545,14 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ if ((ungot_string_ix == 0) && (ungot_char2 == 0)) c1 = ungot_string[ungot_string_ix++]; - if (ungot_string_ix >= 0) + if (ungot_string_ix >= 0) { c2 = ungot_string[ungot_string_ix++]; - else { + } else if (Eof()) { + c2 = ' '; + } else { c2 = GetC(); - - if (Eof()) - c2 = ' '; } + ungot_char2 = 0; if ((option_ssml) && (phoneme_mode == 0)) { @@ -561,7 +564,11 @@ int ReadClause(Translator *tr, char *buf, short *charix, int *charix_top, int n_ c1 = GetC(); } xml_buf2[n_xml_buf] = 0; - c2 = GetC(); + if (Eof()) { + c2 = '\0'; + } else { + c2 = GetC(); + } sprintf(ungot_string, "%s%c%c", &xml_buf2[0], c1, c2); int found = -1; diff --git a/tests/ssml/badly-escaped1.expected b/tests/ssml/badly-escaped1.expected new file mode 100644 index 00000000..ec74f33b --- /dev/null +++ b/tests/ssml/badly-escaped1.expected @@ -0,0 +1 @@ +kəmpˈa͡ɪl ænd flˈæʃ lˈɪnɪɪd͡ʒ ˈændɹɔ͡ɪd ˌo͡ʊˈɛs diff --git a/tests/ssml/badly-escaped1.ssml b/tests/ssml/badly-escaped1.ssml new file mode 100644 index 00000000..f5dcf5a9 --- /dev/null +++ b/tests/ssml/badly-escaped1.ssml @@ -0,0 +1 @@ +compile&flash Lineage Android OS diff --git a/tests/ssml/badly-escaped2.expected b/tests/ssml/badly-escaped2.expected new file mode 100644 index 00000000..35cc6240 --- /dev/null +++ b/tests/ssml/badly-escaped2.expected @@ -0,0 +1 @@ +kəmpˈa͡ɪl ænd flˈæʃ diff --git a/tests/ssml/badly-escaped2.ssml b/tests/ssml/badly-escaped2.ssml new file mode 100644 index 00000000..380562ac --- /dev/null +++ b/tests/ssml/badly-escaped2.ssml @@ -0,0 +1 @@ +compile&flash