pylibrlp

Python3 wrapper for librlp
git clone git://git.defalsify.org/pylibrlp.git
Log | Files | Refs | LICENSE

commit df88f8fb248331da05cfe7ba3dac3740c4a3ca8b
parent e30bcf1715477de22c3559380d21874ab73488c9
Author: nolash <dev@holbrook.no>
Date:   Mon, 12 Apr 2021 18:45:55 +0200

Avoid truncation of zeros in value assumption on deserializaton

Diffstat:
Drlpstream/decode.py | 60------------------------------------------------------------
Mrlpstream/encode.py | 4++--
Mtests/test_rlp_decoder.py | 20+++++++++++++++++++-
Mtests/test_rlp_encoder.py | 3+++
4 files changed, 24 insertions(+), 63 deletions(-)

diff --git a/rlpstream/decode.py b/rlpstream/decode.py @@ -1,60 +0,0 @@ -# standard imports -import logging -import ctypes - -# local imports -from . import ( - LIBRLP_RLP_MAX_LIST_DEPTH, - librlp, - ) - -logg = logging.getLogger().getChild(__name__) - - -class RLPDecoder: - - __nullptr = ctypes.POINTER(ctypes.c_void_p)() - - def __init__(self, buffer_size): - - class RLPDecoderBackend(ctypes.Structure): - - _fields_ = [ - ('buf', ctypes.POINTER(ctypes.c_char * buffer_size)), - ('alloc', ctypes.c_char), - ('depth', ctypes.c_int), - ('size', ctypes.c_int), - ('state', ctypes.c_int), - ('list_ptr', ctypes.POINTER(ctypes.POINTER(ctypes.c_char)) * LIBRLP_RLP_MAX_LIST_DEPTH), - ('ptr', ctypes.POINTER(ctypes.c_char)), - ] - - self.buffer_size = buffer_size - self.backend = RLPEncoderBackend() - self.encoder = ctypes.pointer(self.backend) - - - def __del__(self): - logg.debug('free') - librlp.rlp_free(self.encoder) - - - def encode_item(self, v): - if isinstance(v, list): - librlp.rlp_descend(self.encoder) - for e in v: - self.encode_item(e) - librlp.rlp_ascend(self.encoder) - - else: - b = (ctypes.c_char * len(v))(*v) - librlp.rlp_add(self.encoder, len(v), b) - - return self.backend.size - - - def encode(self, v): - librlp.rlp_init(self.encoder, self.buffer_size, self.__nullptr) - r = self.encode_item(v) - - return bytes(self.backend.buf.contents[:r]) diff --git a/rlpstream/encode.py b/rlpstream/encode.py @@ -89,7 +89,7 @@ class RLPEncoder: elif self.backend.state == RLPState.RLP_STRING: l = int(self.zl.contents.value) - b = self.buf.contents.value[:l] + b = self.buf.contents[:l] logg.debug('v {}'.format(b)) frame.append(b) @@ -118,4 +118,4 @@ class RLPEncoder: (frame, stack) = self.decode_item(frame, stack) l = self.backend.depth - return frame[0] + return frame diff --git a/tests/test_rlp_decoder.py b/tests/test_rlp_decoder.py @@ -26,7 +26,25 @@ class TestRlpDecoder(unittest.TestCase): def test_decode_single_string(self): b = b'\xc4\x83\x66\x6f\x6f' v = self.encoder.decode(b) - self.assertEqual(v, b'foo') + self.assertEqual(v, [b'foo']) + + + def test_decode_multiple_adjacent(self): + b = bytes.fromhex('f86801843b9aca008252089416cfb63467452ecf15e9d6ac48e9b4da628716c482040083666f6f26a0d825b2e797550c144f5e8acae452bd81e1947fdcbc3430240e44e967b82181f4a030856f4a51a8e9464b506490f4c7d391c386efe1134cabb546dfa4260f801c6a') + v = self.encoder.decode(b) + + t = [ + bytes.fromhex('01'), + bytes.fromhex('3b9aca00'), + bytes.fromhex('5208'), + bytes.fromhex('3102ac39709f178c0f5e87d05908609d8e09d820'), + bytes.fromhex('0400'), + bytes.fromhex('666f6f'), + bytes.fromhex('01'), + os.urandom(32), + os.urandom(32), + ] + self.assertEqual(v, t) if __name__ == '__main__': diff --git a/tests/test_rlp_encoder.py b/tests/test_rlp_encoder.py @@ -17,18 +17,21 @@ class TestRlpEncoder(unittest.TestCase): self.encoder = RLPEncoder(1024) + @unittest.skip('test') def test_encode_single_string(self): v = b'foo' b = self.encoder.encode(v) print(b.hex()) + @unittest.skip('test') def test_encode_single_list(self): v = [b'foo'] b = self.encoder.encode(v) print(b.hex()) + @unittest.skip('test') def test_encode_nested(self): v = [b'foo', [b'bar', b'baz']] b = self.encoder.encode(v)