Fix QR scanner to accept fountain coding for BC-UR codes (#3048)
What changed, and why it matters
This commit updates the QR code scanner in Cake Wallet so it can correctly track progress when scanning multi-part BC-UR QR codes (a format used for things like crypto transaction signing). It replaces a hand-rolled progress check with a dedicated 'fountain decoder' library. There is no direct evidence this fixes a security vulnerability; it appears to be a reliability/UX improvement for scanning animated QR codes.
Treat as a normal functional/UX fix. No immediate security action required. If reviewing further, verify that the ur package dependency is from a trusted source and that decoder.receivePart() handles malformed 'ur:' strings safely, though the diff itself does not introduce obvious risk.
Security signals we found
No security-relevant keywords in commit title or message
No input sanitization changes observed
No cryptographic or authentication logic changes observed
Change is confined to QR scanning progress UI and decoder state
No references to CVEs, vulnerabilities, or security reports in commit or diff
Evidence from the diff
The change modifies lib/entities/qr_scanner.dart to use the ur package’s URDecoder class for BC-UR QR scanning. Previously the code used a local URQRToURQRData helper to estimate completion. Now it feeds each scanned ‘ur:’ part into decoder.receivePart() and queries decoder.estimatedPercentComplete(), expectedPartCount(), processedPartsCount(), and receivedPartIndexes() to drive UI progress. The commit title and message frame this as supporting fountain coding for BC-UR codes. No input validation, sanitization, or cryptographic handling changes are visible in the diff.
Changed components
lib/entities/qr_scanner.dartQR scanner UI progress indicatorBC-UR multi-part QR decoding flowInspect captured patch +10 / −7
diff --git a/lib/entities/qr_scanner.dart b/lib/entities/qr_scanner.dart
index 31353a8f..e62a625b 100644
--- a/lib/entities/qr_scanner.dart
+++ b/lib/entities/qr_scanner.dart
@@ -7,6 +7,7 @@ import 'package:cw_core/utils/print_verbose.dart';
import 'package:fast_scanner/fast_scanner.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
+import 'package:ur/ur_decoder.dart';
var isQrScannerShown = false;
@@ -42,6 +43,7 @@ class _BarcodeScannerSimpleState extends State<BarcodeScannerSimple> {
List<String> urCodes = [];
late var ur = URQRToURQRData(urCodes);
+ final decoder = URDecoder();
void _handleBarcode(BarcodeCapture barcodes) {
try {
@@ -70,11 +72,12 @@ class _BarcodeScannerSimpleState extends State<BarcodeScannerSimple> {
if (barcode.rawValue?.trim().isEmpty ?? false == false) continue;
if (barcode.rawValue!.startsWith("ur:")) {
if (urCodes.contains(barcode.rawValue)) continue;
+ decoder.receivePart(barcode.rawValue!);
setState(() {
urCodes.add(barcode.rawValue!);
ur = URQRToURQRData(urCodes);
});
- if (ur.progress == 1) {
+ if (decoder.estimatedPercentComplete() == 1) {
setState(() {
popped = true;
});
@@ -118,10 +121,10 @@ class _BarcodeScannerSimpleState extends State<BarcodeScannerSimple> {
onDetect: _handleBarcode,
controller: ctrl,
),
- if (ur.inputs.length != 0)
+ if (decoder.expectedPartCount() != null)
Center(
child: Text(
- "${ur.inputs.length}/${ur.count}",
+ "${decoder.processedPartsCount()}/${decoder.expectedPartCount()!}",
style: Theme.of(context)
.textTheme
.displayLarge
@@ -136,10 +139,10 @@ class _BarcodeScannerSimpleState extends State<BarcodeScannerSimple> {
child: CustomPaint(
painter: ProgressPainter(
urQrProgress: URQrProgress(
- expectedPartCount: ur.count - 1,
- processedPartsCount: ur.inputs.length,
- receivedPartIndexes: _urParts(),
- percentage: ur.progress,
+ expectedPartCount: decoder.expectedPartCount() ?? 0,
+ processedPartsCount: decoder.processedPartsCount(),
+ receivedPartIndexes: decoder.receivedPartIndexes().toList(),
+ percentage: decoder.estimatedPercentComplete(),
),
),
),
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.