tbitcoin.py: make int_to_hex throw on overflow - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 1a8e8bc047bc6cd124b338e9c69c3bbb561db54a DIR parent 79f4a8bae970b8581dc069934d7ae6a390c79c90 HTML Author: SomberNight <somber.night@protonmail.com> Date: Sat, 16 Jun 2018 02:34:27 +0200 bitcoin.py: make int_to_hex throw on overflow Diffstat: M lib/bitcoin.py | 10 ++++++++-- M lib/tests/test_bitcoin.py | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) --- DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py t@@ -50,12 +50,18 @@ def rev_hex(s): return bh2u(bfh(s)[::-1]) -def int_to_hex(i, length=1): +def int_to_hex(i: int, length: int=1) -> str: + """Converts int to little-endian hex string. + `length` is the number of bytes available + """ if not isinstance(i, int): raise TypeError('{} instead of int'.format(i)) + range_size = pow(256, length) + if i < -range_size/2 or i >= range_size: + raise OverflowError('cannot convert int {} to hex ({} bytes)'.format(i, length)) if i < 0: # two's complement - i = pow(256, length) + i + i = range_size + i s = hex(i)[2:].rstrip('L') s = "0"*(2*length - len(s)) + s return rev_hex(s) DIR diff --git a/lib/tests/test_bitcoin.py b/lib/tests/test_bitcoin.py t@@ -12,7 +12,7 @@ from lib.bitcoin import ( deserialize_privkey, serialize_privkey, is_segwit_address, is_b58_address, address_to_scripthash, is_minikey, is_compressed, is_xpub, xpub_type, is_xprv, is_bip32_derivation, seed_type, EncodeBase58Check, - script_num_to_hex, push_script, add_number_to_script) + script_num_to_hex, push_script, add_number_to_script, int_to_hex) from lib import ecc, crypto, ecc_fast from lib.ecc import number_to_string, string_to_number from lib.transaction import opcodes t@@ -227,6 +227,26 @@ class Test_bitcoin(SequentialTestCase): result = Hash(payload) self.assertEqual(expected, result) + def test_int_to_hex(self): + self.assertEqual('00', int_to_hex(0, 1)) + self.assertEqual('ff', int_to_hex(-1, 1)) + self.assertEqual('00000000', int_to_hex(0, 4)) + self.assertEqual('01000000', int_to_hex(1, 4)) + self.assertEqual('7f', int_to_hex(127, 1)) + self.assertEqual('7f00', int_to_hex(127, 2)) + self.assertEqual('80', int_to_hex(128, 1)) + self.assertEqual('80', int_to_hex(-128, 1)) + self.assertEqual('8000', int_to_hex(128, 2)) + self.assertEqual('ff', int_to_hex(255, 1)) + self.assertEqual('ff7f', int_to_hex(32767, 2)) + self.assertEqual('0080', int_to_hex(-32768, 2)) + self.assertEqual('ffff', int_to_hex(65535, 2)) + with self.assertRaises(OverflowError): int_to_hex(256, 1) + with self.assertRaises(OverflowError): int_to_hex(-129, 1) + with self.assertRaises(OverflowError): int_to_hex(-257, 1) + with self.assertRaises(OverflowError): int_to_hex(65536, 2) + with self.assertRaises(OverflowError): int_to_hex(-32769, 2) + def test_var_int(self): for i in range(0xfd): self.assertEqual(var_int(i), "{:02x}".format(i) )