Skip to content

Commit e17dea1

Browse files
fix(crypto_addresses): correct testnet segwit prefix and reject non-hex ETH
Two correctness bugs in the crypto address validators: btc_address: the segwit branch is taken when the value starts with "bc" or "tb", but the regexp only matched "bc" or "tc". Every valid testnet bech32 address (tb1...) was therefore rejected. Correct the prefix to "tb". eth_address: _validate_eth_checksum_address only checked the length of the stripped address, not that its characters were hexadecimal. Inputs made of non-hex, caseless characters (e.g. "0x" + "*" * 40) passed the checksum loop vacuously and were accepted as valid. Require 40 hex digits before running the checksum. Existing fixtures are unchanged; added testnet bech32 addresses and a non-hex input as regression tests.
1 parent 70de324 commit e17dea1

4 files changed

Lines changed: 9 additions & 3 deletions

File tree

src/validators/crypto_addresses/btc_address.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def btc_address(value: str, /):
5050

5151
return (
5252
# segwit pattern
53-
re.compile(r"^(bc|tc)[0-3][02-9ac-hj-np-z]{14,74}$").match(value)
53+
re.compile(r"^(bc|tb)[0-3][02-9ac-hj-np-z]{14,74}$").match(value)
5454
if value[:2] in ("bc", "tb")
5555
else _validate_old_btc_address(value)
5656
)

src/validators/crypto_addresses/eth_address.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
def _validate_eth_checksum_address(addr: str):
1818
"""Validate ETH type checksum address."""
1919
addr = addr.replace("0x", "")
20-
addr_hash = keccak.new(addr.lower().encode("ascii")).digest().hex() # type: ignore
2120

22-
if len(addr) != 40:
21+
if not re.fullmatch(r"[0-9a-fA-F]{40}", addr):
2322
return False
2423

24+
addr_hash = keccak.new(addr.lower().encode("ascii")).digest().hex() # type: ignore
25+
2526
for i in range(0, 40):
2627
if (int(addr_hash[i], 16) > 7 and addr[i].upper() != addr[i]) or (
2728
int(addr_hash[i], 16) <= 7 and addr[i].lower() != addr[i]

tests/crypto_addresses/test_btc_address.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
# Bech32/segwit type
1818
"bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
1919
"bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9",
20+
# Bech32/segwit testnet (tb prefix)
21+
"tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx",
22+
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3",
2023
],
2124
)
2225
def test_returns_true_on_valid_btc_address(value: str):

tests/crypto_addresses/test_eth_address.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ def test_returns_true_on_valid_eth_address(value: str):
3737
"0x7c8EE9977c6f96b6b9774b3e8e4Cc9B93B12b2c",
3838
"0x7Fb21a171205f3B8d8E4d88A2d2f8A56E45DdB5c",
3939
"validators.eth",
40+
# non-hex characters (the checksum path used to accept these)
41+
"0x" + "*" * 40,
4042
],
4143
)
4244
def test_returns_failed_validation_on_invalid_eth_address(value: str):

0 commit comments

Comments
 (0)