From f1d85a6d841ac113326ab0113ab8e8741ed4974e Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Wed, 1 Dec 2021 17:16:40 +0100 Subject: [PATCH] Fail gracefully when decoding range fails --- contractabi/decoding.nim | 16 ++++++++++++++++ tests/contractabi/testDecoding.nim | 6 +++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/contractabi/decoding.nim b/contractabi/decoding.nim index 6e876e0..bc1a234 100644 --- a/contractabi/decoding.nim +++ b/contractabi/decoding.nim @@ -71,6 +71,22 @@ func read(decoder: var AbiDecoder, amount: int, padding=padLeft): ?!seq[byte] = func decode(decoder: var AbiDecoder, T: type UInt): ?!T = success T.fromBytesBE(?decoder.read(sizeof(T))) +template basetype(Range: type range): untyped = + when Range isnot SomeUnsignedInt: {.error: "only uint ranges supported".} + elif sizeof(Range) == sizeof(uint8): uint8 + elif sizeof(Range) == sizeof(uint16): uint16 + elif sizeof(Range) == sizeof(uint32): uint32 + elif sizeof(Range) == sizeof(uint64): uint64 + else: {.error "unsupported range type".} + +func decode(decoder: var AbiDecoder, T: type range): ?!T = + let bytes = ?decoder.read(sizeof(T)) + let value = basetype(T).fromBytesBE(bytes) + if value in T.low..T.high: + success T(value) + else: + failure "value not in range" + func decode(decoder: var AbiDecoder, T: type bool): ?!T = case ?decoder.read(uint8) of 0: success false diff --git a/tests/contractabi/testDecoding.nim b/tests/contractabi/testDecoding.nim index 7384cd1..1ba9dbd 100644 --- a/tests/contractabi/testDecoding.nim +++ b/tests/contractabi/testDecoding.nim @@ -52,7 +52,11 @@ suite "ABI decoding": checkDecode(SomeRange.low) checkDecode(SomeRange.high) - # TODO: failure to decode when value not in range + test "fails to decode when value not in range": + type SomeRange = range[0x0000'u16..0xAAAA'u16] + let encoded = AbiEncoder.encode(0xFFFF'u16) + let decoded = AbiDecoder.decode(encoded, SomeRange) + check decoded.error.msg == "value not in range" test "decodes enums": type SomeEnum = enum