From ce388d3783dfa8d43c0119d10a422fe47cf36cee Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 30 Aug 2021 19:49:45 +0100 Subject: [PATCH] Further simplify parsing. This also ensures that the encoding ends with a receiver value, not a type or length. Signed-off-by: Daira Hopwood --- unified_address.py | 49 ++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/unified_address.py b/unified_address.py index a1dec6a..f1cfcf4 100644 --- a/unified_address.py +++ b/unified_address.py @@ -54,39 +54,32 @@ def decode_unified(addr_str): assert suffix == padding(hrp) rest = decoded[:-16] - s = 0 result = {} while len(rest) > 0: - if s == 0: - (receiver_type, rest) = parse_compact_size(rest) - s = 1 - elif s == 1: - (receiver_len, rest) = parse_compact_size(rest) - expected_len = {0: 20, 1: 20, 2: 43, 3: 43}.get(receiver_type) - if expected_len is not None: - assert receiver_len == expected_len, "incorrect receiver length" - s = 2 - elif s == 2: - assert len(rest) >= receiver_len - (receiver, rest) = (rest[:receiver_len], rest[receiver_len:]) + (receiver_type, rest) = parse_compact_size(rest) + (receiver_len, rest) = parse_compact_size(rest) - if receiver_type == 0 or receiver_type == 1: - assert not ('transparent' in result), "duplicate transparent receiver detected" - assert len(receiver) == 20 - result['transparent'] = receiver - s = 0 + expected_len = {0: 20, 1: 20, 2: 43, 3: 43}.get(receiver_type) + if expected_len is not None: + assert receiver_len == expected_len, "incorrect receiver length" - elif receiver_type == 2: - assert not ('sapling' in result), "duplicate sapling receiver detected" - assert len(receiver) == 43 - result['sapling'] = receiver - s = 0 + assert len(rest) >= receiver_len + (receiver, rest) = (rest[:receiver_len], rest[receiver_len:]) - elif receiver_type == 3: - assert not ('orchard' in result), "duplicate orchard receiver detected" - assert len(receiver) == 43 - result['orchard'] = receiver - s = 0 + if receiver_type == 0 or receiver_type == 1: + assert not ('transparent' in result), "duplicate transparent receiver detected" + assert len(receiver) == 20 + result['transparent'] = receiver + + elif receiver_type == 2: + assert not ('sapling' in result), "duplicate sapling receiver detected" + assert len(receiver) == 43 + result['sapling'] = receiver + + elif receiver_type == 3: + assert not ('orchard' in result), "duplicate orchard receiver detected" + assert len(receiver) == 43 + result['orchard'] = receiver return result