From 1d4babfe7163628c547b1e747057bcfdaaeef69a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 14 Oct 2024 22:49:40 -0500 Subject: [PATCH 1/3] Fix URL.build not validating that path has a leading slash when passing authority The validation only worked when host was passed --- tests/test_url_build.py | 8 +++++++- yarl/_url.py | 19 ++++++++----------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/test_url_build.py b/tests/test_url_build.py index cc9b15f7e..a3943dc2d 100644 --- a/tests/test_url_build.py +++ b/tests/test_url_build.py @@ -140,12 +140,18 @@ def test_build_with_invalid_host(host: str, is_authority: bool): def test_build_with_authority(): - url = URL.build(scheme="http", authority="степан:bar@host.com:8000", path="path") + url = URL.build(scheme="http", authority="степан:bar@host.com:8000", path="/path") assert ( str(url) == "http://%D1%81%D1%82%D0%B5%D0%BF%D0%B0%D0%BD:bar@host.com:8000/path" ) +def test_build_with_authority_no_leading_flash(): + msg = r"Path in a URL with authority should start with a slash \('/'\) if set" + with pytest.raises(ValueError, match=msg): + URL.build(scheme="http", authority="степан:bar@host.com:8000", path="path") + + def test_build_with_authority_without_encoding(): url = URL.build( scheme="http", authority="foo:bar@host.com:8000", path="path", encoded=True diff --git a/yarl/_url.py b/yarl/_url.py index 271e0840e..37536610f 100644 --- a/yarl/_url.py +++ b/yarl/_url.py @@ -309,7 +309,8 @@ def __new__( if netloc: if "." in path: path = cls._normalize_path(path) - cls._validate_authority_uri_abs_path(host, path) + if path[0] != "/": + cls._raise_for_authority_missing_abs_path() query = cls._QUERY_REQUOTER(query) if query else query fragment = cls._FRAGMENT_REQUOTER(fragment) if fragment else fragment @@ -407,7 +408,8 @@ def build( if path and netloc: if "." in path: path = cls._normalize_path(path) - cls._validate_authority_uri_abs_path(host, path) + if path[0] != "/": + cls._raise_for_authority_missing_abs_path() query_string = ( cls._QUERY_QUOTER(query_string) if query_string else query_string @@ -947,15 +949,10 @@ def suffixes(self) -> tuple[str, ...]: return tuple(self._UNQUOTER(suffix) for suffix in self.raw_suffixes) @staticmethod - def _validate_authority_uri_abs_path(host: str, path: str) -> None: - """Ensure that path in URL with authority starts with a leading slash. - - Raise ValueError if not. - """ - if host and path and path[0] != "/": - raise ValueError( - "Path in a URL with authority should start with a slash ('/') if set" - ) + def _raise_for_authority_missing_abs_path() -> None: + """Raise when he path in URL with authority starts lacks a leading slash.""" + msg = "Path in a URL with authority should start with a slash ('/') if set" + raise ValueError(msg) def _make_child(self, paths: "Sequence[str]", encoded: bool = False) -> "URL": """ From 1253dfabb02e445595c95e3621e3f7c6d2c56fff Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 14 Oct 2024 23:28:20 -0500 Subject: [PATCH 2/3] changelog --- CHANGES/1265.bugfix.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CHANGES/1265.bugfix.rst diff --git a/CHANGES/1265.bugfix.rst b/CHANGES/1265.bugfix.rst new file mode 100644 index 000000000..79b131c6d --- /dev/null +++ b/CHANGES/1265.bugfix.rst @@ -0,0 +1,3 @@ +Fixed :py:meth:`~yarl.URL.build` failing to validate paths must start with a / when passing ``authority`` -- by :user:`bdraco`. + +The validation only worked correctly when passing ``host``. From 798387627feb831da92766711cb12d12e7b8a207 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 14 Oct 2024 23:30:53 -0500 Subject: [PATCH 3/3] Update CHANGES/1265.bugfix.rst --- CHANGES/1265.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/1265.bugfix.rst b/CHANGES/1265.bugfix.rst index 79b131c6d..60cd5e5b6 100644 --- a/CHANGES/1265.bugfix.rst +++ b/CHANGES/1265.bugfix.rst @@ -1,3 +1,3 @@ -Fixed :py:meth:`~yarl.URL.build` failing to validate paths must start with a / when passing ``authority`` -- by :user:`bdraco`. +Fixed :py:meth:`~yarl.URL.build` failing to validate paths must start with a ``/`` when passing ``authority`` -- by :user:`bdraco`. The validation only worked correctly when passing ``host``.