fix(files): reject oversized reads before loading
This commit is contained in:
committed by
chengyongru
parent
d5658dbc91
commit
cdb2df4982
@@ -237,6 +237,7 @@ class ReadFileTool(_FsTool):
|
|||||||
_scopes = {"core", "subagent", "memory"}
|
_scopes = {"core", "subagent", "memory"}
|
||||||
|
|
||||||
_MAX_CHARS = 128_000
|
_MAX_CHARS = 128_000
|
||||||
|
_MAX_FILE_SIZE_BYTES = 100 * 1024 * 1024
|
||||||
_DEFAULT_LIMIT = 2000
|
_DEFAULT_LIMIT = 2000
|
||||||
_MAX_PDF_PAGES = 20
|
_MAX_PDF_PAGES = 20
|
||||||
|
|
||||||
@@ -290,6 +291,15 @@ class ReadFileTool(_FsTool):
|
|||||||
if not fp.is_file():
|
if not fp.is_file():
|
||||||
return ToolResult.error(f"Error: Not a file: {path}")
|
return ToolResult.error(f"Error: Not a file: {path}")
|
||||||
|
|
||||||
|
file_size = fp.stat().st_size
|
||||||
|
if file_size > self._MAX_FILE_SIZE_BYTES:
|
||||||
|
size_mib = file_size / (1024 * 1024)
|
||||||
|
max_mib = self._MAX_FILE_SIZE_BYTES // (1024 * 1024)
|
||||||
|
return ToolResult.error(
|
||||||
|
f"Error: File too large to read ({size_mib:.1f} MiB). "
|
||||||
|
f"Maximum is {max_mib} MiB."
|
||||||
|
)
|
||||||
|
|
||||||
# PDF support
|
# PDF support
|
||||||
if fp.suffix.lower() == ".pdf":
|
if fp.suffix.lower() == ".pdf":
|
||||||
return self._read_pdf(fp, pages)
|
return self._read_pdf(fp, pages)
|
||||||
|
|||||||
@@ -99,6 +99,22 @@ class TestReadFileTool:
|
|||||||
assert len(result) <= ReadFileTool._MAX_CHARS + 500 # small margin for footer
|
assert len(result) <= ReadFileTool._MAX_CHARS + 500 # small margin for footer
|
||||||
assert "Use offset=" in result
|
assert "Use offset=" in result
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_oversized_file_is_rejected_before_read(self, tool, tmp_path, monkeypatch):
|
||||||
|
f = tmp_path / "huge.txt"
|
||||||
|
with f.open("wb") as stream:
|
||||||
|
stream.truncate(ReadFileTool._MAX_FILE_SIZE_BYTES + 1)
|
||||||
|
|
||||||
|
def fail_read_bytes(self):
|
||||||
|
raise AssertionError("oversized file content should not be loaded")
|
||||||
|
|
||||||
|
monkeypatch.setattr(type(f), "read_bytes", fail_read_bytes)
|
||||||
|
|
||||||
|
result = await tool.execute(path=str(f))
|
||||||
|
|
||||||
|
assert "File too large to read" in result
|
||||||
|
assert "Maximum is 100 MiB" in result
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# _find_match (unit tests for the helper)
|
# _find_match (unit tests for the helper)
|
||||||
|
|||||||
Reference in New Issue
Block a user