Fix LibP2P varint implementation to follow latest specification. (#65)
* Fix LibP2P varint implementation to decode only minimal valus.
This commit is contained in:
parent
d42833947a
commit
d902127595
|
@ -21,6 +21,7 @@ type
|
||||||
Success,
|
Success,
|
||||||
Overflow,
|
Overflow,
|
||||||
Incomplete,
|
Incomplete,
|
||||||
|
Overlong,
|
||||||
Overrun
|
Overrun
|
||||||
|
|
||||||
PB* = object
|
PB* = object
|
||||||
|
@ -99,6 +100,13 @@ proc getUVarint*[T: PB|LP](vtype: typedesc[T],
|
||||||
outlen = 0
|
outlen = 0
|
||||||
outval = cast[type(outval)](0)
|
outval = cast[type(outval)](0)
|
||||||
|
|
||||||
|
when vtype is LP:
|
||||||
|
if result == VarintStatus.Success:
|
||||||
|
if outlen != vsizeof(outval):
|
||||||
|
outval = cast[type(outval)](0)
|
||||||
|
outlen = 0
|
||||||
|
result = VarintStatus.Overlong
|
||||||
|
|
||||||
proc putUVarint*[T: PB|LP](vtype: typedesc[T],
|
proc putUVarint*[T: PB|LP](vtype: typedesc[T],
|
||||||
pbytes: var openarray[byte],
|
pbytes: var openarray[byte],
|
||||||
outlen: var int,
|
outlen: var int,
|
||||||
|
@ -242,18 +250,3 @@ proc encodeVarint*(vtype: typedesc[LP],
|
||||||
result.setLen(outsize)
|
result.setLen(outsize)
|
||||||
else:
|
else:
|
||||||
raise newException(VarintError, "Error '" & $res & "'")
|
raise newException(VarintError, "Error '" & $res & "'")
|
||||||
|
|
||||||
proc decodeSVarint*(data: openarray[byte]): int {.inline.} =
|
|
||||||
## Decode signed integer from array ``data`` and return it as result.
|
|
||||||
var outsize = 0
|
|
||||||
let res = getSVarint(data, outsize, result)
|
|
||||||
if res != VarintStatus.Success:
|
|
||||||
raise newException(VarintError, "Error '" & $res & "'")
|
|
||||||
|
|
||||||
proc decodeUVarint*[T: PB|LP](vtype: typedesc[T],
|
|
||||||
data: openarray[byte]): uint {.inline.} =
|
|
||||||
## Decode unsigned integer from array ``data`` and return it as result.
|
|
||||||
var outsize = 0
|
|
||||||
let res = vtype.getUVarint(data, outsize, result)
|
|
||||||
if res != VarintStatus.Success:
|
|
||||||
raise newException(VarintError, "Error '" & $res & "'")
|
|
||||||
|
|
|
@ -216,3 +216,54 @@ suite "Variable integer test suite":
|
||||||
0x8000_0000_0000_0000'u64) == VarintStatus.Overflow
|
0x8000_0000_0000_0000'u64) == VarintStatus.Overflow
|
||||||
LP.putUVarint(buffer, length,
|
LP.putUVarint(buffer, length,
|
||||||
0xFFFF_FFFF_FFFF_FFFF'u64) == VarintStatus.Overflow
|
0xFFFF_FFFF_FFFF_FFFF'u64) == VarintStatus.Overflow
|
||||||
|
|
||||||
|
test "[LibP2P] Overlong values test":
|
||||||
|
const OverlongValues = [
|
||||||
|
# Zero bytes at the end
|
||||||
|
@[0x81'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8,
|
||||||
|
0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8,
|
||||||
|
0x80'u8, 0x00'u8],
|
||||||
|
# Zero bytes at the middle and zero byte at the end
|
||||||
|
@[0x81'u8, 0x80'u8, 0x81'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x81'u8,
|
||||||
|
0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8,
|
||||||
|
0x81'u8, 0x00'u8],
|
||||||
|
# Zero bytes at the middle and zero bytes at the end
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x80'u8, 0x80'u8, 0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x80'u8, 0x80'u8,
|
||||||
|
0x00'u8],
|
||||||
|
@[0x81'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x80'u8, 0x81'u8, 0x80'u8,
|
||||||
|
0x80'u8, 0x00'u8],
|
||||||
|
]
|
||||||
|
var length = 0
|
||||||
|
var value = 0'u64
|
||||||
|
|
||||||
|
for item in OverlongValues:
|
||||||
|
check:
|
||||||
|
LP.getUVarint(item, length, value) == VarintStatus.Overlong
|
||||||
|
length == 0
|
||||||
|
value == 0
|
||||||
|
|
||||||
|
# We still should be able to decode zero value
|
||||||
|
check:
|
||||||
|
LP.getUVarint(@[0x00'u8], length, value) == VarintStatus.Success
|
||||||
|
length == 1
|
||||||
|
value == 0
|
||||||
|
|
||||||
|
# But not overlonged zero value
|
||||||
|
check:
|
||||||
|
LP.getUVarint(@[0x80'u8, 0x00'u8], length, value) == VarintStatus.Overlong
|
||||||
|
length == 0
|
||||||
|
value == 0
|
||||||
|
|
Loading…
Reference in New Issue