Documenteditor kan na sluiten crashen terwijl slim plakken nog wacht #1665

Closed
opened 2026-08-21 12:02:01 +00:00 by brenno · 1 comment
Owner

Probleem

Slim plakken wacht achtereenvolgens op beeldimport en meerdere klembordaanroepen. Na die awaits wordt zonder mounted-controle de editor/controller/ref gebruikt. Als het documenttabblad in de tussentijd sluit, kan de vervolgcode een disposed State, controller of context aanspreken.

Reproductie

  1. Start Slim plakken met een traag klembord-/beeldpad.
  2. Sluit direct het documenttabblad of navigeer weg.
  3. Laat de async klembordoperatie afronden.

Verwacht

Na dispose stopt de plakactie stil en raakt zij geen editorstate meer.

Technische aanwijzing

lib/widgets/document_editor_screen.dart:_smartPaste controleert mounted alleen rond meldingen, niet vóór _insertBlock, _insertPastedMarkdown of verdere ref/controller-toegang na awaits. Andere async invoegpaden doen die controle wel.

Gevonden bij audit van commit d439638c6b.

## Probleem Slim plakken wacht achtereenvolgens op beeldimport en meerdere klembordaanroepen. Na die awaits wordt zonder mounted-controle de editor/controller/ref gebruikt. Als het documenttabblad in de tussentijd sluit, kan de vervolgcode een disposed State, controller of context aanspreken. ## Reproductie 1. Start Slim plakken met een traag klembord-/beeldpad. 2. Sluit direct het documenttabblad of navigeer weg. 3. Laat de async klembordoperatie afronden. ## Verwacht Na dispose stopt de plakactie stil en raakt zij geen editorstate meer. ## Technische aanwijzing lib/widgets/document_editor_screen.dart:_smartPaste controleert mounted alleen rond meldingen, niet vóór _insertBlock, _insertPastedMarkdown of verdere ref/controller-toegang na awaits. Andere async invoegpaden doen die controle wel. Gevonden bij audit van commit d439638c6bd1b519d68d87680cb022b7d5eddc85.
Author
Owner

Triage: accepted

Bevestigd tegen main (e93ef205c). _smartPaste staat in lib/widgets/parts/document_editor_layouts.dart. Na await imageService.pasteImageDetailed(...) volgt direct _insertBlock('![](…)') — de mounted-controle staat pas eromheen bij de snackbar. Hetzelfde geldt na await Clipboard.getData(...) en await readClipboardHtml(): _insertBlock(resolved.text) en _insertPastedMarkdown(resolved.text) draaien zonder controle. Beide raken _controller (na dispose gooit die) en ref.

Andere asynchrone invoegwegen in dit scherm doen die controle wél; dit pad is de uitzondering.

Oplossingsrichting

Na élk await-punt een if (!mounted) return false;, dus vier plekken: na de beeldimport, na Clipboard.getData, na readClipboardHtml, en vóór de laatste invoeging. Geen melding, geen log — de gebruiker heeft het tabblad zelf gesloten; stil stoppen is het juiste gedrag.

Wat ik hier níét zou doen: het use_build_context_synchronously-gat afdekken met een opgeslagen ScaffoldMessengerState. Dat maakt de melding veilig maar laat de echte fout (schrijven naar een weggegooide controller) staan.

Regressietest (verplicht)

test/document_editor_screen_test.dart: nep-klembord/beeldservice met een Completer, tabblad sluiten, dan de future afronden → tester.takeException() is null én de notifier heeft niets ontvangen. Let op dat de test óók de tweede tak (klembord) dekt, niet alleen de beeldtak.

Kosten

Klein. Zelfde klasse als #1636, dat net geland is (d52782f8c) — kijk of daar een patroon of hulpstuk uit is gekomen dat hier hergebruikt kan worden.

Prioriteit

Middelhoog: een crash is zichtbaar en kost onopgeslagen werk.

## Triage: accepted **Bevestigd tegen `main` (e93ef205c).** `_smartPaste` staat in `lib/widgets/parts/document_editor_layouts.dart`. Na `await imageService.pasteImageDetailed(...)` volgt direct `_insertBlock('![](…)')` — de `mounted`-controle staat pas eromheen bij de snackbar. Hetzelfde geldt na `await Clipboard.getData(...)` en `await readClipboardHtml()`: `_insertBlock(resolved.text)` en `_insertPastedMarkdown(resolved.text)` draaien zonder controle. Beide raken `_controller` (na `dispose` gooit die) en `ref`. Andere asynchrone invoegwegen in dit scherm doen die controle wél; dit pad is de uitzondering. ## Oplossingsrichting Na élk `await`-punt een `if (!mounted) return false;`, dus vier plekken: na de beeldimport, na `Clipboard.getData`, na `readClipboardHtml`, en vóór de laatste invoeging. Geen melding, geen log — de gebruiker heeft het tabblad zelf gesloten; stil stoppen is het juiste gedrag. Wat ik hier níét zou doen: het `use_build_context_synchronously`-gat afdekken met een opgeslagen `ScaffoldMessengerState`. Dat maakt de melding veilig maar laat de echte fout (schrijven naar een weggegooide controller) staan. ## Regressietest (verplicht) `test/document_editor_screen_test.dart`: nep-klembord/beeldservice met een `Completer`, tabblad sluiten, dan de future afronden → `tester.takeException()` is null én de notifier heeft niets ontvangen. Let op dat de test óók de tweede tak (klembord) dekt, niet alleen de beeldtak. ## Kosten Klein. Zelfde klasse als #1636, dat net geland is (d52782f8c) — kijk of daar een patroon of hulpstuk uit is gekomen dat hier hergebruikt kan worden. ## Prioriteit Middelhoog: een crash is zichtbaar en kost onopgeslagen werk.
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#1665
No description provided.