Browse Source

transaction.BCDataStream: minor fixes

- fix read/write_boolean (though unused...)
- sanity check in read_bytes
hard-fail-on-bad-server-string
SomberNight 5 years ago
parent
commit
6937b87a7c
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 14
      electrum/tests/test_transaction.py
  2. 13
      electrum/transaction.py

14
electrum/tests/test_transaction.py

@ -55,6 +55,8 @@ class TestBCDataStream(ElectrumTestCase):
def test_bytes(self): def test_bytes(self):
s = transaction.BCDataStream() s = transaction.BCDataStream()
with self.assertRaises(transaction.SerializationError):
s.read_bytes(1)
s.write(b'foobar') s.write(b'foobar')
self.assertEqual(s.read_bytes(3), b'foo') self.assertEqual(s.read_bytes(3), b'foo')
self.assertEqual(s.read_bytes(2), b'ba') self.assertEqual(s.read_bytes(2), b'ba')
@ -64,6 +66,18 @@ class TestBCDataStream(ElectrumTestCase):
self.assertEqual(s.read_bytes(1), b'r') self.assertEqual(s.read_bytes(1), b'r')
self.assertEqual(s.read_bytes(0), b'') self.assertEqual(s.read_bytes(0), b'')
def test_bool(self):
s = transaction.BCDataStream()
s.write(b'f\x00\x00b')
self.assertTrue(s.read_boolean())
self.assertFalse(s.read_boolean())
self.assertFalse(s.read_boolean())
self.assertTrue(s.read_boolean())
s.write_boolean(True)
s.write_boolean(False)
self.assertEqual(b'\x01\x00', s.read_bytes(2))
self.assertFalse(s.can_read_more())
class TestTransaction(ElectrumTestCase): class TestTransaction(ElectrumTestCase):

13
electrum/transaction.py

@ -244,7 +244,8 @@ class BCDataStream(object):
self.input = None self.input = None
self.read_cursor = 0 self.read_cursor = 0
def write(self, _bytes): # Initialize with string of _bytes def write(self, _bytes: Union[bytes, bytearray]): # Initialize with string of _bytes
assert isinstance(_bytes, (bytes, bytearray))
if self.input is None: if self.input is None:
self.input = bytearray(_bytes) self.input = bytearray(_bytes)
else: else:
@ -271,12 +272,14 @@ class BCDataStream(object):
self.write_compact_size(len(string)) self.write_compact_size(len(string))
self.write(string) self.write(string)
def read_bytes(self, length) -> bytes: def read_bytes(self, length: int) -> bytes:
if self.input is None:
raise SerializationError("call write(bytes) before trying to deserialize")
assert length >= 0 assert length >= 0
input_len = len(self.input) input_len = len(self.input)
read_begin = self.read_cursor read_begin = self.read_cursor
read_end = read_begin + length read_end = read_begin + length
if 0 <= read_begin <= input_len and read_end <= input_len: if 0 <= read_begin <= read_end <= input_len:
result = self.input[read_begin:read_end] # type: bytearray result = self.input[read_begin:read_end] # type: bytearray
self.read_cursor += length self.read_cursor += length
return bytes(result) return bytes(result)
@ -288,7 +291,7 @@ class BCDataStream(object):
return False return False
return self.read_cursor < len(self.input) return self.read_cursor < len(self.input)
def read_boolean(self): return self.read_bytes(1)[0] != chr(0) def read_boolean(self) -> bool: return self.read_bytes(1) != b'\x00'
def read_int16(self): return self._read_num('<h') def read_int16(self): return self._read_num('<h')
def read_uint16(self): return self._read_num('<H') def read_uint16(self): return self._read_num('<H')
def read_int32(self): return self._read_num('<i') def read_int32(self): return self._read_num('<i')
@ -296,7 +299,7 @@ class BCDataStream(object):
def read_int64(self): return self._read_num('<q') def read_int64(self): return self._read_num('<q')
def read_uint64(self): return self._read_num('<Q') def read_uint64(self): return self._read_num('<Q')
def write_boolean(self, val): return self.write(chr(1) if val else chr(0)) def write_boolean(self, val): return self.write(b'\x01' if val else b'\x00')
def write_int16(self, val): return self._write_num('<h', val) def write_int16(self, val): return self._write_num('<h', val)
def write_uint16(self, val): return self._write_num('<H', val) def write_uint16(self, val): return self._write_num('<H', val)
def write_int32(self, val): return self._write_num('<i', val) def write_int32(self, val): return self._write_num('<i', val)

Loading…
Cancel
Save