mirror of
https://github.com/github/spec-kit.git
synced 2026-07-07 22:56:57 +08:00
fix(bundler): reject host-less catalog URLs in adapters (use hostname, not netloc) (#3333)
_validate_remote_url in bundler/services/adapters.py guarded on parsed.netloc, which is truthy for host-less URLs like "https://:8080" or "https://user@" even though they carry no host. so those passed the "must be a valid URL with a host" check. its docstring says it mirrors specify_cli.catalogs validation, but that site was already fixed to use hostname in #3210/#3227 and this twin was missed. switch to parsed.hostname (None for host-less URLs), matching catalogs.py. this guard runs before any network call, so it is a pre-flight safety check. add parametrized regression tests for the host-less forms plus a valid host+port sanity case.
This commit is contained in:
@@ -69,3 +69,30 @@ def test_http_fetch_rejects_non_https_final_url(monkeypatch):
|
||||
fetcher = adapters.make_catalog_fetcher(allow_network=True)
|
||||
with pytest.raises(BundlerError, match="must use HTTPS"):
|
||||
fetcher(_source("https://example.com/c.json"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"url",
|
||||
[
|
||||
"https://:8080", # port only, no host
|
||||
"https://:0",
|
||||
"https://user@", # userinfo only, no host
|
||||
"https://user:pw@",
|
||||
"https://:8080/catalog.json",
|
||||
],
|
||||
)
|
||||
def test_validate_remote_url_rejects_host_less_urls(url):
|
||||
"""A URL with a truthy netloc but no host (``https://:8080``,
|
||||
``https://user@``) must be rejected.
|
||||
|
||||
``urlparse`` gives these a non-empty ``netloc`` but ``hostname is None``,
|
||||
so a ``netloc`` check would wrongly accept them. This mirrors the fix in
|
||||
``specify_cli.catalogs`` (#3210), which the docstring says this validator
|
||||
mirrors."""
|
||||
with pytest.raises(BundlerError, match="valid URL with a host"):
|
||||
adapters._validate_remote_url("team", url)
|
||||
|
||||
|
||||
def test_validate_remote_url_accepts_normal_https_url():
|
||||
# Sanity: a real host with a port still passes.
|
||||
adapters._validate_remote_url("team", "https://example.com:8080/c.json")
|
||||
|
||||
Reference in New Issue
Block a user