From 1df19f7f976b1ebe75f12c765f4ca11fbc222565 Mon Sep 17 00:00:00 2001 From: cheatfate Date: Tue, 17 Oct 2023 04:25:48 +0300 Subject: [PATCH] Add character check and add tests. --- stint/io.nim | 25 ++++++---- tests/test_io.nim | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 10 deletions(-) diff --git a/stint/io.nim b/stint/io.nim index a01dcd9..6f9da9a 100644 --- a/stint/io.nim +++ b/stint/io.nim @@ -201,12 +201,16 @@ func readHexChar(c: char): int8 {.inline.}= else: raise newException(ValueError, $c & "is not a hexadecimal character") -func readStrictHexChar(c: char): Result[int8, cstring] {.raises: [], inline.} = +func readStrictHexChar(c: char, radix: static[uint8]): Result[int8, cstring] {. + raises: [], inline.} = ## Converts an hex char to an int + const + lowerLastChar = chr(ord('a') + radix - 11'u8) + capitalLastChar = chr(ord('A') + radix - 11'u8) case c - of '0'..'9': ok(int8 ord(c) - ord('0')) - of 'a'..'f': ok(int8 ord(c) - ord('a') + 10) - of 'A'..'F': ok(int8 ord(c) - ord('A') + 10) + of '0' .. '9': ok(int8 ord(c) - ord('0')) + of 'a' .. lowerLastChar: ok(int8 ord(c) - ord('a') + 10) + of 'A' .. capitalLastChar: ok(int8 ord(c) - ord('A') + 10) else: err("Invalid hexadecimal character encountered!") @@ -258,11 +262,12 @@ func readDecChar(c: range['0'..'9']): int {.inline.}= # specialization without branching for base <= 10. ord(c) - ord('0') -func readStrictDecChar(c: char): Result[int8, cstring] {.raises: [], inline.} = +func readStrictDecChar(c: char, radix: static[uint8]): Result[int8, cstring] {. + raises: [], inline.} = + const lastChar = char(ord('0') + radix - 1'u8) case c - of '0'..'9': ok(int8 ord(c) - ord('0')) - else: - err("Invalid decimal character encountered!") + of '0' .. lastChar: ok(int8 ord(c) - ord('0')) + else: err("Invalid decimal character encountered!") func strictParse*[bits: static[int]](input: string, T: typedesc[StUint[bits]], @@ -286,9 +291,9 @@ func strictParse*[bits: static[int]](input: string, while currentIndex < len(input): let value = when radix <= 10: - ? readStrictDecChar(input[currentIndex]) + ? readStrictDecChar(input[currentIndex], radix) else: - ? readStrictHexChar(input[currentIndex]) + ? readStrictHexChar(input[currentIndex], radix) let mres = res * base if (res != zero) and (mres div base != res): return err("Overflow error") diff --git a/tests/test_io.nim b/tests/test_io.nim index 687f035..e328f15 100644 --- a/tests/test_io.nim +++ b/tests/test_io.nim @@ -962,6 +962,130 @@ proc main() = expect(AssertionDefect): discard parse(s, StUint[256], 10) + test "strictParse() test": + const + GoodVectors16 = [ + ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + ("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + ("0x123456789ABCDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "123456789abcdefffffffffffffffffffffffffffffffffffffffffffffffff"), + ("123456789ABCDEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "123456789abcdefffffffffffffffffffffffffffffffffffffffffffffffff") + ] + GoodVectors10 = [ + ("115792089237316195423570985008687907853269984665640564039457584007913129639935", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + ("0", "0"), + ] + GoodVectors8 = [ + ("0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777777", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + ] + GoodVectors2 = [ + ("0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") + ] + OverflowVectors16 = [ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" + ] + OverflowVectors10 = [ + "1157920892373161954235709850086879078532699846656405640394575840079131296399350", + "1157920892373161954235709850086879078532699846656405640394575840079131296399351" + ] + OverflowVectors8 = [ + "0o177777777777777777777777777777777777777777777777777777777777777777777777777777777777770", + "0o177777777777777777777777777777777777777777777777777777777777777777777777777777777777777" + ] + OverflowVectors2 = [ + "0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110", + "0b11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" + ] + InvalidCharsVectors16 = [ + "GFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0xGFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0x0123456789ABCDEFZFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0123456789ABCDEFXFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + ] + InvalidCharsVectors10 = [ + "11579208923731619542357098500868790785326998466564056403945758400791312963993A", + "K" + ] + InvalidCharsVectors8 = [ + "0o17777777777777777777777777777777777777777777777777777777777777777777777777777777777778" + ] + InvalidCharsVectors2 = [ + "0b1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112" + ] + + for vector in GoodVectors16: + let res = strictParse(vector[0], UInt256, 16) + check: + res.isOk() + res.get().toHex() == vector[1] + + for vector in GoodVectors10: + let res = strictParse(vector[0], UInt256, 10) + check: + res.isOk() + res.get().toHex() == vector[1] + + for vector in GoodVectors8: + let res = strictParse(vector[0], UInt256, 8) + check: + res.isOk() + res.get().toHex() == vector[1] + + for vector in GoodVectors2: + let res = strictParse(vector[0], UInt256, 2) + check: + res.isOk() + res.get().toHex() == vector[1] + + for vector in OverflowVectors16: + let res = strictParse(vector, UInt256, 16) + check: + res.isErr() + res.error == "Overflow error" + + for vector in OverflowVectors10: + let res = strictParse(vector, UInt256, 10) + check: + res.isErr() + res.error == "Overflow error" + + for vector in OverflowVectors8: + let res = strictParse(vector, UInt256, 8) + check: + res.isErr() + res.error == "Overflow error" + + for vector in OverflowVectors2: + let res = strictParse(vector, UInt256, 2) + check: + res.isErr() + res.error == "Overflow error" + + for vector in InvalidCharsVectors16: + let res = strictParse(vector, UInt256, 16) + check res.isErr() + + for vector in InvalidCharsVectors10: + let res = strictParse(vector, UInt256, 10) + check res.isErr() + + for vector in InvalidCharsVectors8: + let res = strictParse(vector, UInt256, 8) + check res.isErr() + + for vector in InvalidCharsVectors2: + let res = strictParse(vector, UInt256, 2) + check res.isErr() + suite "Testing conversion functions: Hex, Bytes, Endianness using secp256k1 curve": let