Two names that differ only in case are one file on Windows and on macOS as they
come, and Win32 drops a trailing dot or space, so `clip.png` with `CLIP.png`,
and `a.png` with `a.png.`, still landed on each other: ten entries extracted to
nine files on APFS, one footage item holding the other's picture. Collisions are
now looked up by a key with the case folded and those characters off the end,
while the name written stays as the entry asked.
Found by CodeRabbit on the pull request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The fallback name was never checked against the names already taken, so an
entry called exactly what the fallback produces took the same file: `media/1/a:b.png`,
`media/2/a_b.png` and `media/3/2-a_b.png` extracted to five files for six
entries, the third overwriting the second, and both items' footage pointing at
it. Deduplication now runs on the name actually written and counts up until it
is free.
The collision predates making the names safe (two entries named `a_b.png` and
`2-a_b.png` collide on their own), but sanitising gives more ways in, so it
belongs with it.
Found by CodeRabbit on the pull request.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
EffectCraft writes its own templates as `media/<item id>/<file>` entries, and
extraction trusted both halves. `base_name` splits on `/` and `\`, but the item
id was taken with `split('/')` alone, and it is pasted in front of a base name
another item already used. So a second `media/..\..\..\Startup\x/clip.mp4`
entry became `<dir>/..\..\..\Startup\x-clip.mp4`, which on Windows is three
folders up, with the attacker choosing how the name ends.
The id is now used only when it is one, and the name goes through
`safe_file_name`: separators, drive colons and NUL become `_`, and `.` / `..`
become `footage`. Reached from `templates.create` with `path`, from File ▸ New
from Template, and from a template dropped in the user Templates folder.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(ui-egui): craft_ui::ComboBox for every combo box, so open menus grow back (egui#5225)
Repins craft-libs to aiongg/craft-libs 60d60d48 (storytold main with the shared
dropdown) and bans egui::ComboBox in clippy.toml.
* fix(ui-egui): font menu under the font field is a craft_ui combo menu that grows back
The filter row is the menu's header and only the font list scrolls, so a search
that matched nothing grows the menu back when it is cleared.
* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)
* chore(deps): craft-libs 92d392cf (#387 merged)
* chore(xtask): pdf-deps expects craft-libs 92d392cf