fix: three bugs found in code review

- DataStore: validate ringtone2_len <= 32 after loading from flash
  (same guard as ringtone_len on line 252; we introduced this field
  but forgot the validation)
- UITask: fix shutdown buzzer timeout to conventional unsigned form
  (millis() - start) < timeout to avoid unsigned underflow if called
  within first 2.5s of boot
- UITask: guard _last_notif_ch_idx < 64 before 1ULL shift in notify()
  (defensive; MAX_GROUP_CHANNELS=40 so currently unreachable, but
  prevents UB if the value is ever unexpectedly out of range)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-05-15 15:34:10 +02:00
co-authored by Claude Sonnet 4.6
parent a819b05ed0
commit 484f0891b1
2 changed files with 4 additions and 3 deletions
+1
View File
@@ -273,6 +273,7 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
if (file.available()) { if (file.available()) {
file.read((uint8_t *)&_prefs.ringtone2_bpm_idx, sizeof(_prefs.ringtone2_bpm_idx)); file.read((uint8_t *)&_prefs.ringtone2_bpm_idx, sizeof(_prefs.ringtone2_bpm_idx));
file.read((uint8_t *)&_prefs.ringtone2_len, sizeof(_prefs.ringtone2_len)); file.read((uint8_t *)&_prefs.ringtone2_len, sizeof(_prefs.ringtone2_len));
if (_prefs.ringtone2_len > 32) _prefs.ringtone2_len = 0;
file.read((uint8_t *)_prefs.ringtone2_notes, sizeof(_prefs.ringtone2_notes)); file.read((uint8_t *)_prefs.ringtone2_notes, sizeof(_prefs.ringtone2_notes));
if (file.available()) { if (file.available()) {
file.read((uint8_t *)&_prefs.notif_melody_dm, sizeof(_prefs.notif_melody_dm)); file.read((uint8_t *)&_prefs.notif_melody_dm, sizeof(_prefs.notif_melody_dm));
+3 -3
View File
@@ -2527,7 +2527,7 @@ switch(t){
case UIEventType::channelMessage: { case UIEventType::channelMessage: {
bool play = false; bool play = false;
bool force = false; bool force = false;
if (_last_notif_ch_idx >= 0 && _node_prefs) { if (_last_notif_ch_idx >= 0 && _last_notif_ch_idx < 64 && _node_prefs) {
uint64_t mask = 1ULL << _last_notif_ch_idx; uint64_t mask = 1ULL << _last_notif_ch_idx;
if (_node_prefs->ch_notif_override & mask) { if (_node_prefs->ch_notif_override & mask) {
if (!(_node_prefs->ch_notif_muted & mask)) { play = true; force = true; } if (!(_node_prefs->ch_notif_muted & mask)) { play = true; force = true; }
@@ -2539,7 +2539,7 @@ switch(t){
} }
if (play) { if (play) {
int slot = _node_prefs ? (int)_node_prefs->notif_melody_ch : 0; int slot = _node_prefs ? (int)_node_prefs->notif_melody_ch : 0;
if (_last_notif_ch_idx >= 0 && _node_prefs) { if (_last_notif_ch_idx >= 0 && _last_notif_ch_idx < 64 && _node_prefs) {
uint64_t mask = 1ULL << _last_notif_ch_idx; uint64_t mask = 1ULL << _last_notif_ch_idx;
if (_node_prefs->ch_notif_melody_set & mask) if (_node_prefs->ch_notif_melody_set & mask)
slot = (_node_prefs->ch_notif_melody_2 & mask) ? 2 : 1; slot = (_node_prefs->ch_notif_melody_2 & mask) ? 2 : 1;
@@ -2664,7 +2664,7 @@ void UITask::shutdown(bool restart){
*/ */
buzzer.shutdown(); buzzer.shutdown();
uint32_t buzzer_timer = millis(); // fail-safe shutdown uint32_t buzzer_timer = millis(); // fail-safe shutdown
while (buzzer.isPlaying() && (millis() - 2500) < buzzer_timer) while (buzzer.isPlaying() && (millis() - buzzer_timer) < 2500)
buzzer.loop(); buzzer.loop();
#endif // PIN_BUZZER #endif // PIN_BUZZER