From 149159d19334fe5f7c1b553e8f6c92a8e3f04385 Mon Sep 17 00:00:00 2001 From: Alex Vandiver Date: Wed, 7 Apr 2021 13:11:15 -0700 Subject: [PATCH] is_valid_ip: Do not raise exceptions on too-long input. is_valid_ip calls `socket.getaddrinfo` with `socket.AI_NUMERICHOST` on the potential "ip"; even though IP addresses are not hostnames and do not use the `idna` encoding, `socket.getaddrinfo` will raise UnicodeError if the potential "ip" is longer than 63 characters long, the RFC-mandated max hostname length. Catch these UnicodeErrors and return false for too-long IPs, rather than raising an exception. --- tornado/netutil.py | 6 ++++++ tornado/test/netutil_test.py | 1 + 2 files changed, 7 insertions(+) diff --git a/tornado/netutil.py b/tornado/netutil.py index f8a303805..15eea9704 100644 --- a/tornado/netutil.py +++ b/tornado/netutil.py @@ -301,6 +301,12 @@ def is_valid_ip(ip: str) -> bool: if e.args[0] == socket.EAI_NONAME: return False raise + except UnicodeError: + # `socket.getaddrinfo` will raise a UnicodeError from the + # `idna` decoder if the input is longer than 63 characters, + # even for socket.AI_NUMERICHOST. See + # https://bugs.python.org/issue32958 for discussion + return False return True diff --git a/tornado/test/netutil_test.py b/tornado/test/netutil_test.py index f36b7c271..3911be6a2 100644 --- a/tornado/test/netutil_test.py +++ b/tornado/test/netutil_test.py @@ -204,6 +204,7 @@ class IsValidIPTest(unittest.TestCase): self.assertTrue(not is_valid_ip(" ")) self.assertTrue(not is_valid_ip("\n")) self.assertTrue(not is_valid_ip("\x00")) + self.assertTrue(not is_valid_ip("a" * 100)) class TestPortAllocation(unittest.TestCase): -- 2.47.2