Skip to content

Commit

Permalink
Handle misplaced options better in the standalone CLI.
Browse files Browse the repository at this point in the history
  • Loading branch information
J08nY committed Aug 19, 2024
1 parent fd7d7ef commit d8965fa
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,9 @@ public class ParserOptions {
private Options options;
private String description;

public ParserOptions(CommandLineParser parser, Options options) {
public ParserOptions(CommandLineParser parser, Options options, String description) {
this.parser = parser;
this.options = options;
}

public ParserOptions(CommandLineParser parser, Options options, String description) {
this(parser, options);
this.description = description;
}

Expand Down
36 changes: 19 additions & 17 deletions common/src/main/java/cz/crcs/ectester/common/cli/TreeParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ public TreeCommandLine parse(Options options, String[] arguments, boolean stopAt
public TreeCommandLine parse(Options options, String[] arguments, Properties properties, boolean stopAtNonOption) throws ParseException {
DefaultParser thisParser = new DefaultParser();
CommandLine cli = thisParser.parse(options, arguments, properties, true);
//System.err.println("arguments " + Arrays.toString(arguments));
//System.err.println("args " + Arrays.toString(args.stream().map(Argument::getName).collect(Collectors.toList()).toArray()));

CommandLine subCli = null;
String[] cliArgs = cli.getArgs();
//System.err.println(Arrays.toString(cliArgs));
String sub = null;
if (cliArgs.length != 0) {
sub = cliArgs[0];
Expand All @@ -74,6 +77,7 @@ public TreeCommandLine parse(Options options, String[] arguments, Properties pro
if (matches.size() == 1) {
sub = matches.get(0);
ParserOptions subparser = parsers.get(sub);
//System.err.println("found sub ->" + sub);
String[] remainingArgs = new String[cliArgs.length - 1];
System.arraycopy(cliArgs, 1, remainingArgs, 0, cliArgs.length - 1);
subCli = subparser.getParser().parse(subparser.getOptions(), remainingArgs, true);
Expand All @@ -92,37 +96,35 @@ public TreeCommandLine parse(Options options, String[] arguments, Properties pro

if (subCli instanceof TreeCommandLine) {
TreeCommandLine subTreeCli = (TreeCommandLine) subCli;

TreeCommandLine lastCli = subTreeCli;
while (lastCli.getNext() != null) {
lastCli = lastCli.getNext();
}

if (lastCli.getArgs().length < requiredArgs) {
throw new MissingArgumentException("Not enough arguments: " + reqArgs);
}
//else if (lastCli.getArgs().length > maxArgs) {
// throw new MissingArgumentException("Too many arguments.");
//}

subTreeCli.setName(sub);
return new TreeCommandLine(cli, subTreeCli);
} else if (subCli != null) {
//System.err.println("subCli " + subCli.getArgs().length + " maxArgs " + maxArgs);
if (subCli.getArgs().length < requiredArgs) {
throw new MissingArgumentException("Not enough arguments: " + reqArgs);
} else if (subCli.getArgs().length > maxArgs) {
throw new MissingArgumentException("Too many arguments.");
for (String arg : subCli.getArgs()) {
if (arg.startsWith("-")) {
throw new UnrecognizedOptionException("Option " + arg + " not recognized.");
}
}
throw new MissingArgumentException("Too many arguments: " + Arrays.toString(cliArgs));
}

TreeCommandLine subTreeCli = new TreeCommandLine(sub, subCli, null);
return new TreeCommandLine(cli, subTreeCli);
} else {
//System.err.println("cliArgs " + cliArgs.length + " maxArgs " + maxArgs);
if (cliArgs.length < requiredArgs) {
throw new MissingArgumentException("Not enough arguments: " + reqArgs);
} else if (cliArgs.length > maxArgs) {
for (String arg : cliArgs) {
if (arg.startsWith("-")) {
throw new UnrecognizedOptionException("Option " + arg + " not recognized.");
}
}
throw new MissingArgumentException("Too many arguments: " + Arrays.toString(cliArgs));
}
//else if (cliArgs.length > maxArgs) {
// throw new MissingArgumentException("Too many arguments.");
//}

return new TreeCommandLine(cli, null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
testOpts.addOption(Option.builder().longOpt("key-type").desc("Set the key [algorithm] for which the key should be derived in KeyAgreements with KDF. Default is \"AES\".").hasArg().argName("algorithm").optionalArg(false).build());
List<Argument> testArgs = new LinkedList<>();
testArgs.add(new Argument("test-suite", "The test suite to run.", true));
ParserOptions test = new ParserOptions(new TreeParser(Collections.emptyMap(), true, testArgs), testOpts, "Test a library.");
testArgs.add(new Argument("lib", "What library to use.", true));
ParserOptions test = new ParserOptions(new TreeParser(Collections.emptyMap(), false, testArgs), testOpts, "Test a library.");
actions.put("test", test);

Options ecdhOpts = new Options();
Expand All @@ -273,7 +274,9 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
ecdhOpts.addOption(Option.builder().longOpt("fixed-private").desc("Perform ECDH with fixed private key.").build());
ecdhOpts.addOptionGroup(privateKey);
ecdhOpts.addOption(Option.builder().longOpt("fixed-public").desc("Perform ECDH with fixed public key.").build());
ParserOptions ecdh = new ParserOptions(new DefaultParser(), ecdhOpts, "Perform EC based KeyAgreement.");
List<Argument> ecdhArgs = new LinkedList<>();
ecdhArgs.add(new Argument("lib", "What library to use.", true));
ParserOptions ecdh = new ParserOptions(new TreeParser(Collections.emptyMap(), false, ecdhArgs), ecdhOpts, "Perform EC based KeyAgreement.");
actions.put("ecdh", ecdh);

Options ecdsaOpts = new Options();
Expand All @@ -289,7 +292,9 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
ecdsaOpts.addOption(Option.builder("t").longOpt("type").desc("Set Signature object [type].").hasArg().argName("type").optionalArg(false).build());
ecdsaOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Do ECDSA [amount] times.").build());
ecdsaOpts.addOptionGroup(ecdsaMessage);
ParserOptions ecdsa = new ParserOptions(new DefaultParser(), ecdsaOpts, "Perform EC based Signature.");
List<Argument> ecdsaArgs = new LinkedList<>();
ecdsaArgs.add(new Argument("lib", "What library to use.", true));
ParserOptions ecdsa = new ParserOptions(new TreeParser(Collections.emptyMap(), false, ecdsaArgs), ecdsaOpts, "Perform EC based Signature.");
actions.put("ecdsa", ecdsa);

Options generateOpts = new Options();
Expand All @@ -301,14 +306,18 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
generateOpts.addOption(prngSeed);
generateOpts.addOption(Option.builder("n").longOpt("amount").hasArg().argName("amount").optionalArg(false).desc("Generate [amount] of EC keys.").build());
generateOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPairGenerator object [type].").build());
ParserOptions generate = new ParserOptions(new DefaultParser(), generateOpts, "Generate EC keypairs.");
List<Argument> generateArgs = new LinkedList<>();
generateArgs.add(new Argument("lib", "What library to use.", true));
ParserOptions generate = new ParserOptions(new TreeParser(Collections.emptyMap(), false, generateArgs), generateOpts, "Generate EC keypairs.");
actions.put("generate", generate);

Options exportOpts = new Options();
exportOpts.addOption(bits);
exportOpts.addOption(outputRaw);
exportOpts.addOption(Option.builder("t").longOpt("type").hasArg().argName("type").optionalArg(false).desc("Set KeyPair object [type].").build());
ParserOptions export = new ParserOptions(new DefaultParser(), exportOpts, "Export default curve parameters.");
List<Argument> exportArgs = new LinkedList<>();
exportArgs.add(new Argument("lib", "What library to use.", true));
ParserOptions export = new ParserOptions(new TreeParser(Collections.emptyMap(), false, exportArgs), exportOpts, "Export default curve parameters.");
actions.put("export", export);

Options listDataOpts = new Options();
Expand All @@ -318,7 +327,9 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
actions.put("list-data", listData);

Options listLibsOpts = new Options();
ParserOptions listLibs = new ParserOptions(new DefaultParser(), listLibsOpts, "List supported libraries.");
List<Argument> listLibsArgs = new LinkedList<>();
listLibsArgs.add(new Argument("lib", "What library to use.", false));
ParserOptions listLibs = new ParserOptions(new TreeParser(Collections.emptyMap(), false, listLibsArgs), listLibsOpts, "List supported libraries.");
actions.put("list-libs", listLibs);

Options listSuitesOpts = new Options();
Expand All @@ -329,9 +340,7 @@ private TreeCommandLine parseArgs(String[] args) throws ParseException {
ParserOptions listIdents = new ParserOptions(new DefaultParser(), listIdentsOpts, "List KeyPairGenerator, KeyAgreement and Signature types.");
actions.put("list-types", listIdents);

List<Argument> baseArgs = new LinkedList<>();
baseArgs.add(new Argument("lib", "What library to use.", false));
optParser = new TreeParser(actions, false, baseArgs);
optParser = new TreeParser(actions, false);

opts.addOption(Option.builder("V").longOpt("version").desc("Print version info.").build());
opts.addOption(Option.builder("h").longOpt("help").desc("Print help(about <command>).").hasArg().argName("command").optionalArg(true).build());
Expand Down

0 comments on commit d8965fa

Please sign in to comment.