From db0f714b4fb1493a535368966a5e6a8e9f91efb3 Mon Sep 17 00:00:00 2001 From: nendo Date: Fri, 29 May 2026 17:40:56 +0900 Subject: [PATCH] SaveSync: use pathlib joins for asset content-hash paths FSAssetsHandler.compute_content_hash and _compute_zip_hash were building full paths via f"{self.base_path}/{file_path}". self.base_path is already a pathlib.Path (resolved by FSHandler.__init__), so the f-string forced it to str, hard-coded the separator, and re-parsed -- fine on Linux but a footgun if a caller ever sneaks a leading slash or the path needs Path semantics elsewhere. Switch both spots to self.base_path / file_path, which is what every other FSHandler subclass in this module already does (e.g. FSRomsHandler, FSResourcesHandler, FSSyncHandler all join Path objects directly). --- backend/handler/filesystem/assets_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/handler/filesystem/assets_handler.py b/backend/handler/filesystem/assets_handler.py index 68d9aef68..f6825a3bf 100644 --- a/backend/handler/filesystem/assets_handler.py +++ b/backend/handler/filesystem/assets_handler.py @@ -132,7 +132,7 @@ class FSAssetsHandler(FSHandler): return hash_obj.hexdigest() async def _compute_zip_hash(self, zip_path: str) -> str: - with zipfile.ZipFile(f"{self.base_path}/{zip_path}", "r") as zf: + with zipfile.ZipFile(self.base_path / zip_path, "r") as zf: file_hashes = [] for name in sorted(zf.namelist()): if not name.endswith("/"): @@ -144,7 +144,7 @@ class FSAssetsHandler(FSHandler): async def compute_content_hash(self, file_path: str) -> str | None: try: - full_path = f"{self.base_path}/{file_path}" + full_path = self.base_path / file_path if zipfile.is_zipfile(full_path): return await self._compute_zip_hash(file_path) return await self._compute_file_hash(file_path)