Raise error on invalid labels in create_connection()
MODIFY
src/urllib3/util/connection.py
src/urllib3/util/connection.py
from __future__ import absolute_import
import socket
+
+from urllib3.exceptions import LocationParseError
+
from .wait import NoWayToWaitForSocketError, wait_for_read
from ..contrib import _appengine_environ
+from ..packages import six
def is_connection_dropped(conn): # Platform-specific
@@ -58,6 +62,13 @@ def create_connection(
# The original create_connection function always returns all records.
family = allowed_gai_family()
+ try:
+ host.encode("idna")
+ except UnicodeError:
+ return six.raise_from(
+ LocationParseError(u"'%s', label empty or too long" % host), None
+ )
+
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
sock = None

MODIFY
test/test_util.py
test/test_util.py
@@ -11,6 +11,7 @@ from mock import patch, Mock
import pytest
from urllib3 import add_stderr_logger, disable_warnings, util
+from urllib3.util.connection import create_connection
from urllib3.util.request import make_headers, rewind_body, _FAILEDTELL
from urllib3.util.response import assert_header_parsing
from urllib3.util.timeout import Timeout
@@ -796,6 +797,29 @@ class TestUtil(object):
header_msg.seek(0)
assert_header_parsing(client.parse_headers(header_msg))
+ @pytest.mark.parametrize("host", [".localhost", "...", "t" * 64])
+ def test_create_connection_with_invalid_idna_labels(self, host):
+ with pytest.raises(LocationParseError) as ctx:
+ create_connection((host, 80))
+ assert str(ctx.value) == "Failed to parse: '%s', label empty or too long" % host
+
+ @pytest.mark.parametrize(
+ "host",
+ [
+ "a.example.com",
+ "localhost.",
+ "[dead::beef]",
+ "[dead::beef%en5]",
+ "[dead::beef%en5.]",
+ ],
+ )
+ @patch("socket.getaddrinfo")
+ @patch("socket.socket")
+ def test_create_connection_with_valid_idna_labels(self, socket, getaddrinfo, host):
+ getaddrinfo.return_value = [(None, None, None, None, None)]
+ socket.return_value = Mock()
+ create_connection((host, 80))
+
class TestUtilSSL(object):
"""Test utils that use an SSL backend."""

Raise error on invalid labels in create_connection()