Skip to content

uppercase .LOCAL should be allowed #1746

Description

@bdraco
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

type_ = 'Localhost.LOCAL.'

    @lru_cache(maxsize=512)
    def service_type_name(type_: str, *, strict: bool = True) -> str:  # pylint: disable=too-many-branches
        """
        Validate a fully qualified service name, instance or subtype. [rfc6763]
    
        Returns fully qualified service name.
    
        Domain names used by mDNS-SD take the following forms:
    
                       <sn> . <_tcp|_udp> . local.
          <Instance> . <sn> . <_tcp|_udp> . local.
          <sub>._sub . <sn> . <_tcp|_udp> . local.
    
        1) must end with 'local.'
    
          This is true because we are implementing mDNS and since the 'm' means
          multi-cast, the 'local.' domain is mandatory.
    
        2) local is preceded with either '_udp.' or '_tcp.' unless
           strict is False
    
        3) service name <sn> precedes <_tcp|_udp> unless
           strict is False
    
          The rules for Service Names [RFC6335] state that they may be no more
          than fifteen characters long (not counting the mandatory underscore),
          consisting of only letters, digits, and hyphens, must begin and end
          with a letter or digit, must not contain consecutive hyphens, and
          must contain at least one letter.
    
        The instance name <Instance> and sub type <sub> may be up to 63 bytes.
    
        The portion of the Service Instance Name is a user-
        friendly name consisting of arbitrary Net-Unicode text [RFC5198]. It
        MUST NOT contain ASCII control characters (byte values 0x00-0x1F and
        0x7F) [RFC20] but otherwise is allowed to contain any characters,
        without restriction, including spaces, uppercase, lowercase,
        punctuation -- including dots -- accented characters, non-Roman text,
        and anything else that may be represented using Net-Unicode.
    
        :param type_: Type, SubType or service name to validate
        :return: fully qualified service name (eg: _http._tcp.local.)
        """
        if len(type_) > 256:
            # https://datatracker.ietf.org/doc/html/rfc6763#section-7.2
            raise BadTypeInNameException(f"Full name ({type_}) must be > 256 bytes")
    
        if type_.endswith((_TCP_PROTOCOL_LOCAL_TRAILER, _NONTCP_PROTOCOL_LOCAL_TRAILER)):
            remaining = type_[: -len(_TCP_PROTOCOL_LOCAL_TRAILER)].split(".")
            trailer = type_[-len(_TCP_PROTOCOL_LOCAL_TRAILER) :]
            has_protocol = True
        elif strict:
            raise BadTypeInNameException(
                f"Type '{type_}' must end with "
                f"'{_TCP_PROTOCOL_LOCAL_TRAILER}' or '{_NONTCP_PROTOCOL_LOCAL_TRAILER}'"
            )
        elif type_.endswith(_LOCAL_TRAILER):
            remaining = type_[: -len(_LOCAL_TRAILER)].split(".")
            trailer = type_[-len(_LOCAL_TRAILER) + 1 :]
            has_protocol = False
        else:
>           raise BadTypeInNameException(f"Type '{type_}' must end with '{_LOCAL_TRAILER}'")
E           zeroconf._exceptions.BadTypeInNameException: Type 'Localhost.LOCAL.' must end with '.local.'

strict     = False
type_      = 'Localhost.LOCAL.'

/opt/hostedtoolcache/Python/3.10.20/x64/lib/python3.10/site-packages/zeroconf/_utils/name.py:100: BadTypeInNameException
============================= slowest 10 durations =============================
0.20s call     tests/test_impl.py::test_exception_dns_before_result_async_dual_mdns_resolver
0.20s call     tests/test_impl.py::test_exception_mdns_before_result_async_dual_mdns_resolver
0.10s call     tests/test_impl.py::test_no_cancel_swallow_dual_mdns_resolver
0.01s call     tests/test_impl.py::test_resolve_localhost_with_async_mdns_resolver
0.01s setup    tests/test_api.py::test_api
0.01s setup    tests/test_impl.py::test_resolve_localhost_with_async_mdns_resolver

(4 durations < 0.005s hidden.  Use -vv to show these durations.)
=========================== short test summary info ============================
FAILED tests/test_impl.py::test_resolve_mdns_name_mixed_case - zeroconf._exceptions.BadTypeInNameException: Type 'Localhost.LOCAL.' must end with '.local.'
========================= 1 failed, 23 passed in 1.21s =========================

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions