From 9eceb100130dd560f505fe23d7a61751ee035bcb Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Mon, 13 Jul 2026 17:31:09 +0200 Subject: [PATCH] Fix crash announcing menu strings past the voice-prompt table voicePromptsAppendLanguageString() turns a language-string pointer into a prompt index (NUM_VOICE_PROMPTS + offset), and voicePromptsPlay() then reads tableOfContents[index + 1]. Strings added after the voice-prompt pack was built (the SMS menu entries) land past the 368-entry table, so the player read off the end of the array and the radio crashed when the Messages menu announced a submenu name with voice prompts enabled. Clamp any index at or beyond the last table slot to PROMPT_SILENCE, so such strings are simply not spoken. Also protects the pre-existing strings sitting at the very end of the table. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 6 +++++- .../application/source/functions/voicePrompts.c | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6ac322..00513db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,11 @@ single running list until the first versioned release. ## Unreleased -_Nothing yet._ +- **Fix:** the radio **crashed** when navigating the Messages menu with voice + prompts enabled. Menu strings added after the voice-prompt pack was built map + to a table-of-contents slot that doesn't exist; the player read past the end + of the table. Such strings now play silence instead (also hardens the + pre-existing strings sitting at the end of the table). ## 0.7.0 diff --git a/MDUV380_firmware/application/source/functions/voicePrompts.c b/MDUV380_firmware/application/source/functions/voicePrompts.c index a105fbc..63cf9c1 100644 --- a/MDUV380_firmware/application/source/functions/voicePrompts.c +++ b/MDUV380_firmware/application/source/functions/voicePrompts.c @@ -352,13 +352,25 @@ void voicePromptsAppendLanguageString(const char *languageStringAdd) return; } - voicePromptsAppendPrompt(NUM_VOICE_PROMPTS + + int promptNumber = NUM_VOICE_PROMPTS + ((languageStringAdd - currentLanguage->LANGUAGE_NAME) #if ! defined(HAS_COLOURS) - ((languageStringAdd >= currentLanguage->theme_chooser) ? ((currentLanguage->theme_colour_picker_blue - currentLanguage->theme_chooser) + LANGUAGE_TEXTS_LENGTH) : 0) #endif - ) / LANGUAGE_TEXTS_LENGTH); + ) / LANGUAGE_TEXTS_LENGTH; + + // Language strings added after the voice prompt pack was built have no + // entry in the table of contents. voicePromptsPlay() reads TOC[promptNumber + 1], + // so anything at or past the last slot would read past the array and crash; + // play silence for those instead. + if ((promptNumber < 0) || (promptNumber >= (VOICE_PROMPTS_TOC_SIZE - 1))) + { + voicePromptsAppendPrompt(PROMPT_SILENCE); + return; + } + + voicePromptsAppendPrompt(promptNumber); } void voicePromptsPlay(void)