mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-19 02:10:25 -05:00
Photo ▸ Edit In ▸ Open Original in Other Editor handed a photo's stored path straight to `open` / `xdg-open` / `explorer.exe`, with `Path::is_file()` as the only check, and Lightroom catalog import kept original paths exactly as the catalog had them. A crafted `.lrcat` could therefore put `payload.exe`, `start.lnk`, `run.bat`, `page.hta`, `Evil.app` or `go.command` into the library and have it run on one user click. - `lightcraft_engine::open_path`: one gate for every path that leaves LightCraft for the OS. The extension must be one LightCraft reads (`import::EXTENSIONS`, which already covers the Edit In copy formats `tif`/`tiff`/`psd`), it must be a regular file (so a `.app` bundle and any other folder are out), what a link resolves to must be a read type too, and what is handed over is the absolute path. A refusal is the sentence shown to the user. - Open Original and Edit In go through it; a refused photo is listed in `skipped` with the reason, and the menu item is greyed out for a record that can never be opened (extension only, so no disk or share is touched while a menu is drawn). - `lightroom_catalog::refuse_non_media` drops such images where the catalog is read and again where its photos become records, with a warning each, so a refused entry never becomes an openable library record. A virtual copy of a refused original goes with it. Tests: a catalog naming a program (and a virtual copy of it) imports neither while the catalog's real photos do; a library record naming a program is never handed to the stub launcher, which records no invocation, and a program selected beside a photo leaves only the photo, by absolute path. Both fail before this change. Co-Authored-By: Claude <noreply@anthropic.com>