From 4ee16d0ff0cfec6c9a9db7811a79349c34c99aac Mon Sep 17 00:00:00 2001 From: SoorajDevadiga Date: Tue, 26 May 2026 18:57:07 +0530 Subject: [PATCH] Fix: recoverable diagnostics for truncated TLV value --- sigflow/parsers/tlv.py | 11 +++++++++++ tests/test_parsers.py | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/sigflow/parsers/tlv.py b/sigflow/parsers/tlv.py index c05746c..ae00549 100644 --- a/sigflow/parsers/tlv.py +++ b/sigflow/parsers/tlv.py @@ -14,16 +14,27 @@ def parse(self, data: bytes, context: ExecutionContext) -> list[Frame]: offset = 0 seq = 0 while offset < len(data): + # Need at least the TLV header (tag + length) if len(data) - offset < TLV.size: context.warn("tlv-truncated", "partial tlv header", offset) break + tag, length = TLV.unpack_from(data, offset) offset += TLV.size + if length > self.max_payload: context.warn("tlv-large", f"tag {tag} exceeds max payload", offset) break + + # If the TLV header is present, but the declared value bytes are truncated, + # downgrade to a recoverable diagnostic (consistent with BinaryFrameParser). + if offset + length > len(data): + context.warn("tlv-truncated", "truncated tlv value", offset) + break + value = self.require(data, offset, length) frames.append(Frame(tag, seq, value, metadata={"tag": tag})) seq += 1 offset += length return frames + diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 638db7a..68c0e50 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -2,6 +2,7 @@ from sigflow.core.context import ExecutionContext from sigflow.core.exceptions import ParseError from sigflow.parsers.binary import BinaryFrameParser +from sigflow.parsers.tlv import TLVParser def test_binary_parser_reads_frames(sample_stream): @@ -19,3 +20,16 @@ def test_binary_parser_reports_truncation(sample_stream): def test_invalid_magic_raises(): with pytest.raises(ParseError): BinaryFrameParser().parse(b"NOPE" + b"0" * 32, ExecutionContext({})) + + +def test_tlv_truncated_value_is_recoverable(): + # TLV format: >HH (tag, length) + # Provide header declaring length=4 but only 2 bytes for value. + data = b"\x00\x01" + b"\x00\x04" + b"AB" + ctx = ExecutionContext({}) + frames = TLVParser().parse(data, ctx) + + # No ParseError should be raised; parsing should stop and emit a diagnostic. + assert frames == [] + assert any(d.code == "tlv-truncated" for d in ctx.diagnostics) +