Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions sphinx/ext/intersphinx/_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,17 +399,18 @@ def _fetch_inventory_url(
raw_data = r.content
new_inv_location = r.url
except Exception as err:
safe_url = _get_safe_url(inv_location)
err.args = (
'intersphinx inventory %r not fetchable due to %s: %s',
inv_location,
safe_url,
err.__class__,
str(err),
str(err).replace(inv_location, safe_url),
)
raise

if inv_location != new_inv_location:
msg = __('intersphinx inventory has moved: %s -> %s')
LOGGER.info(msg, inv_location, new_inv_location)
LOGGER.info(msg, _get_safe_url(inv_location), _get_safe_url(new_inv_location))

if target_uri in {
inv_location,
Expand Down
56 changes: 56 additions & 0 deletions tests/test_ext_intersphinx/test_ext_intersphinx.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,62 @@ def test_getsafeurl_unauthed() -> None:
assert actual == expected


def test_fetch_inventory_url_error_hides_credentials(capsys):

This comment was marked as resolved.

"""Credentials should not appear in error messages on fetch failure."""

class ErrorHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_error(500, 'Internal Server Error')

def log_message(*args, **kwargs):
pass

with http_server(ErrorHandler) as server:
url = f'http://user:secret@localhost:{server.server_port}/{INVENTORY_FILENAME}'
inspect_main([url])

_, stderr = capsys.readouterr()
assert 'secret' not in stderr

This comment was marked as resolved.

This comment was marked as resolved.

assert 'user@localhost' in stderr


@pytest.mark.sphinx('html', testroot='root')
def test_fetch_inventory_redirect_hides_credentials(app):
"""Credentials should not appear in redirect log messages."""

class RedirectHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if '/new/' not in self.path:
self.send_response(302)
new_url = f'http://localhost:{self.server.server_port}/new/{INVENTORY_FILENAME}'
self.send_header('Location', new_url)
self.end_headers()
else:
self.send_response(200, 'OK')
self.end_headers()
self.wfile.write(INVENTORY_V2)

def log_message(*args, **kwargs):
pass

intersphinx_setup(app)

with http_server(RedirectHandler) as server:
port = server.server_port
inv_location = f'http://user:secret@localhost:{port}/{INVENTORY_FILENAME}'
_fetch_inventory_data(
target_uri=f'http://localhost:{port}/',
inv_location=inv_location,
config=_InvConfig.from_config(app.config),
srcdir=app.srcdir,
cache_path=None,
)

status_output = app.status.getvalue()
assert 'secret' not in status_output

This comment was marked as resolved.

This comment was marked as resolved.

assert 'user@localhost' in status_output

This comment was marked as resolved.



def test_inspect_main_noargs(capsys):
"""inspect_main interface, without arguments"""
assert inspect_main([]) == 1
Expand Down
Loading