Skip to content

Commit eadbb22

Browse files
committed
fix: removes 64-char limit for url path & query
- removes IDNA 64-char limit for url path & query - validates absurd quoted url: `http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com` - updates dependencies and changelog - bumps patch version **Related items** *Issues* - Closes #257
1 parent 75cda81 commit eadbb22

File tree

6 files changed

+71
-69
lines changed

6 files changed

+71
-69
lines changed

CHANGES.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 0.21.1 (2023-04-10)
4+
5+
- fix: `source .venv/bin/activate` before build by @joe733 in [#260](https://github.com/python-validators/validators/pull/260)
6+
- fix: id-token write permission at job level by @joe733 in [#261](https://github.com/python-validators/validators/pull/261)
7+
- feat: docs can be built with both sphinx & mkdocs by @joe733 in [#262](https://github.com/python-validators/validators/pull/262)
8+
- fix: improves build process by @joe733 in [#263](https://github.com/python-validators/validators/pull/263)
9+
- fix: removes 64-char limit for url path & query by @joe733 in [#264](https://github.com/python-validators/validators/pull/264)
10+
11+
**Full Changelog**: [0.21.0...0.21.1](https://github.com/python-validators/validators/compare/0.21.0...0.21.1)
12+
313
## 0.21.0 (2023-03-25)
414

515
- feat: add build for pypi workflow by @joe733 in [#255](https://github.com/python-validators/validators/pull/255)

poetry.lock

Lines changed: 37 additions & 57 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "validators"
3-
version = "0.21.0"
3+
version = "0.21.1"
44
description = "Python Data Validation for Humans™"
55
authors = ["Konsta Vesterinen <konsta@fastmonkeys.com>"]
66
license = "MIT"
@@ -28,16 +28,16 @@ include = ["CHANGES.md", "docs/*", "docs/validators.1", "validators/py.typed"]
2828
python = "^3.8"
2929

3030
[tool.poetry.group.dev.dependencies]
31-
tox = "^4.4.8"
31+
tox = "^4.4.11"
3232

3333
[tool.poetry.group.docs.dependencies]
3434
mkdocs = "^1.4.2"
35-
mkdocs-material = "^9.1.4"
35+
mkdocs-material = "^9.1.6"
3636
mkdocstrings = { extras = ["python"], version = "^0.20.0" }
3737
pyaml = "^21.10.1"
3838

3939
[tool.poetry.group.hooks.dependencies]
40-
pre-commit = "^3.2.1"
40+
pre-commit = "^3.2.2"
4141

4242
[tool.poetry.group.sast.dependencies]
4343
bandit = "^1.7.5"
@@ -48,14 +48,14 @@ myst-parser = "^1.0.0"
4848
pypandoc-binary = "^1.11"
4949

5050
[tool.poetry.group.tests.dependencies]
51-
pytest = "^7.2.2"
51+
pytest = "^7.3.0"
5252

5353
[tool.poetry.group.type-lint-format.dependencies]
5454
black = "^23.1.1"
5555
flake8 = "^5.0.4"
5656
flake8-docstrings = "^1.7.0"
5757
isort = "^5.12.0"
58-
pyright = "^1.1.301"
58+
pyright = "^1.1.302"
5959

6060
[build-system]
6161
requires = ["poetry-core"]

tests/test_url.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@
8383
"http://президент.рф/",
8484
"http://10.24.90.255:83/",
8585
"https://travel-usa.com/wisconsin/旅行/",
86+
"http://:::::::::::::@exmp.com",
87+
"http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com",
8688
# when simple_host=True
8789
# "http://localhost",
8890
# "http://localhost:8000",

validators/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@
6464
"fi_ssn",
6565
)
6666

67-
__version__ = "0.20.0"
67+
__version__ = "0.21.1"

validators/url.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# -*- coding: utf-8 -*-
33

44
# standard
5-
from urllib.parse import urlsplit
5+
from urllib.parse import urlsplit, unquote
66
from functools import lru_cache
77
import re
88

@@ -24,7 +24,15 @@ def _username_regex():
2424

2525
@lru_cache
2626
def _path_regex():
27-
return re.compile(r"^[\/a-zA-Z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\@\%]+$", re.IGNORECASE)
27+
return re.compile(
28+
# allowed symbols
29+
r"^[\/a-zA-Z0-9\-\.\_\~\!\$\&\'\(\)\*\+\,\;\=\:\@\%"
30+
# emoticons / emoji
31+
+ r"\U0001F600-\U0001F64F"
32+
# multilingual unicode ranges
33+
+ r"\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$",
34+
re.IGNORECASE,
35+
)
2836

2937

3038
@lru_cache
@@ -52,7 +60,9 @@ def _validate_auth_segment(value: str):
5260
if not value:
5361
return True
5462
if (colon_count := value.count(":")) > 1:
55-
return False
63+
# everything before @ is then considered as a username
64+
# this is a bad practice, but syntactically valid URL
65+
return _username_regex().match(unquote(value))
5666
if colon_count < 1:
5767
return _username_regex().match(value)
5868
username, password = value.rsplit(":", 1)
@@ -103,9 +113,9 @@ def _validate_optionals(path: str, query: str, fragment: str):
103113
"""Validate path query and fragments."""
104114
optional_segments = True
105115
if path:
106-
optional_segments &= bool(_path_regex().match(path.encode("idna").decode("utf-8")))
116+
optional_segments &= bool(_path_regex().match(path))
107117
if query:
108-
optional_segments &= bool(_query_regex().match(query.encode("idna").decode("utf-8")))
118+
optional_segments &= bool(_query_regex().match(query))
109119
if fragment:
110120
optional_segments &= all(char_to_avoid not in fragment for char_to_avoid in ("/", "?"))
111121
return optional_segments

0 commit comments

Comments
 (0)