fix(annotations): deny case and Unicode spellings of a listed file

On macOS (case- and normalization-insensitive APFS) a crafted target such
as A.PNG or an NFD name opened the listed a.png or NFC file while
realpath kept the requested spelling, so the tags were stored under a
second locator the Images filter never shows. Capture and verify now
require each path part to be spelled as its directory lists it and deny
any other case or Unicode spelling as an alias (409 source-changed, like
a symlink alias). A missing file with no other spelling keeps its usual
outcome.
This commit is contained in:
Vito Sansevero
2026-10-22 09:59:05 -07:00
parent 913b4689db
commit c6729927e6
3 changed files with 78 additions and 0 deletions
+12
View File
@@ -282,6 +282,18 @@ class TestObserve(AnnotationAPITestCase):
self.assertEqual(response.status, 400)
capture.assert_not_called()
async def test_observe_denies_case_spellings_of_the_listed_file(self):
make_png(self.output_dir / "sub" / "a.png")
for alias in ("sub/A.PNG", "SUB/a.png"):
with self.subTest(alias=alias):
status, body = await self.observe({"target": self.target(alias)})
# Denied as an alias, like a symlink to the listed file.
self.assertEqual((status, body["code"]), (409, "source-changed"))
self.assert_no_paths(body)
store = self.api._captures
self.assertFalse(any(Path(store.directory).iterdir()))
await self.observe_ok("sub/a.png")
async def test_observe_returns_saved_tags_for_exact_bytes_only(self):
path = make_png(self.output_dir / "sub" / "a.png")
original = path.read_bytes()