fix(mcp): ignore malformed path-like text (#4456)

Co-authored-by: chatgpt-codex-connector[bot] <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com>
This commit is contained in:
VectorPeak 2026-07-25 21:43:33 +08:00 committed by GitHub
parent 8c19a2eb36
commit 07d8b98864
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 1 deletions

View File

@ -70,7 +70,10 @@ def _local_path_from_uri(uri: str, *, base_dir: Path | None = None) -> Path | No
"""
if not uri:
return None
parsed = urlparse(uri)
try:
parsed = urlparse(uri)
except ValueError:
return None
if parsed.scheme == "file":
raw = unquote(parsed.path)
elif parsed.scheme == "":

View File

@ -46,6 +46,9 @@ class TestLocalPathFromUri:
assert mcp_tools._local_path_from_uri("https://example.com/a.png") is None
assert mcp_tools._local_path_from_uri("data:image/png;base64,AAAA") is None
def test_malformed_uri_is_ignored(self):
assert mcp_tools._local_path_from_uri("//[::1/foo.png") is None
def test_relative_path_is_ignored_without_base_dir(self):
assert mcp_tools._local_path_from_uri("relative/path.txt") is None
@ -192,6 +195,14 @@ class TestRewriteLocalPathsInText:
assert result == text
def test_malformed_path_like_text_is_left_untouched(self, paths: Paths):
text = "Saved at //[::1/foo.png"
with _patch_paths(paths):
result = mcp_tools._rewrite_local_paths_in_text(text, thread_id="t1", user_id="u1")
assert result == text
def test_playwright_markdown_path_is_rewritten_twice_without_copy(self, paths: Paths):
workspace = paths.sandbox_work_dir("t1", user_id="u1")
_workspace_file(paths, ".playwright-mcp/page.png", content=b"png")
@ -508,6 +519,15 @@ class TestConvertCallToolResultRewrites:
assert content[0]["type"] == "text"
assert content[0]["text"] == "hello"
def test_malformed_path_like_text_result_does_not_raise(self, paths: Paths):
result = CallToolResult(content=[TextContent(type="text", text="Saved at //[::1/foo.png")], isError=False)
with _patch_paths(paths):
content, _ = mcp_tools._convert_call_tool_result(result, thread_id="t1", user_id="u1")
assert content[0]["type"] == "text"
assert content[0]["text"] == "Saved at //[::1/foo.png"
def test_image_content_passthrough(self, paths: Paths):
from mcp.types import ImageContent