What changed, and why it matters
This commit adds safety checks before closing on-screen dialogs and showing confirmation messages. It prevents the app from crashing or behaving oddly if a screen is no longer active when a backup finishes saving or a Ledger hardware wallet reconnects. There is no indication this is a security fix, and it does not appear exploitable by an attacker.
No security action required. Treat as a routine stability/UI polish fix. If auditing, verify no other unguarded Navigator.pop calls exist in async callbacks.
Security signals we found
UI lifecycle hardening only
No trust boundary crossed
No input validation, cryptography, or authorization changes
No memory safety, injection, or secret-handling changes
Evidence from the diff
Two Flutter UI hardening changes: (1) In backup_page.dart, the save-and-share flow now verifies dialogContext.mounted/canPop and context.mounted/canPop before popping a dialog and showing a SnackBar after saving a backup. (2) In ledger_view_model.dart, the Ledger reconnect callback now checks Navigator.canPop() in addition to context.mounted before popping. These are defensive null-state/lifecycle fixes that avoid calling Navigator.pop on an unmounted or non-poppable route.
Changed components
lib/src/screens/backup/backup_page.dartlib/view_model/hardware_wallet/ledger_view_model.dartInspect captured patch +7 / −3
diff --git a/lib/src/screens/backup/backup_page.dart b/lib/src/screens/backup/backup_page.dart
index 59abff99..34ec4a74 100644
--- a/lib/src/screens/backup/backup_page.dart
+++ b/lib/src/screens/backup/backup_page.dart
@@ -154,8 +154,12 @@ class BackupPage extends BasePage {
leftButtonText: S.of(context).share,
actionRightButton: () async {
await backupViewModelBase.saveToDownload(backup.name, backup.file);
- Navigator.of(dialogContext).pop();
- await showBar<void>(context, S.of(context).file_saved);
+ if (dialogContext.mounted && Navigator.canPop(dialogContext)) {
+ Navigator.of(dialogContext).pop();
+ }
+ if (context.mounted && Navigator.canPop(context)) {
+ await showBar<void>(context, S.of(context).file_saved);
+ }
},
actionLeftButton: () async {
Navigator.of(dialogContext).pop();
diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart
index c0746223..5e77473d 100644
--- a/lib/view_model/hardware_wallet/ledger_view_model.dart
+++ b/lib/view_model/hardware_wallet/ledger_view_model.dart
@@ -161,7 +161,7 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
allowChangeWallet: true,
isReconnect: true,
onConnectDevice: (context, ledgerVM) async {
- if (context.mounted) {
+ if (context.mounted && Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
},
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.