diff --git a/ens/constants.py b/ens/constants.py index 8ee310bc28..89755a8751 100644 --- a/ens/constants.py +++ b/ens/constants.py @@ -7,6 +7,4 @@ EMPTY_SHA3_BYTES = b'\0' * 32 EMPTY_ADDR_HEX = '0x' + '00' * 20 -MIN_ETH_LABEL_LENGTH = 7 - REVERSE_REGISTRAR_DOMAIN = 'addr.reverse' diff --git a/ens/utils.py b/ens/utils.py index f420549cdb..ec10e4b5e2 100644 --- a/ens/utils.py +++ b/ens/utils.py @@ -14,11 +14,9 @@ AUCTION_START_GAS_CONSTANT, AUCTION_START_GAS_MARGINAL, EMPTY_SHA3_BYTES, - MIN_ETH_LABEL_LENGTH, REVERSE_REGISTRAR_DOMAIN, ) from ens.exceptions import ( - InvalidLabel, InvalidName, ) @@ -81,10 +79,11 @@ def normalize_name(name): return name elif isinstance(name, (bytes, bytearray)): name = name.decode('utf-8') + try: - return idna.decode(name, uts46=True, std3_rules=True) + return idna.uts46_remap(name, std3_rules=True) except idna.IDNAError as exc: - raise InvalidName("%s is an invalid name, because %s" % (name, exc)) from exc + raise InvalidName(f"{name} is an invalid name, because {exc}") from exc def is_valid_name(name): @@ -104,37 +103,6 @@ def is_valid_name(name): return False -def name_to_label(name, registrar): - name = normalize_name(name) - if '.' not in name: - label = name - else: - name_pieces = name.split('.') - registrar_pieces = registrar.split('.') - if len(name_pieces) != len(registrar_pieces) + 1: - raise ValueError( - "You must specify a label, like 'tickets' " - "or a fully-qualified name, like 'tickets.%s'" % registrar - ) - label, *label_registrar = name_pieces - if label_registrar != registrar_pieces: - raise ValueError("This interface only manages names under .%s " % registrar) - return label - - -def dot_eth_label(name): - """ - Convert from a name, like 'ethfinex.eth', to a label, like 'ethfinex' - If name is already a label, this should be a noop, except for converting to a string - and validating the name syntax. - """ - label = name_to_label(name, registrar='eth') - if len(label) < MIN_ETH_LABEL_LENGTH: - raise InvalidLabel('name %r is too short' % label) - else: - return label - - def to_utc_datetime(timestamp): if timestamp: return datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc) diff --git a/tests/conftest.py b/tests/conftest.py index a3fcb4bad0..a7cf695c10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,8 +11,6 @@ get_open_port, ) -pytest_plugins = ["pytest_ethereum.plugins"] - @pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity]) def address_conversion_func(request): diff --git a/tests/core/utilities/test_abi_is_encodable.py b/tests/core/utilities/test_abi_is_encodable.py index 8966f35127..af357fd657 100644 --- a/tests/core/utilities/test_abi_is_encodable.py +++ b/tests/core/utilities/test_abi_is_encodable.py @@ -34,9 +34,9 @@ ('dennisthepeasant.eth', 'address', True), # passes because eth_utils converts to bytes :/ ('autonomouscollective.eth', 'address', True), ('all-TLDs-valid-now.test', 'address', True), - ('-rejects-invalid-names.test', 'address', False), ('ff', 'address', True), # this could theoretically be a top-level domain (TLD) ('0xname.eth', 'address', True), # 0x in name is fine, if it is not a TLD + ('rejects_invalid_names.eth', 'address', False), # no underscore in domain names # Special bytes behavior ('12', 'bytes2', True), # undersize OK @@ -66,7 +66,7 @@ (('1', 0), '(bytes,int128)', False), (('dennisthepeasant.eth', 0), '(address,int128)', True), - (('-rejects-invalid-names.test', 0), '(address,int128)', False), + (('rejects_invalid_domains.eth', 0), '(address,int128)', False), ((b'anything', 0), '(string,int128)', True), ((b'\x80', 0), '(string,int128)', False), diff --git a/tests/ens/test_nameprep.py b/tests/ens/test_nameprep.py index caa74316bf..4ef7ef2608 100644 --- a/tests/ens/test_nameprep.py +++ b/tests/ens/test_nameprep.py @@ -12,12 +12,25 @@ def test_nameprep_basic_unicode(ens): assert ens.nameprep("öbb.at") == "öbb.at" assert ens.nameprep("Öbb.at") == "öbb.at" assert ens.nameprep("O\u0308bb.at") == "öbb.at" - assert ens.nameprep("xn--bb-eka.at") == "öbb.at" assert ens.nameprep("faß.de") == "faß.de" assert ens.nameprep("fass.de") == "fass.de" - assert ens.nameprep("xn--fa-hia.de") == "faß.de" + assert ens.nameprep("🌈rainbow.eth") == "🌈rainbow.eth" + assert ens.nameprep("🐔🐔.tk") == "🐔🐔.tk" + assert ens.nameprep("√.com") == "√.com" + assert ens.nameprep("ԛәлп.com") == "ԛәлп.com" + assert ens.nameprep("test\u200btest.com") == "testtest.com" + assert ens.nameprep("-test.com") == "-test.com" + assert ens.nameprep("1test.com") == "1test.com" + assert ens.nameprep("test.1com") == "test.1com" -def test_nameprep_std3_rules(ens): - with pytest.raises(InvalidName): - ens.nameprep("not=std3") +@pytest.mark.parametrize( + 'url', [ + ('not=std3'), + ('not_std3.eth'), # underscores not allowed + ] +) +def test_nameprep_std3_rules(ens, url): + with pytest.raises(InvalidName, + match=f'{url} is an invalid name'): + ens.nameprep(url)