diff --git a/tests/test_dns.py b/tests/test_dns.py index f61b1e8a..66da026b 100644 --- a/tests/test_dns.py +++ b/tests/test_dns.py @@ -31,13 +31,13 @@ def _test_getaddrinfo(self, *args, _patch=False, **kwargs): a1 = patched_getaddrinfo(*args, **kwargs) else: a1 = socket.getaddrinfo(*args, **kwargs) - except socket.gaierror as ex: + except (socket.gaierror, UnicodeError) as ex: err = ex try: a2 = self.loop.run_until_complete( self.loop.getaddrinfo(*args, **kwargs)) - except socket.gaierror as ex: + except (socket.gaierror, UnicodeError) as ex: if err is not None: self.assertEqual(ex.args, err.args) else: @@ -187,6 +187,18 @@ def test_getaddrinfo_20(self): self._test_getaddrinfo('127.0.0.1', 80, type=socket.SOCK_STREAM, flags=socket.AI_CANONNAME, _patch=patch) + # https://github.com/libuv/libuv/security/advisories/GHSA-f74f-cvh7-c6q6 + # See also: https://github.com/MagicStack/uvloop/pull/600 + def test_getaddrinfo_21(self): + payload = f'0x{"0" * 246}7f000001.example.com'.encode('ascii') + self._test_getaddrinfo(payload, 80) + self._test_getaddrinfo(payload, 80, type=socket.SOCK_STREAM) + + def test_getaddrinfo_22(self): + payload = f'0x{"0" * 246}7f000001.example.com' + self._test_getaddrinfo(payload, 80) + self._test_getaddrinfo(payload, 80, type=socket.SOCK_STREAM) + ###### def test_getnameinfo_1(self): diff --git a/uvloop/dns.pyx b/uvloop/dns.pyx index 7aad6319..c6be7cbe 100644 --- a/uvloop/dns.pyx +++ b/uvloop/dns.pyx @@ -348,6 +348,11 @@ cdef class AddrInfoRequest(UVRequest): if host is None: chost = NULL + elif host == b'' and sys.platform == 'darwin': + # It seems `getaddrinfo("", ...)` on macOS is equivalent to + # `getaddrinfo("localhost", ...)`. This is inconsistent with + # libuv 1.48 which treats empty nodename as EINVAL. + chost = 'localhost' else: chost = host @@ -356,13 +361,6 @@ cdef class AddrInfoRequest(UVRequest): else: cport = port - if cport is NULL and chost is NULL: - self.on_done() - msg = system.gai_strerror(socket_EAI_NONAME).decode('utf-8') - ex = socket_gaierror(socket_EAI_NONAME, msg) - callback(ex) - return - memset(&self.hints, 0, sizeof(system.addrinfo)) self.hints.ai_flags = flags self.hints.ai_family = family @@ -382,7 +380,17 @@ cdef class AddrInfoRequest(UVRequest): if err < 0: self.on_done() - callback(convert_error(err)) + try: + if err == uv.UV_EINVAL: + # Convert UV_EINVAL to EAI_NONAME to match libc behavior + msg = system.gai_strerror(socket_EAI_NONAME).decode('utf-8') + ex = socket_gaierror(socket_EAI_NONAME, msg) + else: + ex = convert_error(err) + except Exception as ex: + callback(ex) + else: + callback(ex) cdef class NameInfoRequest(UVRequest): diff --git a/vendor/libuv b/vendor/libuv index f0bb7e40..e9f29cb9 160000 --- a/vendor/libuv +++ b/vendor/libuv @@ -1 +1 @@ -Subproject commit f0bb7e40f0508bedf6fad33769b3f87bb8aedfa6 +Subproject commit e9f29cb984231524e3931aa0ae2c5dae1a32884e