Do not raise KeyError copying an undecryptable channels_log entry

parsePacketPayload copies message/msg_hash/sender_timestamp/attempt/txt_type from a
prior channels_log entry matched by pkt_hash. When that prior entry was logged while
the channel could not be decrypted it has none of those keys, so a later duplicate of
the same transmission raises KeyError: 'message' and aborts handle_rx for the whole
packet, dropping its RX_LOG_DATA. It triggers when a channel-table refresh lands
between two copies of a flooded channel message.

Copy with .get() so the fields are simply absent instead of raising. Adds a regression
test that reproduces the crash (fails on main, passes here).
This commit is contained in:
Aluminique
2026-08-29 02:07:07 +01:00
parent dd5502b968
commit 85fc311652
2 changed files with 59 additions and 5 deletions
+9 -5
View File
@@ -160,11 +160,15 @@ class MeshcorePacketParser:
log_data["txt_type"] = txt_type
else:
# found: copy
log_data["message"] = logged["message"]
log_data["msg_hash"] = logged["msg_hash"]
log_data["sender_timestamp"] = logged["sender_timestamp"]
log_data["attempt"] = logged["attempt"]
log_data["txt_type"] = logged["txt_type"]
# A prior channels_log entry matched by pkt_hash may have been logged while the
# channel could not be decrypted, so it has no "message"/"msg_hash"/etc. Copy with
# .get() so a duplicate of an unreadable frame does not raise KeyError and abort
# handle_rx for the whole packet.
log_data["message"] = logged.get("message")
log_data["msg_hash"] = logged.get("msg_hash")
log_data["sender_timestamp"] = logged.get("sender_timestamp")
log_data["attempt"] = logged.get("attempt")
log_data["txt_type"] = logged.get("txt_type")
self.channels_log.append(log_data)
if len(self.channels_log) > 100: