Skip to content

Commit

Permalink
Add more tests cases; update changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
sloria committed Jan 23, 2025
1 parent 8cd29cb commit ea51eab
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Bug fixes:
- Correctly handle multiple `@post_load <marshmallow.post_load>` methods where one method appends to
the data and another passes ``pass_original=True`` (:issue:`1755`).
Thanks :user:`ghostwheel42` for reporting.
- ``URL`` fields now properly validate ``file`` paths.
- ``URL`` fields now properly validate ``file`` paths (:issue:`2249`).
Thanks :user:`0xDEC0DE` for reporting and fixing.

Documentation:

Expand Down
5 changes: 2 additions & 3 deletions src/marshmallow/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,8 @@ def __call__(self, value: str) -> str:
relative=self.relative, absolute=self.absolute, require_tld=self.require_tld
)

# The `file` scheme is a slightly-special case: hostnames are optional,
# and if absent it means `localhost`; fill it in for the validation if
# needed
# Hostname is optional for file URLS. If absent it means `localhost`.
# Fill it in for the validation if needed
if scheme == "file" and value.startswith("file:///"):
matched = regex.search(value.replace("file:///", "file://localhost/", 1))
else:
Expand Down
35 changes: 31 additions & 4 deletions tests/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,11 +205,38 @@ def test_url_custom_scheme():
assert validator(url) == url


def test_url_file_scheme():
# Ensure that file URLs don't get confused
url = "file:///tmp/tmp1234"
@pytest.mark.parametrize(
"valid_url",
(
"file:///tmp/tmp1234",
"file://localhost/tmp/tmp1234",
"file:///C:/Users/test/file.txt",
"file://localhost/C:/Program%20Files/file.exe",
"file:///home/user/documents/test.pdf",
"file:///tmp/test%20file.txt",
"file:///",
"file://localhost/",
),
)
def test_url_accepts_valid_file_urls(valid_url):
validator = validate.URL(schemes={"file"})
assert validator(url) == url
assert validator(valid_url) == valid_url


@pytest.mark.parametrize(
"invalid_url",
(
"file://",
"file:/tmp/file.txt",
"file:tmp/file.txt",
"file://hostname/path",
"file:///tmp/test file.txt",
),
)
def test_url_rejects_invalid_file_urls(invalid_url):
validator = validate.URL(schemes={"file"})
with pytest.raises(ValidationError, match="Not a valid URL."):
assert validator(invalid_url)


def test_url_relative_and_custom_schemes():
Expand Down

0 comments on commit ea51eab

Please sign in to comment.