From 87ccf8e66be333f0e013142da54836a468007e28 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Thu, 9 Apr 2020 11:20:21 +0200 Subject: [PATCH] hex byte: raise instead of assert on hex-to-byte odd lengths --- stew/byteutils.nim | 13 ++++++++----- tests/test_byteutils.nim | 11 ++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/stew/byteutils.nim b/stew/byteutils.nim index a1e08ba..d9e963e 100644 --- a/stew/byteutils.nim +++ b/stew/byteutils.nim @@ -51,7 +51,7 @@ proc readHexChar*(c: char): byte {.noSideEffect, inline.}= template skip0xPrefix(hexStr: string): int = ## Returns the index of the first meaningful char in `hexStr` by skipping ## "0x" prefix - if hexStr[0] == '0' and hexStr[1] in {'x', 'X'}: 2 + if hexStr.len > 1 and hexStr[0] == '0' and hexStr[1] in {'x', 'X'}: 2 else: 0 func hexToByteArray*(hexStr: string, output: var openArray[byte], fromIdx, toIdx: int) = @@ -62,8 +62,8 @@ func hexToByteArray*(hexStr: string, output: var openArray[byte], fromIdx, toIdx doAssert(fromIdx >= 0 and toIdx >= fromIdx and fromIdx < output.len and toIdx < output.len) let sz = toIdx - fromIdx + 1 - doAssert hexStr.len - sIdx >= 2*sz - + if hexStr.len - sIdx < 2*sz: + raise (ref ValueError)(msg: "hex string too short") sIdx += fromIdx * 2 for bIdx in fromIdx ..< sz + fromIdx: output[bIdx] = hexStr[sIdx].readHexChar shl 4 or hexStr[sIdx + 1].readHexChar @@ -89,7 +89,9 @@ func hexToPaddedByteArray*[N: static[int]](hexStr: string): array[N, byte] = bIdx: int shift = 4 - doAssert hexStr.len - p <= maxStrSize + if hexStr.len - p > maxStrSize: + # TODO this is a bit strange, compared to the hexToByteArray above... + raise (ref ValueError)(msg: "hex string too long") if sz < maxStrSize: # include extra byte if odd length @@ -105,7 +107,8 @@ func hexToPaddedByteArray*[N: static[int]](hexStr: string): array[N, byte] = func hexToSeqByte*(hexStr: string): seq[byte] = ## Read an hex string and store it in a sequence of bytes. No "endianness" reordering is done. - doAssert (hexStr.len and 1) == 0 + if (hexStr.len and 1) == 1: + raise (ref ValueError)(msg: "hex string must have even length") let skip = skip0xPrefix(hexStr) let N = (hexStr.len - skip) div 2 diff --git a/tests/test_byteutils.nim b/tests/test_byteutils.nim index 370c5b5..726032d 100644 --- a/tests/test_byteutils.nim +++ b/tests/test_byteutils.nim @@ -33,8 +33,17 @@ suite "Byte utils": a = hexToByteArray[4](s) check a == simpleBArray + expect(ValueError): discard hexToByteArray[1]("") + expect(ValueError): discard hexToByteArray[1]("1") + test "toHex": check simpleBArray.toHex == "12345678" + check hexToSeqByte("12345678") == simpleBArray + check hexToSeqByte("00") == [byte 0] + check hexToSeqByte("0x") == [] + expect(ValueError): discard hexToSeqByte("1234567") + expect(ValueError): discard hexToSeqByte("X") + expect(ValueError): discard hexToSeqByte("0") test "Array concatenation": check simpleBArray & simpleBArray == @@ -57,7 +66,7 @@ suite "Byte utils": let a = hexToPaddedByteArray[32]("0x68656c6c6f20776f726c64") check a.toHex == "00000000000000000000000000000000000000000068656c6c6f20776f726c64" block: - expect AssertionError: + expect ValueError: discard hexToPaddedByteArray[2]("0x12345") test "lessThan":