protobuf: properly implement signed types (fixes #249)
parent
b156ec9757
commit
df8c3da1a2
@ -0,0 +1,90 @@
|
||||
from io import BytesIO
|
||||
import pytest
|
||||
|
||||
from trezorlib import protobuf
|
||||
|
||||
|
||||
class PrimitiveMessage(protobuf.MessageType):
|
||||
FIELDS = {
|
||||
0: ("uvarint", protobuf.UVarintType, 0),
|
||||
1: ("svarint", protobuf.SVarintType, 0),
|
||||
2: ("bool", protobuf.BoolType, 0),
|
||||
3: ("bytes", protobuf.BytesType, 0),
|
||||
4: ("unicode", protobuf.UnicodeType, 0),
|
||||
}
|
||||
|
||||
|
||||
def load_uvarint(buffer):
|
||||
reader = BytesIO(buffer)
|
||||
return protobuf.load_uvarint(reader)
|
||||
|
||||
|
||||
def dump_uvarint(value):
|
||||
writer = BytesIO()
|
||||
protobuf.dump_uvarint(writer, value)
|
||||
return writer.getvalue()
|
||||
|
||||
|
||||
def test_dump_uvarint():
|
||||
assert dump_uvarint(0) == b'\x00'
|
||||
assert dump_uvarint(1) == b'\x01'
|
||||
assert dump_uvarint(0xff) == b'\xff\x01'
|
||||
assert dump_uvarint(123456) == b'\xc0\xc4\x07'
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
dump_uvarint(-1)
|
||||
|
||||
|
||||
def test_load_uvarint():
|
||||
assert load_uvarint(b'\x00') == 0
|
||||
assert load_uvarint(b'\x01') == 1
|
||||
assert load_uvarint(b'\xff\x01') == 0xff
|
||||
assert load_uvarint(b'\xc0\xc4\x07') == 123456
|
||||
|
||||
|
||||
def test_sint_uint():
|
||||
"""
|
||||
Protobuf interleaved signed encoding
|
||||
https://developers.google.com/protocol-buffers/docs/encoding#structure
|
||||
LSbit is sign, rest is shifted absolute value.
|
||||
Or, by example, you count like so: 0, -1, 1, -2, 2, -3 ...
|
||||
"""
|
||||
assert protobuf.sint_to_uint(0) == 0
|
||||
assert protobuf.uint_to_sint(0) == 0
|
||||
|
||||
assert protobuf.sint_to_uint(-1) == 1
|
||||
assert protobuf.sint_to_uint(1) == 2
|
||||
|
||||
assert protobuf.uint_to_sint(1) == -1
|
||||
assert protobuf.uint_to_sint(2) == 1
|
||||
|
||||
# roundtrip:
|
||||
assert protobuf.uint_to_sint(
|
||||
protobuf.sint_to_uint(1234567891011)
|
||||
) == 1234567891011
|
||||
assert protobuf.uint_to_sint(
|
||||
protobuf.sint_to_uint(- 2 ** 32)
|
||||
) == - 2 ** 32
|
||||
|
||||
|
||||
def test_simple_message():
|
||||
msg = PrimitiveMessage(
|
||||
uvarint=12345678910,
|
||||
svarint=-12345678910,
|
||||
bool=True,
|
||||
bytes=b'\xDE\xAD\xCA\xFE',
|
||||
unicode="Příliš žluťoučký kůň úpěl ďábelské ódy 😊",
|
||||
)
|
||||
|
||||
buf = BytesIO()
|
||||
|
||||
protobuf.dump_message(buf, msg)
|
||||
buf.seek(0)
|
||||
retr = protobuf.load_message(buf, PrimitiveMessage)
|
||||
|
||||
assert msg == retr
|
||||
assert retr.uvarint == 12345678910
|
||||
assert retr.svarint == -12345678910
|
||||
assert retr.bool is True
|
||||
assert retr.bytes == b'\xDE\xAD\xCA\xFE'
|
||||
assert retr.unicode == "Příliš žluťoučký kůň úpěl ďábelské ódy 😊"
|
Loading…
Reference in new issue