What changed, and why it matters
This commit adds safety checks in a buy/sell screen so the app doesn't try to show pop-ups or navigate after the user has already left the page. It also adds a screen-reader label to the close button and reformats some code. There is no clear security vulnerability being fixed.
No security action required. Treat as routine stability/accessibility improvement.
Security signals we found
Defensive null/state guards added around async context use
Accessibility semantic label added to close icon
No input validation, crypto, or authentication changes
Evidence from the diff
The patch adds if (context.mounted) guards before Navigator operations and showPopUp calls in buy_sell_amount_page.dart. In Flutter, using a BuildContext after the widget is unmounted can throw exceptions or cause undefined behavior. The change prevents potential crashes during asynchronous operations. It also adds a leadingSemanticLabel for accessibility and reformats a constructor. No exploit path, privilege escalation, or data exposure is evident from the diff.
Changed components
lib/new-ui/pages/buy_sell/buy_sell_amount_page.dartInspect captured patch +29 / −10
diff --git a/lib/new-ui/pages/buy_sell/buy_sell_amount_page.dart b/lib/new-ui/pages/buy_sell/buy_sell_amount_page.dart
index 79ab64d5..bf04c5ab 100644
--- a/lib/new-ui/pages/buy_sell/buy_sell_amount_page.dart
+++ b/lib/new-ui/pages/buy_sell/buy_sell_amount_page.dart
@@ -76,6 +76,7 @@ class _NewBuySellAmountPageState extends State<NewBuySellAmountPage> {
? null
: "${S.of(context).up_to} ~${widget.buySellViewModel.maxFiatAmount} ${widget.buySellViewModel.fiatCurrency.title}",
leadingIcon: const Icon(Icons.close),
+ leadingSemanticLabel: S.of(context).close,
onLeadingPressed: Navigator.of(context, rootNavigator: true).pop,
),
),
@@ -119,7 +120,9 @@ class _NewBuySellAmountPageState extends State<NewBuySellAmountPage> {
customInputFocusNode.requestFocus();
} else {
await widget.buySellViewModel.changeFiatAmount(amount: amount);
- await navigateToProviders(context);
+ if(context.mounted) {
+ await navigateToProviders(context);
+ }
}
},
),
@@ -159,13 +162,15 @@ class _NewBuySellAmountPageState extends State<NewBuySellAmountPage> {
.contains(widget.buySellViewModel.paymentMethodState.runtimeType),);
if (widget.buySellViewModel.paymentMethodState is PaymentMethodFailed) {
- await showPopUp(
+ if(context.mounted) {
+ await showPopUp(
context: context,
builder: (context) => AlertWithOneAction(
- alertTitle: S.of(context).failed_to_load_payment_methods,
- alertContent: S.of(context).please_try_again_later,
- buttonText: "OK",
- buttonAction: Navigator.of(context).pop,),);
+ alertTitle: S.of(context).failed_to_load_payment_methods,
+ alertContent: S.of(context).please_try_again_later,
+ buttonText: "OK",
+ buttonAction: Navigator.of(context).pop,),);
+ }
return;
}
@@ -176,8 +181,11 @@ class _NewBuySellAmountPageState extends State<NewBuySellAmountPage> {
unawaited(widget.buySellViewModel.calculateBestRate());
final page = BuySellProviderPage(buySellViewModel: widget.buySellViewModel);
- Navigator.of(context).push(CupertinoPageRoute(
- builder: (context) => Material(color: Colors.transparent, child: page),),);
+ if(context.mounted) {
+ unawaited(Navigator.of(context).push(CupertinoPageRoute(
+ builder: (context) => Material(color: Colors.transparent, child: page),),));
+ }
+
} finally {
setState(() {
_isLoadingPaymentMethods = false;
@@ -187,8 +195,19 @@ class _NewBuySellAmountPageState extends State<NewBuySellAmountPage> {
}
class BuySellCustomAmountInput extends StatelessWidget {
- const BuySellCustomAmountInput(
- {required this.fiatCurrency, required this.cryptoCurrency, required this.cryptoAmount, required this.controller, required this.onContinuePressed, required this.isLoading, required this.onChanged, required this.focusNode, required this.hasCurrencySelector, required this.onCurrencySelectorPressed, super.key,});
+ const BuySellCustomAmountInput({
+ required this.fiatCurrency,
+ required this.cryptoCurrency,
+ required this.cryptoAmount,
+ required this.controller,
+ required this.onContinuePressed,
+ required this.isLoading,
+ required this.onChanged,
+ required this.focusNode,
+ required this.hasCurrencySelector,
+ required this.onCurrencySelectorPressed,
+ super.key,
+ });
final FiatCurrency fiatCurrency;
final CryptoCurrency cryptoCurrency;
Why this scored 18/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.