From 35e483e312773af29792193ab591e9b32ffd6ef2 Mon Sep 17 00:00:00 2001 From: ErikBrown2 <32511867+ErikBrown2@users.noreply.github.com> Date: Sun, 30 Aug 2026 12:45:01 +0200 Subject: [PATCH 1/2] Fix ADVERT_PATH parsing of zero bytes Preserve valid 0x00 bytes in ADVERT_PATH data by reading the exact number of path bytes instead of stripping all zero bytes. --- src/meshcore/reader.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/meshcore/reader.py b/src/meshcore/reader.py index dc9ff90..002d1b8 100644 --- a/src/meshcore/reader.py +++ b/src/meshcore/reader.py @@ -149,7 +149,8 @@ class MessageReader: else: r["path_hash_mode"] = plen >> 6 # 2 upper bytes r["path_len"] = plen & 0x3F - r["path"] = dbuf.read().replace(b"\0", b"").hex() + path_byte_count = r["path_len"] * (r["path_hash_mode"] + 1) + r["path"] = dbuf.read(path_byte_count).hex() await self.dispatcher.dispatch(Event(EventType.ADVERT_PATH, r)) From e5a82eba5b937d2faf37ef55a0179dfbbbaa587c Mon Sep 17 00:00:00 2001 From: ErikBrown2 <32511867+ErikBrown2@users.noreply.github.com> Date: Sun, 30 Aug 2026 13:14:51 +0200 Subject: [PATCH 2/2] Add regression test for ADVERT_PATH zero bytes Verify that embedded 0x00 bytes in multi-byte ADVERT_PATH hashes are preserved during parsing. --- tests/unit/test_reader.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_reader.py b/tests/unit/test_reader.py index 758968e..2abc906 100644 --- a/tests/unit/test_reader.py +++ b/tests/unit/test_reader.py @@ -277,4 +277,29 @@ async def test_parse_packet_payload_txt_type_decodes_high_bits(): ) assert log_data["attempt"] == 1, ( f"Expected attempt=1, got {log_data['attempt']}" - ) \ No newline at end of file + ) + + +@pytest.mark.asyncio +async def test_advert_path_preserves_embedded_zero_bytes(): + """ADVERT_PATH must preserve valid 0x00 bytes inside path hashes.""" + dispatcher = _CapturingDispatcher() + reader = MessageReader(dispatcher) + + # ADVERT_PATH (0x0e), 2 hops, 3-byte hashes. + # path_len byte: hash mode 2 (3 bytes) + 2 hops = 0x82. + # The first hash deliberately contains an embedded 0x00 byte. + packet = bytearray.fromhex("0e8212003456789a") + + await reader.handle_rx(packet) + + advert_path_events = [ + e for e in dispatcher.events if e.type == EventType.ADVERT_PATH + ] + + assert len(advert_path_events) == 1 + + payload = advert_path_events[0].payload + assert payload["path_hash_mode"] == 2 + assert payload["path_len"] == 2 + assert payload["path"] == "12003456789a"