mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-08 13:12:08 +00:00
Guard native image routing with file safety
This commit is contained in:
parent
51c1ba6976
commit
c13281ab57
2 changed files with 49 additions and 0 deletions
|
|
@ -632,6 +632,17 @@ def _file_to_data_url(path: Path) -> Optional[str]:
|
|||
caller reports those paths in ``skipped`` and the rest of the turn
|
||||
proceeds.
|
||||
"""
|
||||
try:
|
||||
from agent.file_safety import raise_if_read_blocked
|
||||
|
||||
raise_if_read_blocked(str(path))
|
||||
except ValueError as exc:
|
||||
logger.warning("image_routing: blocked local image attachment %s -- %s", path, exc)
|
||||
return None
|
||||
except Exception:
|
||||
# Keep attachment routing best-effort if the guard itself is unavailable.
|
||||
pass
|
||||
|
||||
try:
|
||||
raw = path.read_bytes()
|
||||
except Exception as exc:
|
||||
|
|
|
|||
|
|
@ -780,6 +780,44 @@ class TestFormatCompatibility:
|
|||
b64 = url.split(",", 1)[1]
|
||||
assert base64.b64decode(b64) == _png_bytes()
|
||||
|
||||
def test_file_to_data_url_blocks_read_denied_image_path(self, tmp_path: Path):
|
||||
"""Native image routing must honor the shared credential read guard."""
|
||||
from agent.image_routing import _file_to_data_url
|
||||
|
||||
img_path = tmp_path / ".env"
|
||||
img_path.write_bytes(_png_bytes())
|
||||
|
||||
assert _file_to_data_url(img_path) is None
|
||||
|
||||
def test_native_content_parts_skip_read_denied_local_image(self, tmp_path: Path):
|
||||
from agent.image_routing import build_native_content_parts
|
||||
|
||||
img_path = tmp_path / ".env.local"
|
||||
img_path.write_bytes(_png_bytes())
|
||||
|
||||
parts, skipped = build_native_content_parts("inspect this", [str(img_path)])
|
||||
|
||||
assert skipped == [str(img_path)]
|
||||
assert all(part.get("type") != "image_url" for part in parts)
|
||||
|
||||
def test_native_content_parts_blocks_image_symlink_to_read_denied_file(self, tmp_path: Path):
|
||||
from agent.image_routing import build_native_content_parts
|
||||
import os
|
||||
import pytest
|
||||
|
||||
secret = tmp_path / ".env"
|
||||
secret.write_bytes(_png_bytes())
|
||||
img_link = tmp_path / "secret.png"
|
||||
try:
|
||||
os.symlink(secret, img_link)
|
||||
except (OSError, NotImplementedError) as exc:
|
||||
pytest.skip(f"symlinks unavailable: {exc}")
|
||||
|
||||
parts, skipped = build_native_content_parts("inspect this", [str(img_link)])
|
||||
|
||||
assert skipped == [str(img_link)]
|
||||
assert all(part.get("type") != "image_url" for part in parts)
|
||||
|
||||
def test_jpeg_passes_through_no_transcode(self, tmp_path: Path):
|
||||
from agent.image_routing import _file_to_data_url
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue