[Bug] Image carousel picker reads a blob: path on web, and its callers are ungated #526
Labels
No labels
accepted
bug
declined
docs
duplicate
enhancement
good first issue
in-progress
needs-info
privacy
security
triage
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
LibreKAT/Ocideck#526
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Describe the bug
_browse()inlib/widgets/dialogs/parts/image_carousel_picker_actions.dart:612calls
FilePicker.pickFileswithoutwithData: trueand then readsresult.files.single.path. On webfile_pickerputs ablob:URL inpath,while the rest of the app expects
mem:keys for browser-held images(
lib/services/image_service.dart:127,lib/models/asset_origin.dart:88).That path is then handed to
captionService.getCaption(path)and returned as anImagePickResult, so the blob URL travels into the deck.Neither caller gates the picker on platform:
lib/widgets/editors/_editor_field.dart:418(_openCarousel)lib/widgets/app_shell_main_layout.dart:646The two
isWebPlatformreferences inapp_shell_main_layout.dart(lines 306 and945) are about other controls.
Same class as #506, different decision
#506 hid the logo picker, because a logo is stored as a filesystem path in the
theme profile and a browser has nothing to put there. That reasoning does not
carry over here. The carousel returns an image for a slide, and the app already
has a browser-side representation for exactly that — the
mem:pipeline. So thehonest options are:
withData: true, then route the bytes through thesame
mem:path the rest of the web build already uses. This is the betteroutcome if the carousel's other half (browsing
searchPaths) is meaningful onweb at all.
about local image folders — in which case
searchPathsis empty on web andthe whole dialog is already close to useless there.
Establish which before writing code: option 1 is more work and only worth it if
the dialog has a reason to exist in a browser.
Regression guard
Same structural limitation as #506:
kIsWebis alwaysfalseunderflutter test, so the broken branch is unreachable and a widget test would sitgreen around it. The guard belongs with #505, which is exactly the shape of
mistake it is meant to catch — a
pickFilesresult whosepathis read withoutwithData.Found while verifying #506, not by a search; there may be more.
Two more instances of the same class, found while refining the #505 gate to look per call site (PR #535):
lib/services/image_service.dart:265—pickVideolib/services/image_service.dart:276—pickAudioBoth read
result?.files.single.pathwith no platform gate, and both sit directly belowpickImageDetailed, which does have a correctif (kIsWeb)branch usingwithData: trueand themem:store. The file therefore looked clean to the original file-level rule. Their callers are ungated too:video_slide_editor.dart:97,finding_editor.dart:655,audio_attachment_editor.dart:23,editor_panel_slide_settings.dart:806.A fourth, different in kind:
lib/services/file_service.dart:957(pickPackageFile) reads.pathand — unlikepickMarkdownFile, which has a bytes-based sibling for web right below it — has no web counterpart at all.Why none of them are fixed yet. The decision is not the same for all four, and it is a product judgement rather than a mechanical one:
pickImageDetailedcan hold an image in memory; holding a video there is a different proposition, and the HTML export already excludes video deliberately. Hiding the buttons on web, as the logo picker was hidden in #506, looks right — but that is worth confirming against what the web build is actually for.mem:pipeline already exists. Delegating_browse()toImageService.pickImageDetailedwould make it work rather than disappear — and would remove a duplicatedFilePickercall at the same time.All four are recorded in
filePickerPathBaselinewith line numbers, somake checkreports them and the list cannot rot silently.