Files
nousresearch--hermes-agent/tests/gateway/test_api_server_media_data_urls.py
wehub-resource-sync b4fbd6fe9f
Deploy Site / deploy-vercel (push) Has been skipped
Deploy Site / deploy-docs (push) Has been skipped
Build Skills Index / build-index (push) Has been skipped
CI / Deny unrelated histories (push) Has been skipped
CI / Detect affected areas (push) Successful in 27m35s
CI / OSV scan (push) Failing after 4s
CI / Build&Test Docker image (push) Successful in 9s
CI / Supply-chain scan (push) Has been skipped
CI / Lint Docker scripts (push) Failing after 5m13s
CI / Check contributors (push) Failing after 12m8s
CI / Docs Site (push) Failing after 12m8s
CI / TypeScript (push) Failing after 12m8s
CI / Python lints (push) Failing after 12m9s
CI / Python tests (push) Failing after 12m9s
CI / Check uv.lock (push) Failing after 23m22s
CI / CI timing report (push) Has been cancelled
Build Skills Index / trigger-deploy (push) Has been cancelled
CI / All required checks pass (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 11:56:03 +08:00

112 lines
4.2 KiB
Python

"""MEDIA: tag → base64 data-URL resolution for the API server (salvage of #2696).
Remote OpenAI-compatible frontends can't read local file paths, so
``MEDIA:<path>`` image tags in final responses are inlined as markdown
data URLs before crossing the HTTP boundary.
"""
import base64
import unittest
import pytest
pytest.importorskip("aiohttp")
from gateway.platforms.api_server import _resolve_media_to_data_urls # noqa: E402
# 1x1 transparent PNG
_PNG_BYTES = base64.b64decode(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGNgYGBgAAAABQAB"
"h6FO1AAAAABJRU5ErkJggg=="
)
class TestResolveMediaToDataUrls(unittest.TestCase):
def _write_png(self, tmpdir_name="hermes_media_test"):
import tempfile
from pathlib import Path
d = Path(tempfile.mkdtemp(prefix=tmpdir_name))
p = d / "shot.png"
p.write_bytes(_PNG_BYTES)
return p
def test_media_tag_inlined(self):
p = self._write_png()
out = _resolve_media_to_data_urls(f"Here you go: MEDIA:{p}")
self.assertIn("data:image/png;base64,", out)
self.assertNotIn("MEDIA:", out)
def test_backtick_wrapped_tag(self):
p = self._write_png()
out = _resolve_media_to_data_urls(f"See `MEDIA:{p}` above")
self.assertIn("data:image/png;base64,", out)
def test_missing_file_left_untouched(self):
text = "MEDIA:/nonexistent/path/shot.png"
self.assertEqual(_resolve_media_to_data_urls(text), text)
def test_non_image_left_untouched(self):
text = "MEDIA:/tmp/archive.zip"
self.assertEqual(_resolve_media_to_data_urls(text), text)
def test_text_without_media_passthrough(self):
self.assertEqual(_resolve_media_to_data_urls("plain text"), "plain text")
self.assertEqual(_resolve_media_to_data_urls(""), "")
def test_oversized_image_skipped(self):
from gateway.platforms import api_server as mod
p = self._write_png()
orig = mod._MEDIA_DATA_URL_MAX_BYTES
mod._MEDIA_DATA_URL_MAX_BYTES = 1
try:
text = f"MEDIA:{p}"
self.assertEqual(_resolve_media_to_data_urls(text), text)
finally:
mod._MEDIA_DATA_URL_MAX_BYTES = orig
def test_multiple_tags(self):
p1 = self._write_png()
p2 = self._write_png("hermes_media_test2")
out = _resolve_media_to_data_urls(f"MEDIA:{p1}\nand MEDIA:{p2}")
self.assertEqual(out.count("data:image/png;base64,"), 2)
def test_relative_traversal_path_not_inlined(self):
"""A relative/traversal path must never be inlined — the anchored
MEDIA_TAG_CLEANUP_RE matcher requires an absolute-path prefix
(~/, /, or a Windows drive letter), so a bare relative token after
MEDIA: is left as literal text rather than resolved against cwd."""
text = "MEDIA:../../../../etc/passwd.png"
self.assertEqual(_resolve_media_to_data_urls(text), text)
def test_credential_path_not_inlined_even_with_image_extension(self):
"""An absolute path under the credential/system-path denylist
(validate_media_delivery_path) must not be inlined even though it
has an allowed image extension and the tag matcher's shape."""
text = "MEDIA:~/.ssh/id_rsa.png"
self.assertEqual(_resolve_media_to_data_urls(text), text)
def test_symlink_escaping_to_denylisted_target_not_inlined(self):
"""A symlink whose resolved target lands under a denylisted system
prefix (/etc) must not be inlined — validate_media_delivery_path
resolves symlinks before the containment/denylist check runs, so
the traversal can't be laundered through an innocuous-looking
image-suffixed symlink name."""
import os
import tempfile
from pathlib import Path
d = Path(tempfile.mkdtemp(prefix="hermes_media_test_symlink"))
link = d / "shot.png"
try:
os.symlink("/etc/hosts", link)
except OSError:
self.skipTest("symlink creation not supported in this environment")
text = f"MEDIA:{link}"
self.assertEqual(_resolve_media_to_data_urls(text), text)
if __name__ == "__main__":
unittest.main()