Skip to content

Commit 15bfb5f

Browse files
ajdavisgvanrossum
authored andcommitted
Don't use getservbyname for non-numeric ports. (python#437)
Fixes python#422.
1 parent 51dabc4 commit 15bfb5f

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed

asyncio/base_events.py

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,24 +115,16 @@ def _ipaddr_info(host, port, family, type, proto):
115115

116116
if port is None:
117117
port = 0
118-
elif isinstance(port, bytes):
119-
if port == b'':
120-
port = 0
121-
else:
122-
try:
123-
port = int(port)
124-
except ValueError:
125-
# Might be a service name like b"http".
126-
port = socket.getservbyname(port.decode('ascii'))
127-
elif isinstance(port, str):
128-
if port == '':
129-
port = 0
130-
else:
131-
try:
132-
port = int(port)
133-
except ValueError:
134-
# Might be a service name like "http".
135-
port = socket.getservbyname(port)
118+
elif isinstance(port, bytes) and port == b'':
119+
port = 0
120+
elif isinstance(port, str) and port == '':
121+
port = 0
122+
else:
123+
# If port's a service name like "http", don't skip getaddrinfo.
124+
try:
125+
port = int(port)
126+
except (TypeError, ValueError):
127+
return None
136128

137129
if family == socket.AF_UNSPEC:
138130
afs = [socket.AF_INET, socket.AF_INET6]

tests/test_base_events.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -142,26 +142,6 @@ def test_port_parameter_types(self):
142142
(INET, STREAM, TCP, '', ('1.2.3.4', 1)),
143143
base_events._ipaddr_info('1.2.3.4', b'1', INET, STREAM, TCP))
144144

145-
def test_getaddrinfo_servname(self):
146-
INET = socket.AF_INET
147-
STREAM = socket.SOCK_STREAM
148-
TCP = socket.IPPROTO_TCP
149-
150-
self.assertEqual(
151-
(INET, STREAM, TCP, '', ('1.2.3.4', 80)),
152-
base_events._ipaddr_info('1.2.3.4', 'http', INET, STREAM, TCP))
153-
154-
self.assertEqual(
155-
(INET, STREAM, TCP, '', ('1.2.3.4', 80)),
156-
base_events._ipaddr_info('1.2.3.4', b'http', INET, STREAM, TCP))
157-
158-
# Raises "service/proto not found".
159-
with self.assertRaises(OSError):
160-
base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
161-
162-
with self.assertRaises(OSError):
163-
base_events._ipaddr_info('1.2.3.4', 'nonsense', INET, STREAM, TCP)
164-
165145
@patch_socket
166146
def test_ipaddr_info_no_inet_pton(self, m_socket):
167147
del m_socket.inet_pton
@@ -1209,6 +1189,37 @@ def test_create_connection_ip_addr(self, m_socket):
12091189
def test_create_connection_no_inet_pton(self, m_socket):
12101190
self._test_create_connection_ip_addr(m_socket, False)
12111191

1192+
@patch_socket
1193+
def test_create_connection_service_name(self, m_socket):
1194+
m_socket.getaddrinfo = socket.getaddrinfo
1195+
sock = m_socket.socket.return_value
1196+
1197+
self.loop.add_reader = mock.Mock()
1198+
self.loop.add_reader._is_coroutine = False
1199+
self.loop.add_writer = mock.Mock()
1200+
self.loop.add_writer._is_coroutine = False
1201+
1202+
for service, port in ('http', 80), (b'http', 80):
1203+
coro = self.loop.create_connection(asyncio.Protocol,
1204+
'127.0.0.1', service)
1205+
1206+
t, p = self.loop.run_until_complete(coro)
1207+
try:
1208+
sock.connect.assert_called_with(('127.0.0.1', port))
1209+
_, kwargs = m_socket.socket.call_args
1210+
self.assertEqual(kwargs['family'], m_socket.AF_INET)
1211+
self.assertEqual(kwargs['type'], m_socket.SOCK_STREAM)
1212+
finally:
1213+
t.close()
1214+
test_utils.run_briefly(self.loop) # allow transport to close
1215+
1216+
for service in 'nonsense', b'nonsense':
1217+
coro = self.loop.create_connection(asyncio.Protocol,
1218+
'127.0.0.1', service)
1219+
1220+
with self.assertRaises(OSError):
1221+
self.loop.run_until_complete(coro)
1222+
12121223
def test_create_connection_no_local_addr(self):
12131224
@asyncio.coroutine
12141225
def getaddrinfo(host, *args, **kw):

0 commit comments

Comments
 (0)