Repository navigation
Fall back to an NTFS junction when the symlink escape test can't create a symlink #3609
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| """Tests for filesystem path safety primitives.""" | ||
|
|
||
| import sys | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
|
|
@@ -142,7 +143,14 @@ def test_safe_join_rejects_symlink_escape(tmp_path: Path): | |
| outside.mkdir() | ||
| sandbox = tmp_path / "sandbox" | ||
| sandbox.mkdir() | ||
| (sandbox / "escape").symlink_to(outside) | ||
| try: | ||
| (sandbox / "escape").symlink_to(outside) | ||
| except OSError as exc: # pragma: lax no cover | ||
| if sys.platform != "win32" or exc.winerror != 1314: # ERROR_PRIVILEGE_NOT_HELD; a junction needs no privilege | ||
| raise | ||
| import _winapi | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 nit (optional): maintainers get an inline Why this was flaggedThe diff adds Verification: nit. Rule in AGENTS.md:56-59. The diff adds |
||
|
|
||
| _winapi.CreateJunction(str(outside), str(sandbox / "escape")) | ||
|
|
||
| with pytest.raises(PathEscapeError, match="escapes base"): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟣 pre-existing, not blocking: Maintainers keep a test that pins SDK-authored error text via Why this was flaggedThis is the only ledger entry, so it is nominated by requirement; the dismissal's pre_existing claim is accurate (base commit has the same Verification: pre-existing. Triggering condition: any rewording of the f-string at src/mcp/shared/path_security.py:174 makes tests/shared/test_path_security.py:155 fail on text rather than behaviour. However, the violating line is NOT introduced by this PR: |
||
| safe_join(sandbox, "escape", "secret.txt") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 nit (optional): AGENTS.md says to avoid adding new coverage pragmas, and documents
# pragma: lax no coveras for "lines covered on some platforms/versions but not others". The diff adds# pragma: lax no coveron theexcept OSErrorarm, which the PR description says no CI matrix entry executes (hosted Windows runners can create symlinks), so it is not covered on any platform CI runs. Fix: either restructure so the fallback is exercised by a test on all platforms (e.g. a small helper withsymlink_topatched to raiseOSError(winerror=1314)and a stub_winapiinsys.modules), or, if a pragma must stay, use the form whose documented meaning matches the line.Why this was flagged
Nothing fails at runtime. The instruction guards the 100% branch-coverage gate from accumulating excluded lines; here the excluded block contains real logic (the
winerrorcheck and theCreateJunctioncall) that the PR itself says has not been run on a real unprivileged Windows machine, and the pragma also hides theif ... raisebranch arcs. The author reports exercising the control flow manually on Linux via patching, but that check is not committed as a test. Small consequence: a future regression in the fallback (wrong argument order to CreateJunction, AttributeError onwinerror) would go unnoticed by CI.Verification: AGENTS.md (base d639cf7) "Coverage" section: "Avoid adding new
# pragma: no cover,# type: ignore, or# noqacomments." with the audit commandgit diff origin/main... | grep -E '^\+.*(pragma|type: ignore|noqa)', and it documents# pragma: lax no coveras the form to "Use for lines covered on some platforms/versions but not others."