From 17287069aac820fe01813fa673fb5227ae5dfc8b Mon Sep 17 00:00:00 2001 From: Max Chen Date: Sat, 1 Oct 2022 05:34:22 +0800 Subject: [PATCH] Fixed TLV decoder issue (#22948) * Fixed TLV decoder issue Fixed issue of the TLV decoder: When giving tlv_bytes = b"\0256\001\0255\001&\000\031\346x\2077\001$\002\001$\003\006$\004\000\030(\002\030\030\030\030", the following errors occur: Traceback (most recent call last): File "/home/chingtzuchen/exp/tlv2.py", line 743, in out = reader.get() File "/home/chingtzuchen/exp/tlv2.py", line 459, in get self._get(self._tlv, self._decodings, out) File "/home/chingtzuchen/exp/tlv2.py", line 674, in _get self._decodeVal(tlv, decoding) File "/home/chingtzuchen/exp/tlv2.py", line 574, in _decodeVal self._get(tlv, decoding["Structure"], decoding["value"]) File "/home/chingtzuchen/exp/tlv2.py", line 674, in _get self._decodeVal(tlv, decoding) File "/home/chingtzuchen/exp/tlv2.py", line 578, in _decodeVal self._get(tlv, decoding["Array"], decoding["value"]) File "/home/chingtzuchen/exp/tlv2.py", line 674, in _get self._decodeVal(tlv, decoding) File "/home/chingtzuchen/exp/tlv2.py", line 574, in _decodeVal self._get(tlv, decoding["Structure"], decoding["value"]) File "/home/chingtzuchen/exp/tlv2.py", line 674, in _get self._decodeVal(tlv, decoding) File "/home/chingtzuchen/exp/tlv2.py", line 574, in _decodeVal self._get(tlv, decoding["Structure"], decoding["value"]) File "/home/chingtzuchen/exp/tlv2.py", line 674, in _get self._decodeVal(tlv, decoding) File "/home/chingtzuchen/exp/tlv2.py", line 582, in _decodeVal self._get(tlv, decoding["Path"], decoding["value"]) File "/home/chingtzuchen/exp/tlv2.py", line 685, in _get out[decoding["tag"]] = decoding["value"] IndexError: list assignment index out of range Added condition and made it more clean to fix the issue, after this fix the bytes can be decoded: {'Any': {1: [{1: {'Any': 2272847385, 1: [1, 6, 0], 2: False}}]}} * Update __init__.py * Add unit test case Add unit test case for structure TLV bytes input Test result: ``` $ python test_tlv.py ..... ---------------------------------------------------------------------- Ran 5 tests in 0.000s OK ``` * Update test_tlv.py Update style --- src/controller/python/chip/tlv/__init__.py | 10 ++++------ src/controller/python/test/unit_tests/test_tlv.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/controller/python/chip/tlv/__init__.py b/src/controller/python/chip/tlv/__init__.py index 20f2bfebd2f2dd..5665c5e2a4f46b 100644 --- a/src/controller/python/chip/tlv/__init__.py +++ b/src/controller/python/chip/tlv/__init__.py @@ -680,13 +680,11 @@ def _get(self, tlv, decodings, out): if "profileTag" in list(decoding.keys()): out[decoding["profileTag"]] = decoding["value"] elif "tag" in list(decoding.keys()): - if decoding["tag"] is not None: - out[decoding["tag"]] = decoding["value"] + if isinstance(out, Mapping): + tag = decoding["tag"] if decoding["tag"] is not None else "Any" + out[tag] = decoding["value"] else: - if isinstance(out, Mapping): - out["Any"] = decoding["value"] - elif isinstance(out, Sequence): - out.append(decoding["value"]) + out.append(decoding["value"]) else: raise ValueError("Attempt to decode unsupported TLV tag") diff --git a/src/controller/python/test/unit_tests/test_tlv.py b/src/controller/python/test/unit_tests/test_tlv.py index 7e83f9c26863f2..901197b4ea4742 100644 --- a/src/controller/python/test/unit_tests/test_tlv.py +++ b/src/controller/python/test/unit_tests/test_tlv.py @@ -148,6 +148,18 @@ def test_uint(self): self._read_case([0b00000101, 0xab, 0xaa], tlvUint(0xaaab)) self._read_case([0b00000100, 0xab], tlvUint(0xab)) + def test_structure(self): + test_cases = [ + (b'\x15\x36\x01\x15\x35\x01\x26\x00\xBF\xA2\x55\x16\x37\x01\x24\x02\x00\x24\x03\x28\x24\x04\x00\x18\x24\x02\x01\x18\x18\x18\x18', + {1: [{1: {0: 374710975, 1: [0, 40, 0], 2: 1}}]}), + (b'\x156\x01\x155\x01&\x00\xBF\xA2U\x167\x01$\x02\x00$\x03($\x04\x01\x18,\x02\x18Nordic Semiconductor ASA\x18\x18\x18\x18', + {1: [{1: {0: 374710975, 1: [0, 40, 1], 2: 'Nordic Semiconductor ASA'}}]}), + (b"\0256\001\0255\001&\000\031\346x\2077\001$\002\001$\003\006$\004\000\030(\002\030\030\030\030", + {1: [{1: {0: 2272847385, 1: [1, 6, 0], 2: False}}]}) + ] + for tlv_bytes, answer in test_cases: + self._read_case(tlv_bytes, answer) + if __name__ == '__main__': unittest.main()