Skip to content

Commit

Permalink
Fix URL.build not validating that path has a leading slash when p…
Browse files Browse the repository at this point in the history
…assing `authority` (#1265)
  • Loading branch information
bdraco authored Oct 15, 2024
1 parent 0b16c54 commit f48b0d6
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
3 changes: 3 additions & 0 deletions CHANGES/1265.bugfix.rst
Original file line number Diff line number Diff line change
@@ -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``.
8 changes: 7 additions & 1 deletion tests/test_url_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 8 additions & 11 deletions yarl/_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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":
"""
Expand Down

0 comments on commit f48b0d6

Please sign in to comment.