Skip to content

Commit fe72524

Browse files
authored
Fix lookup of uppercase names in registry (#597)
- If the ServiceInfo was registered with an uppercase name and the query was for a lowercase name, it would not be found and vice-versa.
1 parent d2d8262 commit fe72524

3 files changed

Lines changed: 47 additions & 10 deletions

File tree

tests/services/test_registry.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,41 @@ def test_lookups(self):
4646
assert registry.get_infos_type(type_) == [info]
4747
assert registry.get_infos_server("ash-2.local.") == [info]
4848
assert registry.get_types() == [type_]
49+
50+
def test_lookups_upper_case_by_lower_case(self):
51+
type_ = "_test-SRVC-type._tcp.local."
52+
name = "Xxxyyy"
53+
registration_name = "%s.%s" % (name, type_)
54+
55+
desc = {'path': '/~paulsm/'}
56+
info = ServiceInfo(
57+
type_, registration_name, 80, 0, 0, desc, "ASH-2.local.", addresses=[socket.inet_aton("10.0.1.2")]
58+
)
59+
60+
registry = r.ServiceRegistry()
61+
registry.add(info)
62+
63+
assert registry.get_service_infos() == [info]
64+
assert registry.get_info_name(registration_name.lower()) == info
65+
assert registry.get_infos_type(type_.lower()) == [info]
66+
assert registry.get_infos_server("ash-2.local.") == [info]
67+
assert registry.get_types() == [type_.lower()]
68+
69+
def test_lookups_lower_case_by_upper_case(self):
70+
type_ = "_test-srvc-type._tcp.local."
71+
name = "xxxyyy"
72+
registration_name = "%s.%s" % (name, type_)
73+
74+
desc = {'path': '/~paulsm/'}
75+
info = ServiceInfo(
76+
type_, registration_name, 80, 0, 0, desc, "ash-2.local.", addresses=[socket.inet_aton("10.0.1.2")]
77+
)
78+
79+
registry = r.ServiceRegistry()
80+
registry.add(info)
81+
82+
assert registry.get_service_infos() == [info]
83+
assert registry.get_info_name(registration_name.upper()) == info
84+
assert registry.get_infos_type(type_.upper()) == [info]
85+
assert registry.get_infos_server("ASH-2.local.") == [info]
86+
assert registry.get_types() == [type_]

zeroconf/_handlers.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def _answer_service_type_enumeration_query(self, msg: DNSIncoming, out: DNSOutgo
7373

7474
def _answer_ptr_query(self, msg: DNSIncoming, out: DNSOutgoing, question: DNSQuestion) -> None:
7575
"""Answer a PTR query."""
76-
for service in self.registry.get_infos_type(question.name.lower()):
76+
for service in self.registry.get_infos_type(question.name):
7777
out.add_answer(msg, service.dns_pointer())
7878
# Add recommended additional answers according to
7979
# https://tools.ietf.org/html/rfc6763#section-12.1.
@@ -87,14 +87,13 @@ def _answer_non_ptr_query(self, msg: DNSIncoming, out: DNSOutgoing, question: DN
8787
8888
Add answer(s) for A, AAAA, SRV, or TXT queries.
8989
"""
90-
name_to_find = question.name.lower()
9190
# Answer A record queries for any service addresses we know
9291
if question.type in (_TYPE_A, _TYPE_ANY):
93-
for service in self.registry.get_infos_server(name_to_find):
92+
for service in self.registry.get_infos_server(question.name):
9493
for dns_address in service.dns_addresses():
9594
out.add_answer(msg, dns_address)
9695

97-
service = self.registry.get_info_name(name_to_find) # type: ignore
96+
service = self.registry.get_info_name(question.name) # type: ignore
9897
if service is None:
9998
return
10099

zeroconf/_services/registry.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def get_service_infos(self) -> List[ServiceInfo]:
7070

7171
def get_info_name(self, name: str) -> Optional[ServiceInfo]:
7272
"""Return all ServiceInfo for the name."""
73-
return self._services.get(name)
73+
return self._services.get(name.lower())
7474

7575
def get_types(self) -> List[str]:
7676
"""Return all types."""
@@ -88,7 +88,7 @@ def _get_by_index(self, attr: str, key: str) -> List[ServiceInfo]:
8888
"""Return all ServiceInfo matching the index."""
8989
service_infos = []
9090

91-
for name in getattr(self, attr).get(key, [])[:]:
91+
for name in getattr(self, attr).get(key.lower(), [])[:]:
9292
info = self._services.get(name)
9393
# Since we do not get under a lock since it would be
9494
# a performance issue, its possible
@@ -106,13 +106,13 @@ def _add(self, info: ServiceInfo) -> None:
106106
raise ServiceNameAlreadyRegistered
107107

108108
self._services[lower_name] = info
109-
self.types.setdefault(info.type, []).append(lower_name)
110-
self.servers.setdefault(info.server, []).append(lower_name)
109+
self.types.setdefault(info.type.lower(), []).append(lower_name)
110+
self.servers.setdefault(info.server.lower(), []).append(lower_name)
111111

112112
def _remove(self, info: ServiceInfo) -> None:
113113
"""Remove a service under the lock."""
114114
lower_name = info.name.lower()
115115
old_service_info = self._services[lower_name]
116-
self.types[old_service_info.type].remove(lower_name)
117-
self.servers[old_service_info.server].remove(lower_name)
116+
self.types[old_service_info.type.lower()].remove(lower_name)
117+
self.servers[old_service_info.server.lower()].remove(lower_name)
118118
del self._services[lower_name]

0 commit comments

Comments
 (0)