mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-04-12 13:46:41 +02:00
Fix https://github.com/gruns/furl/issues/164 by using standard ipaddress library to detect valid and invalid IPs.
147 lines
4.8 KiB
Diff
147 lines
4.8 KiB
Diff
From 38252c55790f3684c90b411df8d1b6e9e83c9025 Mon Sep 17 00:00:00 2001
|
|
From: Wenlong Zhang <zhangwenlong@loongson.cn>
|
|
Date: Thu, 4 Jul 2024 01:32:07 +0000
|
|
Subject: [PATCH] Use ipaddress to detect valid and invalid IPs
|
|
|
|
https://github.com/gruns/furl/pull/165
|
|
---
|
|
furl/furl.py | 45 ++++++++++++++++++++++++++++++++++++---------
|
|
setup.py | 1 +
|
|
tests/test_furl.py | 21 +++++++++++----------
|
|
3 files changed, 48 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/furl/furl.py b/furl/furl.py
|
|
index 3f1ce3b..1fffdf3 100755
|
|
--- a/furl/furl.py
|
|
+++ b/furl/furl.py
|
|
@@ -12,6 +12,7 @@
|
|
|
|
import re
|
|
import abc
|
|
+import ipaddress
|
|
import warnings
|
|
from copy import deepcopy
|
|
from posixpath import normpath
|
|
@@ -240,6 +241,35 @@ def is_valid_host(hostname):
|
|
|
|
return '' not in toks # Adjacent periods aren't allowed.
|
|
|
|
+def is_valid_ipv4(ip):
|
|
+ if isinstance(ip, six.binary_type):
|
|
+ ip = ip.decode()
|
|
+
|
|
+ try:
|
|
+ ipaddress.IPv4Address(ip)
|
|
+ return True
|
|
+ except ValueError:
|
|
+ return False
|
|
+
|
|
+
|
|
+def is_valid_ipv6(ip):
|
|
+ if isinstance(ip, six.binary_type):
|
|
+ ip = ip.decode()
|
|
+
|
|
+ # ipaddress handle IPs without brackets
|
|
+ if (
|
|
+ callable_attr(ip, 'startswith')
|
|
+ and callable_attr(ip, 'endswith')
|
|
+ and ip.startswith("[")
|
|
+ and ip.endswith("]")
|
|
+ ):
|
|
+ ip = ip[1:-1]
|
|
+
|
|
+ try:
|
|
+ ipaddress.IPv6Address(ip)
|
|
+ return True
|
|
+ except ValueError:
|
|
+ return False
|
|
|
|
def get_scheme(url):
|
|
if url.startswith(':'):
|
|
@@ -1434,15 +1464,12 @@ class furl(URLPathCompositionInterface, QueryCompositionInterface,
|
|
"""
|
|
Raises: ValueError on invalid host or malformed IPv6 address.
|
|
"""
|
|
- # Invalid IPv6 literal.
|
|
- urllib.parse.urlsplit('http://%s/' % host) # Raises ValueError.
|
|
-
|
|
- # Invalid host string.
|
|
- resembles_ipv6_literal = (
|
|
- host is not None and lget(host, 0) == '[' and ':' in host and
|
|
- lget(host, -1) == ']')
|
|
- if (host is not None and not resembles_ipv6_literal and
|
|
- not is_valid_host(host)):
|
|
+ if (
|
|
+ host
|
|
+ and not is_valid_host(host)
|
|
+ and not is_valid_ipv4(host)
|
|
+ and not is_valid_ipv6(host)
|
|
+ ):
|
|
errmsg = (
|
|
"Invalid host '%s'. Host strings must have at least one "
|
|
"non-period character, can't contain any of '%s', and can't "
|
|
diff --git a/setup.py b/setup.py
|
|
index 403d5ae..b223b34 100755
|
|
--- a/setup.py
|
|
+++ b/setup.py
|
|
@@ -109,6 +109,7 @@ setup(
|
|
install_requires=[
|
|
'six>=1.8.0',
|
|
'orderedmultidict>=1.0.1',
|
|
+ 'ipaddress>=1.0.23; python_version < "3.3"',
|
|
],
|
|
cmdclass={
|
|
'test': RunTests,
|
|
diff --git a/tests/test_furl.py b/tests/test_furl.py
|
|
index 27e4b55..cd37e2e 100755
|
|
--- a/tests/test_furl.py
|
|
+++ b/tests/test_furl.py
|
|
@@ -1666,10 +1666,10 @@ class TestFurl(unittest.TestCase):
|
|
# addresses.
|
|
f = furl.furl('http://1.2.3.4.5.6/')
|
|
|
|
- # Invalid, but well-formed, IPv6 addresses shouldn't raise an
|
|
- # exception because urlparse.urlsplit() doesn't raise an
|
|
- # exception on invalid IPv6 addresses.
|
|
- furl.furl('http://[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]/')
|
|
+ # Invalid, but well-formed, IPv6 addresses should raise an
|
|
+ # exception.
|
|
+ with self.assertRaises(ValueError):
|
|
+ furl.furl('http://[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]/')
|
|
|
|
# Malformed IPv6 should raise an exception because urlparse.urlsplit()
|
|
# raises an exception on malformed IPv6 addresses.
|
|
@@ -1695,12 +1695,17 @@ class TestFurl(unittest.TestCase):
|
|
assert f.host == '1.2.3.4.5.6'
|
|
assert f.port == 999
|
|
|
|
- netloc = '[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]:888'
|
|
+ netloc = '[1:2:3:4:5:6:7:8]:888'
|
|
f.netloc = netloc
|
|
assert f.netloc == netloc
|
|
- assert f.host == '[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]'
|
|
+ assert f.host == '[1:2:3:4:5:6:7:8]'
|
|
assert f.port == 888
|
|
|
|
+ # Well-formed but invalid IPv6 should raise an exception
|
|
+ netloc = '[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]:888'
|
|
+ with self.assertRaises(ValueError):
|
|
+ f.netloc = netloc
|
|
+
|
|
# Malformed IPv6 should raise an exception because
|
|
# urlparse.urlsplit() raises an exception
|
|
with self.assertRaises(ValueError):
|
|
@@ -1714,10 +1719,6 @@ class TestFurl(unittest.TestCase):
|
|
with self.assertRaises(ValueError):
|
|
f.netloc = 'pump2pump.org:777777777777'
|
|
|
|
- # No side effects.
|
|
- assert f.host == '[0:0:0:0:0:0:0:1:1:1:1:1:1:1:1:9999999999999]'
|
|
- assert f.port == 888
|
|
-
|
|
# Empty netloc.
|
|
f = furl.furl('//')
|
|
assert f.scheme is None and f.netloc == '' and f.url == '//'
|
|
--
|
|
2.45.2
|
|
|