[Feature] Work filePickerPathBaseline down from 7 to 0 #528

Closed
opened 2026-07-22 10:32:28 +00:00 by brenno · 1 comment
Owner

The gate from #505 landed with a baseline of seven files that take a filesystem path from FilePicker without naming a platform flag themselves. The baseline is a record, not an approval — each entry needs its own decision.

Gated at the caller (4). open_presentation_dialog, slide_finder_dialog, import_slides_dialog, save_destination_dialog. These are correct today: the callers (shell_actions.dart, slide_list_panel.dart", deck_provider.dart`) carry the gate. The file itself cannot prove it, which is exactly the fragility — move the gate into the dialog, or give the dialog a required flag, so the guarantee is local.

Services reading .path (2 files, 5 sites). lib/services/file_service.dart:518,957 and lib/services/image_service.dart:239,265,276. The second is the more interesting: this is the service that maintains mem: keys for browser-held images, so a .path read there is either dead on web or a live blob:-URL leak. Establish which before touching it.

Open bug (1). image_carousel_picker_actions.dart — tracked as #526.

Work them one at a time, each with its own reasoning; do not batch. Removing an entry from filePickerPathBaseline is the proof, and make check-conventions reports a stale entry, so the list cannot rot silently.

The gate from #505 landed with a baseline of seven files that take a filesystem path from `FilePicker` without naming a platform flag themselves. The baseline is a record, not an approval — each entry needs its own decision. **Gated at the caller (4).** `open_presentation_dialog`, `slide_finder_dialog`, `import_slides_dialog`, `save_destination_dialog`. These are correct today: the callers (`shell_actions.dart`, `slide_list_panel.dart", `deck_provider.dart`) carry the gate. The file itself cannot prove it, which is exactly the fragility — move the gate into the dialog, or give the dialog a required flag, so the guarantee is local. **Services reading `.path` (2 files, 5 sites).** `lib/services/file_service.dart:518,957` and `lib/services/image_service.dart:239,265,276`. The second is the more interesting: this is the service that maintains `mem:` keys for browser-held images, so a `.path` read there is either dead on web or a live blob:-URL leak. Establish which before touching it. **Open bug (1).** `image_carousel_picker_actions.dart` — tracked as #526. Work them one at a time, each with its own reasoning; do not batch. Removing an entry from `filePickerPathBaseline` is the proof, and `make check-conventions` reports a stale entry, so the list cannot rot silently.
Author
Owner

Done in #565 — the baseline is empty.

Each of the seven got its own decision, as asked, and they came out three different ways.

The four caller-gated dialogs were correct today; the gate now sits inside the method, so the file proves its own guarantee instead of borrowing one.

image_service was not a baseline entry but a live bug. The issue asked to establish first whether a .path read on web is dead code or a blob:-URL leak. It is neither: PlatformFile.path throws a bare String there (file_picker 5.5.0, platform_file.dart line 37). Anyone pressing "Bestand kiezen" on a video or audio slide in the web build got an uncaught error, and none of the four callers gated. Two places in check_conventions.dart asserted the blob story — the rule header and the failure message a developer actually reads — and both are corrected with the date and the source.

settings_dialog and file_service hit the class-size ratchet, which turned out to be a hint rather than an obstacle: the gate belonged once per library in a top-level function, not once per picker. FileService 2885 → 2879, locked in.

No test can prove any of this — kIsWeb is always false under flutter test, which is why the gate is static. The proof is the empty list, and make check-conventions reporting a stale entry itself (which it did three times on the way, each time confirming a fix had landed).

Closing.

Done in #565 — the baseline is empty. Each of the seven got its own decision, as asked, and they came out three different ways. **The four caller-gated dialogs** were correct today; the gate now sits inside the method, so the file proves its own guarantee instead of borrowing one. **`image_service` was not a baseline entry but a live bug.** The issue asked to establish first whether a `.path` read on web is dead code or a blob:-URL leak. It is neither: `PlatformFile.path` **throws** a bare String there (file_picker 5.5.0, `platform_file.dart` line 37). Anyone pressing "Bestand kiezen" on a video or audio slide in the web build got an uncaught error, and none of the four callers gated. Two places in `check_conventions.dart` asserted the blob story — the rule header and the failure message a developer actually reads — and both are corrected with the date and the source. **`settings_dialog` and `file_service`** hit the class-size ratchet, which turned out to be a hint rather than an obstacle: the gate belonged once per library in a top-level function, not once per picker. `FileService` 2885 → 2879, locked in. No test can prove any of this — `kIsWeb` is always false under `flutter test`, which is why the gate is static. The proof is the empty list, and `make check-conventions` reporting a stale entry itself (which it did three times on the way, each time confirming a fix had landed). Closing.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#528
No description provided.