Skip to content

Commit

Permalink
testing/py3-furl: fix failing ipv6 tests
Browse files Browse the repository at this point in the history
Fix gruns/furl#164 by using
standard ipaddress library to detect valid and invalid IPs.
  • Loading branch information
zhangwenlong8911 authored and Celeste committed Jul 9, 2024
1 parent 8be9a64 commit d46a489
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
From 38252c55790f3684c90b411df8d1b6e9e83c9025 Mon Sep 17 00:00:00 2001
From: Wenlong Zhang <[email protected]>
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

6 changes: 4 additions & 2 deletions testing/py3-furl/APKBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pkgname=py3-furl
_pkgname=furl
pkgver=2.1.3
pkgrel=2
pkgrel=3
pkgdesc="Python3 URL manipulator"
url="https://github.com/gruns/furl"
arch="noarch"
Expand All @@ -12,7 +12,8 @@ depends="py3-orderedmultidict py3-six"
makedepends="py3-setuptools"
checkdepends="py3-pytest py3-flake8 py3-pycodestyle py3-pyflakes"
subpackages="$pkgname-pyc"
source="https://files.pythonhosted.org/packages/source/f/furl/furl-$pkgver.tar.gz"
source="https://files.pythonhosted.org/packages/source/f/furl/furl-$pkgver.tar.gz
0001-Use-ipaddress-to-detect-valid-and-invalid-IPs.patch"
builddir="$srcdir"/$_pkgname-$pkgver

build() {
Expand All @@ -29,4 +30,5 @@ package() {

sha512sums="
ce7455bd1a352243efd9715e80e9f9979631cc058927edcd8c52ccb85d27fd8f32079611bb29c487d2add2d1d941d56e4db75520339dc371b1539811ccefda02 furl-2.1.3.tar.gz
2c6fdb72b7b78a11b1999b2edc696e9eea4e8afa3d93c814aa5a0bda1c6b92abbffcc4eaaf024135f52f8194398675e50ff390eb2bf96c73cbe190501ee20a61 0001-Use-ipaddress-to-detect-valid-and-invalid-IPs.patch
"

0 comments on commit d46a489

Please sign in to comment.