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:
+11
-3
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user