Merge pull request #3226 from SomberNight/tx_deser_exc

make tx deserialization more robust to ill-formed tx
This commit is contained in:
ThomasV 2017-11-06 12:48:46 +01:00 committed by GitHub
commit c7350809ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 22 deletions

View File

@ -2119,17 +2119,25 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
return self.tx_from_text(file_content)
def do_process_from_text(self):
from electrum.transaction import SerializationError
text = text_dialog(self, _('Input raw transaction'), _("Transaction:"), _("Load transaction"))
if not text:
return
tx = self.tx_from_text(text)
if tx:
self.show_transaction(tx)
try:
tx = self.tx_from_text(text)
if tx:
self.show_transaction(tx)
except SerializationError as e:
self.show_critical(_("Electrum was unable to deserialize the transaction:") + "\n" + str(e))
def do_process_from_file(self):
tx = self.read_tx_from_file()
if tx:
self.show_transaction(tx)
from electrum.transaction import SerializationError
try:
tx = self.read_tx_from_file()
if tx:
self.show_transaction(tx)
except SerializationError as e:
self.show_critical(_("Electrum was unable to deserialize the transaction:") + "\n" + str(e))
def do_process_from_txid(self):
from electrum import transaction

View File

@ -30,7 +30,7 @@ class TestBCDataStream(unittest.TestCase):
for v in values:
self.assertEqual(s.read_compact_size(), v)
with self.assertRaises(IndexError):
with self.assertRaises(transaction.SerializationError):
s.read_compact_size()
def test_string(self):

View File

@ -77,10 +77,7 @@ class BCDataStream(object):
if self.input is None:
raise SerializationError("call write(bytes) before trying to deserialize")
try:
length = self.read_compact_size()
except IndexError:
raise SerializationError("attempt to read past end of buffer")
length = self.read_compact_size()
return self.read_bytes(length).decode(encoding)
@ -117,15 +114,18 @@ class BCDataStream(object):
def write_uint64(self, val): return self._write_num('<Q', val)
def read_compact_size(self):
size = self.input[self.read_cursor]
self.read_cursor += 1
if size == 253:
size = self._read_num('<H')
elif size == 254:
size = self._read_num('<I')
elif size == 255:
size = self._read_num('<Q')
return size
try:
size = self.input[self.read_cursor]
self.read_cursor += 1
if size == 253:
size = self._read_num('<H')
elif size == 254:
size = self._read_num('<I')
elif size == 255:
size = self._read_num('<Q')
return size
except IndexError:
raise SerializationError("attempt to read past end of buffer")
def write_compact_size(self, size):
if size < 0:
@ -143,8 +143,11 @@ class BCDataStream(object):
self._write_num('<Q', size)
def _read_num(self, format):
(i,) = struct.unpack_from(format, self.input, self.read_cursor)
self.read_cursor += struct.calcsize(format)
try:
(i,) = struct.unpack_from(format, self.input, self.read_cursor)
self.read_cursor += struct.calcsize(format)
except Exception as e:
raise SerializationError(e)
return i
def _write_num(self, format, num):