reject unknown command line options and values given to flags with an error and exit code instead of starting on the default network, and accept the --option=value form
What changed, and why it matters
This commit tightens how Sparrow Wallet handles command-line arguments. Previously, typos or unexpected values could silently be ignored, causing the wallet to start on the default Bitcoin network instead of the one the user intended. Now, unknown options and values mistakenly attached to on/off flags cause the program to print an error and exit. It also adds support for the common `--option=value` syntax. The main risk is operational: a user or script could accidentally connect to the wrong network and not notice, which in a Bitcoin wallet can lead to using the wrong wallet keys or broadcasting transactions on the wrong network.
Users and integrators running Sparrow from scripts should review command-line invocations to ensure they do not rely on previously tolerated typos or `--flag=value` for boolean options. Upgrade to the patched version to avoid accidental default-network startup. No immediate incident response is indicated by the diff alone.
Security signals we found
Command-line argument parsing now rejects unknown options instead of silently ignoring them
Boolean flags now reject `--flag=value` forms that would otherwise silently pass the value through as a file/URI argument
Program now exits with non-zero status on argument errors, reducing risk of unintended default-network startup
Supports `--option=value` syntax, which can reduce user surprise and scripting errors
Evidence from the diff
The patch modifies Args.java to declare @Parameters(separators = "="), enabling JCommander’s --option=value parsing. In SparrowWallet.java, it changes the JCommander setup from acceptUnknownOptions(true) with silent swallowing to explicit post-parse validation: unknown options beginning with - now throw a ParameterException, and boolean flags reject the name=value form. A caught ParameterException prints to stderr, shows usage, and exits with code 1. This prevents silently discarded arguments from falling through to the default Network.MAINNET when the user intended, for example, --network testnet.
Changed components
src/main/java/com/sparrowwallet/sparrow/Args.javasrc/main/java/com/sparrowwallet/sparrow/SparrowWallet.javaJCommander-based CLI argument parsingNetwork selection behavior at startupInspect captured patch +26 / −1
### src/main/java/com/sparrowwallet/sparrow/Args.java
@@ -1,12 +1,14 @@
package com.sparrowwallet.sparrow;
import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
import com.sparrowwallet.drongo.Network;
import org.slf4j.event.Level;
import java.util.ArrayList;
import java.util.List;
+@Parameters(separators = "=")
public class Args {
@Parameter(names = { "--dir", "-d" }, description = "Path to Sparrow home folder")
public String dir;
### src/main/java/com/sparrowwallet/sparrow/SparrowWallet.java
@@ -1,6 +1,8 @@
package com.sparrowwallet.sparrow;
import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterDescription;
+import com.beust.jcommander.ParameterException;
import com.sparrowwallet.drongo.ApplicationDir;
import com.sparrowwallet.drongo.Drongo;
import com.sparrowwallet.drongo.Network;
@@ -39,7 +41,28 @@ public static void main(String[] argv) {
Args args = new Args();
JCommander jCommander = JCommander.newBuilder().addObject(args).programName(APP_NAME.toLowerCase(Locale.ROOT)).acceptUnknownOptions(true).build();
- jCommander.parse(argv);
+ try {
+ jCommander.parse(argv);
+ Optional<String> unknownOption = jCommander.getUnknownOptions().stream().filter(arg -> arg.startsWith("-")).findFirst();
+ if(unknownOption.isPresent()) {
+ throw new ParameterException("Unknown option: " + unknownOption.get());
+ }
+ //Flags take no value, and the = separator would otherwise set the flag and pass the value on as a file or URI
+ for(ParameterDescription description : jCommander.getParameters()) {
+ if(description.getParameterized().getType() == boolean.class) {
+ for(String name : description.getParameter().names()) {
+ if(Arrays.stream(argv).anyMatch(arg -> arg.startsWith(name + "="))) {
+ throw new ParameterException("Option " + name + " does not take a value");
+ }
+ }
+ }
+ }
+ } catch(ParameterException e) {
+ System.err.println(e.getMessage());
+ jCommander.usage();
+ System.exit(1);
+ }
+
if(args.help) {
jCommander.usage();
System.exit(0);Why this scored 37/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.