Skip to content

Commit 4ea18ec

Browse files
committed
Detect invalid short options in aggregations
1 parent 7999357 commit 4ea18ec

2 files changed

Lines changed: 55 additions & 13 deletions

File tree

de.tototec.cmdoption/src/main/java/de/tototec/cmdoption/CmdlineParser.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ public String apply() {
401401
debugMode = true;
402402
debug("Enabled debug mode\n" + debugState(""));
403403
}
404-
404+
continue;
405405
} else if (parseOptions && quickOptionMap.containsKey(param)) {
406406
// Found an option
407407
final OptionHandle optionHandle = quickOptionMap.get(param);
@@ -450,6 +450,7 @@ public String apply() {
450450
throw new CmdlineParserException(msg.notr(), e, msg.tr());
451451
}
452452
}
453+
continue;
453454
} else if (parseOptions && quickCommandMap.containsKey(param)) {
454455
// Found a command
455456
final CommandHandle commandHandle = quickCommandMap.get(param);
@@ -461,19 +462,29 @@ public String apply() {
461462
Arrays.copyOfRange(rest, index + 1, rest.length));
462463
// Stop parsing
463464
break;
464-
} else if (parseOptions
465+
}
466+
467+
if (parseOptions
465468
&& aggregateShortOptionsWithPrefix.isDefined()
466469
&& param.startsWith(aggregatePrefix)
467470
&& param.length() > aggregatePrefixSize + 1) {
471+
468472
// Found an aggregated short option
473+
474+
// if true, the match is not a valid option aggrgation and
475+
// should later be handled as normal parameter
476+
boolean failed = false;
477+
469478
final char[] singleOptions = param.substring(aggregatePrefixSize).toCharArray();
470479
// rewrite the cmdline
471480
final List<String> rewritten = new LinkedList<String>();
472481
int procCount = 1;
473482
for (final char c : singleOptions) {
474483
final OptionHandle oh = shortOptionMap.get(String.valueOf(c));
475484
if (oh == null) {
476-
// FIXME: unsupported aggregation found
485+
// unsupported aggregation found
486+
failed = true;
487+
break;
477488
}
478489
if (rest.length < procCount + oh.getArgsCount()) {
479490
// FIXME: missing args detected
@@ -495,15 +506,18 @@ public String apply() {
495506
++procCount;
496507
}
497508
}
498-
// re-interate parsing with the modified command line
499-
// (backtracking)
500-
final String[] newRest = Arrays.copyOfRange(rest, procCount, rest.length);
501-
rewritten.addAll(Arrays.asList(newRest));
502-
rest = rewritten.toArray(new String[0]);
503-
index = -1;
504-
continue;
509+
if (!failed) {
510+
// re-interate parsing with the modified command line
511+
// (backtracking)
512+
final String[] newRest = Arrays.copyOfRange(rest, procCount, rest.length);
513+
rewritten.addAll(Arrays.asList(newRest));
514+
rest = rewritten.toArray(new String[0]);
515+
index = -1;
516+
continue;
517+
}
518+
}
505519

506-
} else if (parameter == null && defaultCommandName != null
520+
if (parameter == null && defaultCommandName != null
507521
&& quickCommandMap.containsKey(defaultCommandName)) {
508522
// Assume a default command inserted here
509523
debug("Unsupported option '" + param + "' found, assuming default command: " + defaultCommandName);

de.tototec.cmdoption/src/test/java/de/tototec/cmdoption/AggregateShortOptionsTest.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public static class Config {
1919
boolean showSize = false;
2020
}
2121

22+
public static class Param {
23+
@CmdOption(args = { "PARAMETER" })
24+
String param;
25+
}
26+
2227
public AggregateShortOptionsTest() {
2328

2429
test("Setting all short options separate should work (reference test)", () -> {
@@ -74,11 +79,34 @@ public AggregateShortOptionsTest() {
7479
final Config config = new Config();
7580
final CmdlineParser cp = new CmdlineParser(config);
7681
cp.setAggregateShortOptionsWithPrefix("-");
77-
intercept(CmdlineParserException.class, "\\QMissing argument(s): FILE. Option \"-f\" requires 1 arguments, but you gave 0.\\E", () -> {
78-
cp.parse(new String[] { "-lfs" });
82+
intercept(CmdlineParserException.class,
83+
"\\QMissing argument(s): FILE. Option \"-f\" requires 1 arguments, but you gave 0.\\E", () -> {
84+
cp.parse(new String[] { "-lfs" });
85+
});
86+
});
87+
88+
test("Comnbining unknown short options should fail", () -> {
89+
final Config config = new Config();
90+
final CmdlineParser cp = new CmdlineParser(config);
91+
cp.setAggregateShortOptionsWithPrefix("-");
92+
intercept(CmdlineParserException.class, "\\QUnsupported option or parameter found: -lsa\\E", () -> {
93+
// "-a" is an unknown option
94+
cp.parse(new String[] { "-lsa" });
7995
});
8096
});
8197

98+
test("Comnbining unknown short options should result in combined options parsed as main parameter", () -> {
99+
final Config config = new Config();
100+
final Param param = new Param();
101+
final CmdlineParser cp = new CmdlineParser(config, param);
102+
cp.setAggregateShortOptionsWithPrefix("-");
103+
// "-a" is an unknown option
104+
cp.parse(new String[] { "-lsa" });
105+
expectFalse(config.formatLong);
106+
expectFalse(config.showSize);
107+
expectEquals(config.file, null);
108+
expectEquals(param.param, "-lsa");
109+
});
82110

83111
}
84112

0 commit comments

Comments
 (0)