fix: handle flushbar dismissal
What changed, and why it matters
This commit fixes how the app dismisses on-screen notification banners (called 'flushbars') during login. Previously, the code tried to dismiss a banner even when it wasn't currently shown, which could cause the app to crash or behave oddly. The new helper checks whether the banner is actually visible before dismissing it, and removes it from the navigation stack if it isn't. The change is a stability fix rather than a security vulnerability.
Treat as a routine stability/UX fix. No immediate security action required. If auditing, verify that no other flushbar dismissals in the codebase have the same unguarded pattern.
Security signals we found
UI state handling bug fix
Potential null/invalid route dereference mitigated
No explicit security claim in commit message or diff
Evidence from the diff
The patch replaces direct calls to Flushbar.dismiss() with a new _removeBar() helper that guards dismissal. It checks whether the Flushbar’s route exists and is active, then either dismisses the visible flushbar or removes its route from the navigator. The integration test file change removes an unused import and a frame-policy setting, which appears unrelated to the flushbar fix.
Changed components
lib/src/screens/auth/auth_page.dartintegration_test/core/app_launcher.dartInspect captured patch +17 / −6
### integration_test/core/app_launcher.dart
@@ -3,15 +3,11 @@ import "dart:async";
import "package:cake_wallet/main.dart" as app;
import "package:flutter/foundation.dart";
import "package:flutter_test/flutter_test.dart";
-import "package:integration_test/integration_test.dart";
import "benign_errors.dart";
void integrationTest(String description, Future<void> Function(WidgetTester tester) body) {
testWidgets(description, (tester) async {
- IntegrationTestWidgetsFlutterBinding.instance.framePolicy =
- LiveTestWidgetsFlutterBindingFramePolicy.fullyLive;
-
final completer = Completer<void>();
final run = runZonedGuarded(() async {
### lib/src/screens/auth/auth_page.dart
@@ -116,9 +116,9 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
/// not the best scenario, but WidgetsBinding is not behaving correctly on Android
await Future<void>.delayed(Duration(milliseconds: 50));
- await _authBar?.dismiss();
+ await _removeBar(_authBar);
await Future<void>.delayed(Duration(milliseconds: 50));
- await _progressBar?.dismiss();
+ await _removeBar(_progressBar);
await Future<void>.delayed(Duration(milliseconds: 50));
if (route != null) {
Navigator.of(_key.currentContext!).pushReplacementNamed(route, arguments: arguments);
@@ -153,6 +153,21 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
);
}
+ Future<void> _removeBar(Flushbar<void>? bar) async {
+ final barRoute = bar?.flushbarRoute;
+
+ if (bar == null || barRoute == null || !barRoute.isActive) {
+ return;
+ }
+
+ if (bar.isShowing()) {
+ await bar.dismiss();
+ return;
+ }
+
+ barRoute.navigator?.removeRoute(barRoute);
+ }
+
void dismissFlushBar(Flushbar<dynamic>? bar) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await bar?.dismiss();Why this scored 23/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.