From edc4693448541fe1a53e873c45dbf15396bb270b Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 1 Aug 2026 19:40:15 -0400 Subject: [PATCH 1/5] rtl-sdr: Fix out-of-bounds access in gain selection The gain change handler allowed an index equal to m_gains.size(), which is outside the valid vector range. Reject invalid indices before accessing the gain table to avoid undefined behavior. found with cppcheck: Access out of bounds Signed-off-by: Robin Getz --- plugins/samplesource/rtlsdr/rtlsdrgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp index 6cde4e82c..1399637ae 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrgui.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrgui.cpp @@ -394,7 +394,7 @@ void RTLSDRGui::on_ppm_valueChanged(int value) void RTLSDRGui::on_gain_valueChanged(int value) { - if (value > (int)m_gains.size()) { + if (value < 0 || value >= (int)m_gains.size()) { return; } From c170e03dddaf4b76d6b438ebf17658bb00c617cd Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 1 Aug 2026 19:52:09 -0400 Subject: [PATCH 2/5] rtl-sdr: Fix out-of-bounds tuner name lookup Validate the tuner type index before accessing the tuner name table. The previous check allowed an index equal to names.size(), which could result in an out-of-range QStringList access. Use a local integer value for the enum conversion and ensure only valid indices are used when looking up tuner names. pointed out by cppcheck: Access out of bounds Signed-off-by: Robin Getz --- plugins/samplesource/rtlsdr/rtlsdrinput.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp index 82ea15cd9..b5497ef9b 100644 --- a/plugins/samplesource/rtlsdr/rtlsdrinput.cpp +++ b/plugins/samplesource/rtlsdr/rtlsdrinput.cpp @@ -469,8 +469,10 @@ QString RTLSDRInput::getTunerName() const { const static QStringList names = {"Unknown", "E4000", "FC0012", "FC0013", "FC2580", "R820T", "R828D"}; - if ((int) m_tunerType <= names.size()) { - return names[(int) m_tunerType]; + const int tunerType = (int) m_tunerType; + + if (tunerType >= 0 && tunerType < names.size()) { + return names[tunerType]; } else { return names[0]; } From e6c3cecb646f7b8de6323e04b443d36c9d9e6e2c Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 1 Aug 2026 22:41:23 -0400 Subject: [PATCH 3/5] scope: Check for empty trigger list before indexing Move the existing empty-trigger check ahead of the access to the current trigger condition. The previous code indexed m_triggerConditions before verifying that the container was non-empty, which could result in an out-of-bounds access. No functional behavior is changed for the non-empty case. noticed by cppcheck : Access out of bounds Signed-off-by: Robin Getz --- sdrbase/dsp/scopevis.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sdrbase/dsp/scopevis.cpp b/sdrbase/dsp/scopevis.cpp index d69297bac..8ba401eb2 100644 --- a/sdrbase/dsp/scopevis.cpp +++ b/sdrbase/dsp/scopevis.cpp @@ -725,6 +725,12 @@ void ScopeVis::processTrace(const std::vector& vc bool ScopeVis::nextTrigger() { + if (m_triggerConditions.empty()) + { + m_currentTriggerIndex = 0; + return false; // final + } + TriggerCondition *triggerCondition = m_triggerConditions[m_currentTriggerIndex]; // current trigger condition if (triggerCondition->m_triggerData.m_triggerRepeat > 0) @@ -740,12 +746,7 @@ bool ScopeVis::nextTrigger() } } - if (m_triggerConditions.size() == 0) - { - m_currentTriggerIndex = 0; - return false; // final - } - else if (m_currentTriggerIndex < m_triggerConditions.size() - 1) // check if next trigger is available + if (m_currentTriggerIndex < m_triggerConditions.size() - 1) // check if next trigger is available { m_currentTriggerIndex++; return true; // not final keep going From 08ff033dc33a47751b0a8a4c977d3e8457b1dd44 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 1 Aug 2026 23:16:15 -0400 Subject: [PATCH 4/5] aprs: Fix out-of-bounds access in item parsing cppcheck reported an out-of-bounds access in APRSPacket::parseItem() when parsing item names. The parser checked the string length using an incorrect boundary condition, allowing an index equal to the string length to be accessed. Validate the item terminator before indexing the string, and ensure malformed packets without a valid terminator are rejected. Also simplify the item name parsing logic while enforcing the APRS 3-9 character item name limit. Signed-off-by: Robin Getz --- sdrbase/util/aprs.cpp | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/sdrbase/util/aprs.cpp b/sdrbase/util/aprs.cpp index c0dc12d5c..2f810ad36 100644 --- a/sdrbase/util/aprs.cpp +++ b/sdrbase/util/aprs.cpp @@ -724,28 +724,29 @@ bool APRSPacket::parseObject(QString& info, int& idx) bool APRSPacket::parseItem(QString& info, int& idx) { - if (info.length() < idx+3) + // Item names are 3-9 characters long and terminated by '!' or '_' + // Require the minimum 3-character name plus the terminator. + if (info.length() < (idx + 3 + 1)) return false; - // Item names are 3-9 chars long, excluding ! or _ - m_objectName = ""; - int i; - for (i = 0; i < 10; i++) + m_objectName.clear(); + + for (int i = 0; (i < 9) && (idx < info.length()); ++i) { - if (info.length() >= idx) - { - QChar c = info[idx]; - if (c == '!' || c == '_') - break; - else - { - m_objectName.append(c); - idx++; - } - } + const QChar c = info[idx]; + if (c == '!' || c == '_') + break; + + m_objectName.append(c); + ++idx; } - if (i == 11) + + if (idx >= info.length()) return false; + + if (info[idx] != '!' && info[idx] != '_') + return false; + if (info[idx] == '!') m_objectLive = true; else if (info[idx] == '_') From 26c484d668e3629fdf146be91a7d171fa5916135 Mon Sep 17 00:00:00 2001 From: Robin Getz Date: Sat, 1 Aug 2026 23:26:54 -0400 Subject: [PATCH 5/5] aprs: Fix out-of-bounds access when parsing BITS telemetry cppcheck reported a possible out-of-bounds access in the BITS telemetry message parser. The bounds check was reversed, causing m_message[i] to be accessed when i was beyond the end of the string. Correct the condition so missing bit sense values continue to use the existing default value. Signed-off-by: Robin Getz --- sdrbase/util/aprs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdrbase/util/aprs.cpp b/sdrbase/util/aprs.cpp index 2f810ad36..e8dae7862 100644 --- a/sdrbase/util/aprs.cpp +++ b/sdrbase/util/aprs.cpp @@ -953,7 +953,7 @@ bool APRSPacket::parseMessage(QString& info, int& idx) int i = 5; for (int j = 0; j < 8; j++) { - if (i >= m_message.length()) + if (i < m_message.length()) m_telemetryBitSense[j] = m_message[i] == '1'; else m_telemetryBitSense[j] = true;