detect legacy multisig descriptors case insensitively when warning about key sorting
What changed, and why it matters
This commit fixes a minor user-facing bug in Sparrow Wallet where the app failed to recognize legacy multisig wallet descriptors if they used uppercase letters (for example, 'MULTI(' instead of 'multi('). As a result, Sparrow would not show its usual warning that it only supports BIP67-compatible sorted multisig wallets, and it would not automatically sort the public keys. The change makes the detection case-insensitive by using a regular expression pattern instead of a simple lowercase string check. This is a usability and correctness fix rather than a serious security vulnerability.
No immediate security action is required. Users and reviewers should verify that the new LEGACY_MULTI_PATTERN correctly matches only legacy multisig descriptors and does not accidentally match sortedmulti or other descriptor types. Review the drongo submodule diff for the regex definition if available.
Security signals we found
Case-insensitive parsing of descriptor strings
Change in validation/warning path for legacy multisig wallets
Submodule update (drongo) likely containing the new regex definition
Evidence from the diff
The patch replaces literal substring checks for ‘multi(’ and ‘(multi(’ with a compiled case-insensitive regex, OutputDescriptor.LEGACY_MULTI_PATTERN, in Bip129.java and SettingsController.java. It also updates the drongo submodule to a newer commit that presumably defines LEGACY_MULTI_PATTERN. The change ensures that descriptors containing ‘multi(‘, ‘MULTI(‘, or other case variants are consistently treated as legacy unsorted multisig descriptors, triggering the appropriate warning and key-sorting behavior.
Changed components
src/main/java/com/sparrowwallet/sparrow/io/Bip129.javasrc/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.javadrongo submoduleInspect captured patch +4 / −3
### drongo
@@ -1 +1 @@
-Subproject commit a47c2b3f58d7cedd504b2bd07833708866614216
+Subproject commit ae0001ce8b42d2584939c5164a27bc588b7cd256
### src/main/java/com/sparrowwallet/sparrow/io/Bip129.java
@@ -325,7 +325,7 @@ private void checkFirstAddress(Wallet wallet, OutputDescriptor outputDescriptor,
return;
}
- if(descriptor.contains("multi(") && !descriptor.contains("sortedmulti(")) {
+ if(OutputDescriptor.LEGACY_MULTI_PATTERN.matcher(descriptor).find()) {
throw new IllegalStateException("The first address in this BSMS record (" + recordAddress + ") does not match the first address of " + firstAddress + " derived by sorting the provided keys");
} else {
throw new IllegalStateException("The first address in this file (" + recordAddress + ") does not match the first address of the provided descriptor (" + firstAddress + "). " +
### src/main/java/com/sparrowwallet/sparrow/wallet/SettingsController.java
@@ -46,6 +46,7 @@
import java.util.stream.Collectors;
import static com.sparrowwallet.drongo.OutputDescriptor.KEY_ORIGIN_PATTERN;
+import static com.sparrowwallet.drongo.OutputDescriptor.LEGACY_MULTI_PATTERN;
import static com.sparrowwallet.drongo.OutputDescriptor.XPUB_PATTERN;
import static com.sparrowwallet.sparrow.AppServices.showErrorDialog;
import static com.sparrowwallet.sparrow.AppServices.showWarningDialog;
@@ -487,7 +488,7 @@ public void editDescriptor(ActionEvent event) {
(walletForm.getWallet().getPolicyType() == PolicyType.MULTI_HD ? "\nKey expressions are shown in canonical order." : ""));
Optional<String> text = dialog.showAndWait();
if(text.isPresent() && !text.get().isEmpty() && !text.get().equals(outputDescriptorString)) {
- if(text.get().contains("(multi(")) {
+ if(LEGACY_MULTI_PATTERN.matcher(text.get()).find()) {
AppServices.showWarningDialog("Legacy multisig wallet detected", "Sparrow supports BIP67 compatible multisig wallets only.\n\nThe public keys will be lexicographically sorted, and the output descriptor represented with sortedmulti.");
}
Why this scored 24/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.