aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Teterin <mi@FreeBSD.org>2023-02-21 07:23:22 +0000
committerMikhail Teterin <mi@FreeBSD.org>2023-02-21 07:23:22 +0000
commit39e57d44aa5af331426f14f1a54c07d6912a7b91 (patch)
tree75ff1dd3c0238b8ee18580f1f44446c721e4ce44
parent251785d28bfd10945e87b53a0d116fe3af24e947 (diff)
downloadports-39e57d44aa5af331426f14f1a54c07d6912a7b91.tar.gz
ports-39e57d44aa5af331426f14f1a54c07d6912a7b91.zip
audio/festival: fix crash due to overly aggressive optimization
Modern clang, optimize away checks like "if (this == NULL)", which are, indeed, redundant in good C++ code. Unfortunately, festival's code is not too good, and the checks are essential... PR: 269583 While here, eliminate some of the other warnings raised by both compiler and valgrind, and adapt one more patch from Debian. Bump PORTREVISION.
-rw-r--r--audio/festival/Makefile8
-rw-r--r--audio/festival/files/patch-hts-buffer-bounds-check313
-rw-r--r--audio/festival/files/patch-warnings76
3 files changed, 393 insertions, 4 deletions
diff --git a/audio/festival/Makefile b/audio/festival/Makefile
index 3c143deffb14..05001c346ef7 100644
--- a/audio/festival/Makefile
+++ b/audio/festival/Makefile
@@ -1,6 +1,6 @@
PORTNAME= festival
PORTVERSION= 2.4
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= audio accessibility
MASTER_SITES= FESTIVAL
DISTFILES= ${DISTNAME}-release.tar.gz \
@@ -27,13 +27,13 @@ WWW= https://www.cstr.ed.ac.uk/projects/festival/
OPTIONS_DEFINE= NAS
OPTIONS_DEFAULT=NAS
-CXXFLAGS+= -DFTLIBDIR=${LOCALBASE}/share/festival/lib
+CXXFLAGS+= -DFTLIBDIR=${LOCALBASE}/share/festival/lib -fno-delete-null-pointer-checks
CONFIGURE_WRKSRC=${WRKDIR}/festival
USES= gmake
SPEECHTOOLS= ${WRKSRC}/speech_tools
FESTIVAL= ${WRKSRC}/festival
-MAKE_ARGS+= CC="${CC}" GCC="${CC}" \
- CXX="${CXX}" GXX="${CXX}" \
+MAKE_ARGS+= CC="${CCACHE_BIN} ${CC}" GCC="${CCACHE_BIN} ${CC}" \
+ CXX="${CCACHE_BIN} ${CXX}" GXX="${CCACHE_BIN} ${CXX}" \
EST_HOME=${SPEECHTOOLS}
WRKSRC= ${WRKDIR}
diff --git a/audio/festival/files/patch-hts-buffer-bounds-check b/audio/festival/files/patch-hts-buffer-bounds-check
new file mode 100644
index 000000000000..0cb94a0aa357
--- /dev/null
+++ b/audio/festival/files/patch-hts-buffer-bounds-check
@@ -0,0 +1,313 @@
+Obtained from Debian. Original description follows:
+
+Description: HTS engine does not check buffer bounds in some functions.
+This patch adds bounds checking to prevent writing past the end of the buffer.
+
+Author: Peter Drysdale <drysdalepete@gmail.com>
+
+--- festival/src/modules/hts_engine/HTS_engine.c
++++ festival/src/modules/hts_engine/HTS_engine.c
+@@ -467,7 +467,7 @@
+ }
+
+ /* HTS_Engine_synthesize_from_strings: synthesize speech from strings */
+-HTS_Boolean HTS_Engine_synthesize_from_strings(HTS_Engine * engine, char **lines, size_t num_lines)
++HTS_Boolean HTS_Engine_synthesize_from_strings(HTS_Engine * engine, const char **lines, size_t num_lines)
+ {
+ HTS_Engine_refresh(engine);
+ HTS_Label_load_from_strings(&engine->label, engine->condition.sampling_frequency, engine->condition.fperiod, lines, num_lines);
+--- festival/src/modules/hts_engine/HTS_engine.h
++++ festival/src/modules/hts_engine/HTS_engine.h
+@@ -427,7 +427,7 @@
+ HTS_Boolean HTS_Engine_synthesize_from_fn(HTS_Engine * engine, const char *fn);
+
+ /* HTS_Engine_synthesize_from_strings: synthesize speech from string list */
+-HTS_Boolean HTS_Engine_synthesize_from_strings(HTS_Engine * engine, char **lines, size_t num_lines);
++HTS_Boolean HTS_Engine_synthesize_from_strings(HTS_Engine * engine, const char **lines, size_t num_lines);
+
+ /* HTS_Engine_save_information: save trace information */
+ void HTS_Engine_save_information(HTS_Engine * engine, FILE * fp);
+--- festival/src/modules/hts_engine/HTS_hidden.h
++++ festival/src/modules/hts_engine/HTS_hidden.h
+@@ -117,16 +117,16 @@
+ size_t HTS_fwrite_little_endian(const void *buf, size_t size, size_t n, FILE * fp);
+
+ /* HTS_get_pattern_token: get pattern token (single/double quote can be used) */
+-HTS_Boolean HTS_get_pattern_token(HTS_File * fp, char *buff);
++HTS_Boolean HTS_get_pattern_token(HTS_File * fp, char *buff, size_t bufflen);
+
+ /* HTS_get_token: get token from file pointer (separators are space,tab,line break) */
+-HTS_Boolean HTS_get_token_from_fp(HTS_File * fp, char *buff);
++HTS_Boolean HTS_get_token_from_fp(HTS_File * fp, char *buff, size_t bufflen);
+
+ /* HTS_get_token: get token from file pointer with specified separator */
+ HTS_Boolean HTS_get_token_from_fp_with_separator(HTS_File * fp, char *buff, char separator);
+
+ /* HTS_get_token_from_string: get token from string (separator are space,tab,line break) */
+-HTS_Boolean HTS_get_token_from_string(const char *string, size_t * index, char *buff);
++HTS_Boolean HTS_get_token_from_string(const char *string, size_t * index, char *buff, size_t bufflen);
+
+ /* HTS_get_token_from_string_with_separator: get token from string with specified separator */
+ HTS_Boolean HTS_get_token_from_string_with_separator(const char *str, size_t * index, char *buff, char separator);
+@@ -248,7 +248,7 @@
+ void HTS_Label_load_from_fn(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char *fn);
+
+ /* HTS_Label_load_from_strings: load label list from string list */
+-void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, char **lines, size_t num_lines);
++void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char **lines, size_t num_lines);
+
+ /* HTS_Label_get_size: get number of label string */
+ size_t HTS_Label_get_size(HTS_Label * label);
+--- festival/src/modules/hts_engine/HTS_misc.c
++++ festival/src/modules/hts_engine/HTS_misc.c
+@@ -333,7 +333,7 @@
+ }
+
+ /* HTS_get_pattern_token: get pattern token (single/double quote can be used) */
+-HTS_Boolean HTS_get_pattern_token(HTS_File * fp, char *buff)
++HTS_Boolean HTS_get_pattern_token(HTS_File * fp, char *buff, size_t bufflen)
+ {
+ char c;
+ size_t i;
+@@ -369,7 +369,7 @@
+ }
+
+ i = 0;
+- while (1) {
++ while (i<bufflen) {
+ buff[i++] = c;
+ c = HTS_fgetc(fp);
+ if (squote && c == '\'')
+@@ -386,12 +386,16 @@
+ }
+ }
+
++ if (i == bufflen) {
++ HTS_error(2,"HTS_get_pattern_token: Buffer overflow.\n");
++ }
++
+ buff[i] = '\0';
+ return TRUE;
+ }
+
+ /* HTS_get_token: get token from file pointer (separators are space, tab, and line break) */
+-HTS_Boolean HTS_get_token_from_fp(HTS_File * fp, char *buff)
++HTS_Boolean HTS_get_token_from_fp(HTS_File * fp, char *buff, size_t bufflen)
+ {
+ char c;
+ size_t i;
+@@ -407,7 +411,7 @@
+ return FALSE;
+ }
+
+- for (i = 0; c != ' ' && c != '\n' && c != '\t';) {
++ for (i = 0; c != ' ' && c != '\n' && c != '\t' && (i<bufflen);) {
+ buff[i++] = c;
+ if (HTS_feof(fp))
+ break;
+@@ -416,6 +420,10 @@
+ break;
+ }
+
++ if (i == bufflen) {
++ HTS_error(2,"HTS_get_token: Buffer overflow.\n");
++ }
++
+ buff[i] = '\0';
+ return TRUE;
+ }
+@@ -451,7 +459,7 @@
+ }
+
+ /* HTS_get_token_from_string: get token from string (separators are space, tab, and line break) */
+-HTS_Boolean HTS_get_token_from_string(const char *string, size_t * index, char *buff)
++HTS_Boolean HTS_get_token_from_string(const char *string, size_t * index, char *buff, size_t bufflen)
+ {
+ char c;
+ size_t i;
+@@ -467,11 +475,15 @@
+ return FALSE;
+ c = string[(*index)++];
+ }
+- for (i = 0; c != ' ' && c != '\n' && c != '\t' && c != '\0'; i++) {
++ for (i = 0; c != ' ' && c != '\n' && c != '\t' && c != '\0' && (i<bufflen); i++) {
+ buff[i] = c;
+ c = string[(*index)++];
+ }
+
++ if (i == bufflen) {
++ HTS_error(2,"HTS_get_token_from_string: Buffer overflow.\n");
++ }
++
+ buff[i] = '\0';
+ return TRUE;
+ }
+@@ -480,7 +492,7 @@
+ HTS_Boolean HTS_get_token_from_string_with_separator(const char *str, size_t * index, char *buff, char separator)
+ {
+ char c;
+- size_t start;
++ /*size_t start;*/
+ size_t len = 0;
+
+ if (str == NULL)
+@@ -495,7 +507,7 @@
+ (*index)++;
+ c = str[(*index)];
+ }
+- start = (*index);
++ /*start = (*index);*/
+ while (c != separator && c != '\0') {
+ buff[len++] = c;
+ (*index)++;
+--- festival/src/modules/hts_engine/HTS_model.c
++++ festival/src/modules/hts_engine/HTS_model.c
+@@ -194,12 +194,12 @@
+ HTS_Question_clear(question);
+
+ /* get question name */
+- if (HTS_get_pattern_token(fp, buff) == FALSE)
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE)
+ return FALSE;
+ question->string = HTS_strdup(buff);
+
+ /* get pattern list */
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ HTS_Question_clear(question);
+ return FALSE;
+ }
+@@ -207,7 +207,7 @@
+ last_pattern = NULL;
+ if (strcmp(buff, "{") == 0) {
+ while (1) {
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ HTS_Question_clear(question);
+ return FALSE;
+ }
+@@ -218,7 +218,7 @@
+ question->head = pattern;
+ pattern->string = HTS_strdup(buff);
+ pattern->next = NULL;
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ HTS_Question_clear(question);
+ return FALSE;
+ }
+@@ -358,7 +358,7 @@
+ if (tree == NULL || fp == NULL)
+ return FALSE;
+
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ HTS_Tree_clear(tree);
+ return FALSE;
+ }
+@@ -367,14 +367,14 @@
+ tree->root = last_node = node;
+
+ if (strcmp(buff, "{") == 0) {
+- while (HTS_get_pattern_token(fp, buff) == TRUE && strcmp(buff, "}") != 0) {
++ while (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == TRUE && strcmp(buff, "}") != 0) {
+ node = HTS_Node_find(last_node, atoi(buff));
+ if (node == NULL) {
+ HTS_error(0, "HTS_Tree_load: Cannot find node %d.\n", atoi(buff));
+ HTS_Tree_clear(tree);
+ return FALSE;
+ }
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ HTS_Tree_clear(tree);
+ return FALSE;
+ }
+@@ -389,7 +389,7 @@
+ HTS_Node_initialize(node->yes);
+ HTS_Node_initialize(node->no);
+
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ node->quest = NULL;
+ free(node->yes);
+ free(node->no);
+@@ -403,7 +403,7 @@
+ node->no->next = last_node;
+ last_node = node->no;
+
+- if (HTS_get_pattern_token(fp, buff) == FALSE) {
++ if (HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN) == FALSE) {
+ node->quest = NULL;
+ free(node->yes);
+ free(node->no);
+@@ -495,7 +495,7 @@
+ win->coefficient = (double **) HTS_calloc(win->size, sizeof(double *));
+ /* set delta coefficents */
+ for (i = 0; i < win->size; i++) {
+- if (HTS_get_token_from_fp(fp[i], buff) == FALSE) {
++ if (HTS_get_token_from_fp(fp[i], buff, HTS_MAXBUFLEN) == FALSE) {
+ result = FALSE;
+ fsize = 1;
+ } else {
+@@ -508,7 +508,7 @@
+ /* read coefficients */
+ win->coefficient[i] = (double *) HTS_calloc(fsize, sizeof(double));
+ for (j = 0; j < fsize; j++) {
+- if (HTS_get_token_from_fp(fp[i], buff) == FALSE) {
++ if (HTS_get_token_from_fp(fp[i], buff, HTS_MAXBUFLEN) == FALSE) {
+ result = FALSE;
+ win->coefficient[i][j] = 0.0;
+ } else {
+@@ -610,7 +610,7 @@
+ last_question = NULL;
+ last_tree = NULL;
+ while (!HTS_feof(fp)) {
+- HTS_get_pattern_token(fp, buff);
++ HTS_get_pattern_token(fp, buff, HTS_MAXBUFLEN);
+ /* parse questions */
+ if (strcmp(buff, "QS") == 0) {
+ question = (HTS_Question *) HTS_calloc(1, sizeof(HTS_Question));
+--- festival/src/modules/hts_engine/HTS_label.c
++++ festival/src/modules/hts_engine/HTS_label.c
+@@ -117,5 +117,5 @@
+
+ /* parse label file */
+- while (HTS_get_token_from_fp(fp, buff)) {
++ while (HTS_get_token_from_fp(fp, buff, HTS_MAXBUFLEN)) {
+ if (!isgraph((int) buff[0]))
+ break;
+@@ -130,9 +130,9 @@
+ }
+ if (isdigit_string(buff)) { /* has frame infomation */
+ start = atof(buff);
+- HTS_get_token_from_fp(fp, buff);
++ HTS_get_token_from_fp(fp, buff, HTS_MAXBUFLEN);
+ end = atof(buff);
+- HTS_get_token_from_fp(fp, buff);
++ HTS_get_token_from_fp(fp, buff, HTS_MAXBUFLEN);
+ lstring->start = rate * start;
+ lstring->end = rate * end;
+ } else {
+@@ -154,7 +154,7 @@
+ }
+
+ /* HTS_Label_load_from_strings: load label from strings */
+-void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, char **lines, size_t num_lines)
++void HTS_Label_load_from_strings(HTS_Label * label, size_t sampling_rate, size_t fperiod, const char **lines, size_t num_lines)
+ {
+ char buff[HTS_MAXBUFLEN];
+ HTS_LabelString *lstring = NULL;
+@@ -182,11 +182,11 @@
+ }
+ data_index = 0;
+ if (isdigit_string(lines[i])) { /* has frame infomation */
+- HTS_get_token_from_string(lines[i], &data_index, buff);
++ HTS_get_token_from_string(lines[i], &data_index, buff, HTS_MAXBUFLEN);
+ start = atof(buff);
+- HTS_get_token_from_string(lines[i], &data_index, buff);
++ HTS_get_token_from_string(lines[i], &data_index, buff, HTS_MAXBUFLEN);
+ end = atof(buff);
+- HTS_get_token_from_string(lines[i], &data_index, buff);
++ HTS_get_token_from_string(lines[i], &data_index, buff, HTS_MAXBUFLEN);
+ lstring->name = HTS_strdup(buff);
+ lstring->start = rate * start;
+ lstring->end = rate * end;
diff --git a/audio/festival/files/patch-warnings b/audio/festival/files/patch-warnings
new file mode 100644
index 000000000000..228b3a270848
--- /dev/null
+++ b/audio/festival/files/patch-warnings
@@ -0,0 +1,76 @@
+Address some of the warnings flagged by either compiler or valgrind.
+
+ -mi
+--- speech_tools/stats/EST_Discrete.cc 2010-11-05 10:12:43.000000000 -0400
++++ speech_tools/stats/EST_Discrete.cc 2023-02-20 22:17:06.842236000 -0500
+@@ -152,5 +152,5 @@
+ for (i=0; i<next_free; i++)
+ delete discretes[i];
+- delete discretes;
++ delete[] discretes;
+ }
+
+--- festival/src/modules/hts_engine/fest2hts_engine.cc 2013-02-18 10:10:52.000000000 -0500
++++ festival/src/modules/hts_engine/fest2hts_engine.cc 2023-02-20 22:55:59.303248000 -0500
+@@ -191,16 +191,16 @@
+ char *copyright[] = { HTS_COPYRIGHT };
+
+- sprintf(str,
++ str += sprintf(str,
+ "\nThe HMM-Based Speech Synthesis Engine \"hts_engine API\"\n");
+
+- sprintf(str,
+- "%shts_engine API version %s (%s)\n", str, version, url);
++ str += sprintf(str,
++ "hts_engine API version %s (%s)\n", version, url);
+ for (i = 0; i < nCopyright; i++) {
+ if (i == 0)
+- sprintf(str,
+- "%sCopyright (C) %s\n", str, copyright[i]);
++ str += sprintf(str,
++ "Copyright (C) %s\n", copyright[i]);
+ else
+- sprintf(str,
+- "%s %s\n", str, copyright[i]);
++ str += sprintf(str,
++ " %s\n", copyright[i]);
+ }
+ sprintf(str, "%sAll rights reserved.\n", str);
+--- speech_tools/speech_class/EST_wave_io.cc 2013-10-14 17:54:33.000000000 -0400
++++ speech_tools/speech_class/EST_wave_io.cc 2023-02-21 00:03:12.559352000 -0500
+@@ -230,5 +230,5 @@
+ data_length = length*(*num_channels);
+
+- file_data = walloc(unsigned char,sample_width * data_length);
++ file_data = new unsigned char[sample_width * data_length];
+
+ ts.seek(current_pos+NIST_HDR_SIZE+(sample_width*offset*(*num_channels)));
+--- speech_tools/siod/slib_python.cc 2014-12-11 10:30:16.000000000 -0500
++++ speech_tools/siod/slib_python.cc 2023-02-21 00:07:42.577728000 -0500
+@@ -372,8 +372,4 @@
+ Py_Finalize();
+ }
+-#else // No python support
+-
+-/* So there is a symbol in here even if there is no python support */
+-static int est_no_python_support = 1;
+
+ #endif // EST_SIOD_ENABLE_PYTHON
+--- speech_tools/include/EST_Token.h 2004-09-29 04:24:17.000000000 -0400
++++ speech_tools/include/EST_Token.h 2023-02-21 00:23:22.647701000 -0500
+@@ -119,6 +119,4 @@
+ const EST_String &string() const { return String(); }
+ /// Access token as a string
+- const EST_String &S() const { return S(); }
+- /// Access token as a string
+ const EST_String &String() const { return pname; }
+ /// For automatic coercion to \Ref{EST_String}
+--- festival/src/modules/UniSyn/us_mapping.cc 2014-12-18 10:48:03.000000000 -0500
++++ festival/src/modules/UniSyn/us_mapping.cc 2023-02-21 00:47:56.907441000 -0500
+@@ -169,5 +169,5 @@
+ // find closest pitchmark (assume only need forward search from current
+ // point, since pitchmarks should always be increasing)
+- while( (apm_i<=s_i_end) && (fabs((next_apm_t*m)-tpm_t) <= fabs((apm_t*m)-tpm_t)) ){
++ while ((apm_i < s_i_end - 1) && (fabs((next_apm_t*m)-tpm_t) <= fabs((apm_t*m)-tpm_t))) {
+ // printf("(next_apm_t apm_t) %f %f\n",
+ // fabs((next_apm_t*m)-tpm_t), fabs((apm_t*m)-tpm_t) );