fix(lora): check the file Show in folder would open under a LoRA root (#355)

reveal_image resolved the requested path through the client-path
resolver, which can fall back to a path anchor; under a LoRA-linked root
the file that would open now passes the same recorded-media gate, so only
a linked file is ever revealed there.
This commit is contained in:
Vito Sansevero
2026-10-26 20:23:41 -07:00
parent 7c6db24891
commit 3bd01dd2fb
2 changed files with 24 additions and 3 deletions
+11 -3
View File
@@ -3367,12 +3367,16 @@ class ImageRoutesMixin:
status=429,
)
try:
return await self._reveal(relative, root)
return await self._reveal(relative, root, linked_only=index >= len(outputs))
finally:
gate.leave()
async def _reveal(self, relative: str, root: Path):
"""Resolve and open, inside the reveal gate."""
async def _reveal(self, relative: str, root: Path, *, linked_only=False):
"""Resolve and open, inside the reveal gate.
Under a LoRA-linked root the file that would open is checked again
(it may resolve through a path anchor): only a recorded one opens.
"""
try:
path = await self._run_in_executor(self._reveal_path, relative, root)
except (OSError, ValueError) as exc:
@@ -3383,6 +3387,10 @@ class ImageRoutesMixin:
return _reveal_not_found()
if path is None:
return _reveal_not_found()
if linked_only and not await self._run_in_executor(
self._is_recorded_media, path
):
return _forbidden()
try:
await asyncio.get_running_loop().run_in_executor(
reveal_executor(), self._reveal_opener, path, root
+13
View File
@@ -715,6 +715,19 @@ class TestRevealRoute(ImageAPITestCase):
)
self.assertEqual((status, data), (200, {"success": True}))
self.assertEqual(self.opened, [Path(os.path.realpath(linked))])
# The file that would open is checked too, whatever the request named
# (a path anchor could resolve it elsewhere in the root).
other = make_png(lora / "abc" / "other.png")
from py.api.images import ImageRoutesMixin
with patch.object(
ImageRoutesMixin, "_resolve_client_media_path", return_value=other
):
status, _data = await self.post(
{"root_index": 1, "root_scope": scope, "path": "abc/cover.png"}
)
self.assertEqual(status, 403)
self.assertEqual(len(self.opened), 1)
async def test_target_changed_before_launch_is_404(self):
make_png(self.output_dir / "sub" / "a.png")