bpo-39057: Fix urllib.request.proxy_bypass_environment(). (GH-17619)

Ignore leading dots and no longer ignore a trailing newline.
This commit is contained in:
Serhiy Storchaka 2020-01-05 14:14:31 +02:00 committed by GitHub
parent ec007cb43f
commit 6a265f0d0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 13 deletions

View File

@ -270,14 +270,36 @@ class ProxyTests(unittest.TestCase):
self.assertTrue(bypass('localhost')) self.assertTrue(bypass('localhost'))
self.assertTrue(bypass('LocalHost')) # MixedCase self.assertTrue(bypass('LocalHost')) # MixedCase
self.assertTrue(bypass('LOCALHOST')) # UPPERCASE self.assertTrue(bypass('LOCALHOST')) # UPPERCASE
self.assertTrue(bypass('.localhost'))
self.assertTrue(bypass('newdomain.com:1234')) self.assertTrue(bypass('newdomain.com:1234'))
self.assertTrue(bypass('.newdomain.com:1234'))
self.assertTrue(bypass('foo.d.o.t')) # issue 29142 self.assertTrue(bypass('foo.d.o.t')) # issue 29142
self.assertTrue(bypass('d.o.t'))
self.assertTrue(bypass('anotherdomain.com:8888')) self.assertTrue(bypass('anotherdomain.com:8888'))
self.assertTrue(bypass('.anotherdomain.com:8888'))
self.assertTrue(bypass('www.newdomain.com:1234')) self.assertTrue(bypass('www.newdomain.com:1234'))
self.assertFalse(bypass('prelocalhost')) self.assertFalse(bypass('prelocalhost'))
self.assertFalse(bypass('newdomain.com')) # no port self.assertFalse(bypass('newdomain.com')) # no port
self.assertFalse(bypass('newdomain.com:1235')) # wrong port self.assertFalse(bypass('newdomain.com:1235')) # wrong port
def test_proxy_bypass_environment_always_match(self):
bypass = urllib.request.proxy_bypass_environment
self.env.set('NO_PROXY', '*')
self.assertTrue(bypass('newdomain.com'))
self.assertTrue(bypass('newdomain.com:1234'))
self.env.set('NO_PROXY', '*, anotherdomain.com')
self.assertTrue(bypass('anotherdomain.com'))
self.assertFalse(bypass('newdomain.com'))
self.assertFalse(bypass('newdomain.com:1234'))
def test_proxy_bypass_environment_newline(self):
bypass = urllib.request.proxy_bypass_environment
self.env.set('NO_PROXY',
'localhost, anotherdomain.com, newdomain.com:1234')
self.assertFalse(bypass('localhost\n'))
self.assertFalse(bypass('anotherdomain.com:8888\n'))
self.assertFalse(bypass('newdomain.com:1234\n'))
class ProxyTests_withOrderedEnv(unittest.TestCase): class ProxyTests_withOrderedEnv(unittest.TestCase):

View File

@ -1056,9 +1056,9 @@ def _splitport(host):
"""splitport('host:port') --> 'host', 'port'.""" """splitport('host:port') --> 'host', 'port'."""
global _portprog global _portprog
if _portprog is None: if _portprog is None:
_portprog = re.compile('(.*):([0-9]*)$', re.DOTALL) _portprog = re.compile('(.*):([0-9]*)', re.DOTALL)
match = _portprog.match(host) match = _portprog.fullmatch(host)
if match: if match:
host, port = match.groups() host, port = match.groups()
if port: if port:

View File

@ -2492,24 +2492,26 @@ def proxy_bypass_environment(host, proxies=None):
try: try:
no_proxy = proxies['no'] no_proxy = proxies['no']
except KeyError: except KeyError:
return 0 return False
# '*' is special case for always bypass # '*' is special case for always bypass
if no_proxy == '*': if no_proxy == '*':
return 1 return True
host = host.lower()
# strip port off host # strip port off host
hostonly, port = _splitport(host) hostonly, port = _splitport(host)
# check if the host ends with any of the DNS suffixes # check if the host ends with any of the DNS suffixes
no_proxy_list = [proxy.strip() for proxy in no_proxy.split(',')] for name in no_proxy.split(','):
for name in no_proxy_list: name = name.strip()
if name: if name:
name = name.lstrip('.') # ignore leading dots name = name.lstrip('.') # ignore leading dots
name = re.escape(name) name = name.lower()
pattern = r'(.+\.)?%s$' % name if hostonly == name or host == name:
if (re.match(pattern, hostonly, re.I) return True
or re.match(pattern, host, re.I)): name = '.' + name
return 1 if hostonly.endswith(name) or host.endswith(name):
return True
# otherwise, don't bypass # otherwise, don't bypass
return 0 return False
# This code tests an OSX specific data structure but is testable on all # This code tests an OSX specific data structure but is testable on all
@ -2635,7 +2637,7 @@ elif os.name == 'nt':
for p in proxyServer.split(';'): for p in proxyServer.split(';'):
protocol, address = p.split('=', 1) protocol, address = p.split('=', 1)
# See if address has a type:// prefix # See if address has a type:// prefix
if not re.match('^([^/:]+)://', address): if not re.match('(?:[^/:]+)://', address):
address = '%s://%s' % (protocol, address) address = '%s://%s' % (protocol, address)
proxies[protocol] = address proxies[protocol] = address
else: else:

View File

@ -0,0 +1,2 @@
:func:`urllib.request.proxy_bypass_environment` now ignores leading dots and
no longer ignores a trailing newline.