Add character check and add tests.

This commit is contained in:
cheatfate 2023-10-17 04:25:48 +03:00
parent 923ee80009
commit 1df19f7f97
No known key found for this signature in database
GPG Key ID: 46ADD633A7201F95
2 changed files with 139 additions and 10 deletions

View File

@ -201,12 +201,16 @@ func readHexChar(c: char): int8 {.inline.}=
else: else:
raise newException(ValueError, $c & "is not a hexadecimal character") 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 ## Converts an hex char to an int
const
lowerLastChar = chr(ord('a') + radix - 11'u8)
capitalLastChar = chr(ord('A') + radix - 11'u8)
case c case c
of '0' .. '9': ok(int8 ord(c) - ord('0')) of '0' .. '9': ok(int8 ord(c) - ord('0'))
of 'a'..'f': ok(int8 ord(c) - ord('a') + 10) of 'a' .. lowerLastChar: ok(int8 ord(c) - ord('a') + 10)
of 'A'..'F': ok(int8 ord(c) - ord('A') + 10) of 'A' .. capitalLastChar: ok(int8 ord(c) - ord('A') + 10)
else: else:
err("Invalid hexadecimal character encountered!") err("Invalid hexadecimal character encountered!")
@ -258,11 +262,12 @@ func readDecChar(c: range['0'..'9']): int {.inline.}=
# specialization without branching for base <= 10. # specialization without branching for base <= 10.
ord(c) - ord('0') 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 case c
of '0'..'9': ok(int8 ord(c) - ord('0')) of '0' .. lastChar: ok(int8 ord(c) - ord('0'))
else: else: err("Invalid decimal character encountered!")
err("Invalid decimal character encountered!")
func strictParse*[bits: static[int]](input: string, func strictParse*[bits: static[int]](input: string,
T: typedesc[StUint[bits]], T: typedesc[StUint[bits]],
@ -286,9 +291,9 @@ func strictParse*[bits: static[int]](input: string,
while currentIndex < len(input): while currentIndex < len(input):
let value = let value =
when radix <= 10: when radix <= 10:
? readStrictDecChar(input[currentIndex]) ? readStrictDecChar(input[currentIndex], radix)
else: else:
? readStrictHexChar(input[currentIndex]) ? readStrictHexChar(input[currentIndex], radix)
let mres = res * base let mres = res * base
if (res != zero) and (mres div base != res): if (res != zero) and (mres div base != res):
return err("Overflow error") return err("Overflow error")

View File

@ -962,6 +962,130 @@ proc main() =
expect(AssertionDefect): expect(AssertionDefect):
discard parse(s, StUint[256], 10) 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": suite "Testing conversion functions: Hex, Bytes, Endianness using secp256k1 curve":
let let