mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-05 06:45:39 +00:00
Don't crash in LoadVoice if langopts is NULL.
This commit is contained in:
+67
-45
@@ -705,47 +705,57 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
break;
|
||||
case V_INTONATION: // intonation
|
||||
sscanf(p, "%d %d", &option_tone_flags, &option_tone2);
|
||||
if ((option_tone_flags & 0xff) != 0)
|
||||
langopts->intonation_group = option_tone_flags & 0xff;
|
||||
if ((option_tone_flags & 0xff) != 0) {
|
||||
if (langopts)
|
||||
langopts->intonation_group = option_tone_flags & 0xff;
|
||||
else
|
||||
fprintf(stderr, "Cannot set intonation: language not set, or is invalid.\n");
|
||||
}
|
||||
break;
|
||||
case V_TUNES:
|
||||
n = sscanf(p, "%s %s %s %s %s %s", names[0], names[1], names[2], names[3], names[4], names[5]);
|
||||
langopts->intonation_group = 0;
|
||||
for (ix = 0; ix < n; ix++) {
|
||||
if (strcmp(names[ix], "NULL") == 0)
|
||||
continue;
|
||||
if (langopts) {
|
||||
langopts->intonation_group = 0;
|
||||
for (ix = 0; ix < n; ix++) {
|
||||
if (strcmp(names[ix], "NULL") == 0)
|
||||
continue;
|
||||
|
||||
if ((value = LookupTune(names[ix])) < 0)
|
||||
fprintf(stderr, "Unknown tune '%s'\n", names[ix]);
|
||||
else
|
||||
langopts->tunes[ix] = value;
|
||||
}
|
||||
if ((value = LookupTune(names[ix])) < 0)
|
||||
fprintf(stderr, "Unknown tune '%s'\n", names[ix]);
|
||||
else
|
||||
langopts->tunes[ix] = value;
|
||||
}
|
||||
} else
|
||||
fprintf(stderr, "Cannot set tunes: language not set, or is invalid.\n");
|
||||
break;
|
||||
case V_DICTRULES: // conditional dictionary rules and list entries
|
||||
case V_NUMBERS:
|
||||
case V_STRESSOPT:
|
||||
// expect a list of numbers
|
||||
while (*p != 0) {
|
||||
while (isspace(*p)) p++;
|
||||
if ((n = atoi(p)) > 0) {
|
||||
p++;
|
||||
if (n < 32) {
|
||||
if (key == V_DICTRULES)
|
||||
conditional_rules |= (1 << n);
|
||||
else if (key == V_NUMBERS)
|
||||
langopts->numbers |= (1 << n);
|
||||
else if (key == V_STRESSOPT)
|
||||
langopts->stress_flags |= (1 << n);
|
||||
} else {
|
||||
if ((key == V_NUMBERS) && (n < 64))
|
||||
langopts->numbers2 |= (1 << (n-32));
|
||||
else
|
||||
fprintf(stderr, "Bad option number %d\n", n);
|
||||
if (langopts) {
|
||||
// expect a list of numbers
|
||||
while (*p != 0) {
|
||||
while (isspace(*p)) p++;
|
||||
if ((n = atoi(p)) > 0) {
|
||||
p++;
|
||||
if (n < 32) {
|
||||
if (key == V_DICTRULES)
|
||||
conditional_rules |= (1 << n);
|
||||
else if (key == V_NUMBERS)
|
||||
langopts->numbers |= (1 << n);
|
||||
else if (key == V_STRESSOPT)
|
||||
langopts->stress_flags |= (1 << n);
|
||||
} else {
|
||||
if ((key == V_NUMBERS) && (n < 64))
|
||||
langopts->numbers2 |= (1 << (n-32));
|
||||
else
|
||||
fprintf(stderr, "Bad option number %d\n", n);
|
||||
}
|
||||
}
|
||||
while (isalnum(*p)) p++;
|
||||
}
|
||||
while (isalnum(*p)) p++;
|
||||
}
|
||||
ProcessLanguageOptions(langopts);
|
||||
ProcessLanguageOptions(langopts);
|
||||
} else
|
||||
fprintf(stderr, "Cannot set stressopt: language not set, or is invalid.\n");
|
||||
break;
|
||||
case V_REPLACE:
|
||||
if (phonemes_set == 0) {
|
||||
@@ -756,22 +766,31 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
PhonemeReplacement(p);
|
||||
break;
|
||||
case V_WORDGAP: // words
|
||||
sscanf(p, "%d %d", &langopts->word_gap, &langopts->vowel_pause);
|
||||
if (langopts)
|
||||
sscanf(p, "%d %d", &langopts->word_gap, &langopts->vowel_pause);
|
||||
else
|
||||
fprintf(stderr, "Cannot set wordgap: language not set, or is invalid.\n");
|
||||
break;
|
||||
case V_STRESSRULE:
|
||||
sscanf(p, "%d %d %d %d", &langopts->stress_rule,
|
||||
&langopts->stress_flags,
|
||||
&langopts->unstressed_wd1,
|
||||
&langopts->unstressed_wd2);
|
||||
if (langopts)
|
||||
sscanf(p, "%d %d %d %d", &langopts->stress_rule,
|
||||
&langopts->stress_flags,
|
||||
&langopts->unstressed_wd1,
|
||||
&langopts->unstressed_wd2);
|
||||
else
|
||||
fprintf(stderr, "Cannot set stressrule: language not set, or is invalid.\n");
|
||||
break;
|
||||
case V_OPTION:
|
||||
value2 = 0;
|
||||
if (((sscanf(p, "%s %d %d", option_name, &value, &value2) >= 2) && ((ix = LookupMnem(options_tab, option_name)) >= 0)) ||
|
||||
((sscanf(p, "%d %d %d", &ix, &value, &value2) >= 2) && (ix < N_LOPTS))) {
|
||||
langopts->param[ix] = value;
|
||||
langopts->param2[ix] = value2;
|
||||
if (langopts) {
|
||||
value2 = 0;
|
||||
if (((sscanf(p, "%s %d %d", option_name, &value, &value2) >= 2) && ((ix = LookupMnem(options_tab, option_name)) >= 0)) ||
|
||||
((sscanf(p, "%d %d %d", &ix, &value, &value2) >= 2) && (ix < N_LOPTS))) {
|
||||
langopts->param[ix] = value;
|
||||
langopts->param2[ix] = value2;
|
||||
} else
|
||||
fprintf(stderr, "Bad voice option: %s %s\n", buf, p);
|
||||
} else
|
||||
fprintf(stderr, "Bad voice option: %s %s\n", buf, p);
|
||||
fprintf(stderr, "Cannot set option: language not set, or is invalid.\n");
|
||||
break;
|
||||
case V_ECHO:
|
||||
// echo. suggest: 135mS 11%
|
||||
@@ -852,9 +871,12 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
case V_STATUS:
|
||||
break;
|
||||
default:
|
||||
if ((key & 0xff00) == 0x100)
|
||||
sscanf(p, "%d", &langopts->param[key &0xff]);
|
||||
else
|
||||
if ((key & 0xff00) == 0x100) {
|
||||
if (langopts)
|
||||
sscanf(p, "%d", &langopts->param[key &0xff]);
|
||||
else
|
||||
fprintf(stderr, "Cannot set voice attribute: language not set, or is invalid.\n");
|
||||
} else
|
||||
fprintf(stderr, "Bad voice attribute: %s\n", buf);
|
||||
break;
|
||||
}
|
||||
|
||||
+37
@@ -275,6 +275,42 @@ test_espeak_set_voice_by_name_invalid_voice()
|
||||
assert(p_decoder == NULL);
|
||||
}
|
||||
|
||||
void
|
||||
test_espeak_set_voice_by_name_language_variant_intonation_parameter()
|
||||
{
|
||||
printf("testing espeak_SetVoiceByName(\"!v/Annie\") (language variant; intonation)\n");
|
||||
|
||||
assert(event_list == NULL);
|
||||
assert(translator == NULL);
|
||||
assert(p_decoder == NULL);
|
||||
|
||||
assert(espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL, 0, NULL, 0) == 22050);
|
||||
assert(event_list != NULL);
|
||||
assert(translator == NULL);
|
||||
assert(p_decoder == NULL);
|
||||
|
||||
assert(espeak_SetVoiceByName("!v/Annie") == EE_OK);
|
||||
assert(translator != NULL);
|
||||
assert(strcmp(translator->dictionary_name, "en") == 0);
|
||||
assert(p_decoder == NULL);
|
||||
|
||||
const char *test = "One two three.";
|
||||
assert(espeak_Synth(test, strlen(test)+1, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL) == EE_OK);
|
||||
assert(translator != NULL);
|
||||
assert(strcmp(translator->dictionary_name, "en") == 0);
|
||||
assert(p_decoder != NULL);
|
||||
|
||||
assert(espeak_Synchronize() == EE_OK);
|
||||
assert(translator != NULL);
|
||||
assert(strcmp(translator->dictionary_name, "en") == 0);
|
||||
assert(p_decoder != NULL);
|
||||
|
||||
assert(espeak_Terminate() == EE_OK);
|
||||
assert(event_list == NULL);
|
||||
assert(translator == NULL);
|
||||
assert(p_decoder == NULL);
|
||||
}
|
||||
|
||||
// endregion
|
||||
// region espeak_SetVoiceByProperties
|
||||
|
||||
@@ -457,6 +493,7 @@ main(int argc, char **argv)
|
||||
test_espeak_set_voice_by_name_blank_voice();
|
||||
test_espeak_set_voice_by_name_valid_voice();
|
||||
test_espeak_set_voice_by_name_invalid_voice();
|
||||
test_espeak_set_voice_by_name_language_variant_intonation_parameter();
|
||||
|
||||
test_espeak_set_voice_by_properties_empty();
|
||||
test_espeak_set_voice_by_properties_blank_language();
|
||||
|
||||
Reference in New Issue
Block a user