Skip to content

Commit 6f830b4

Browse files
committed
fix(argv): bypass Commons Exec internal argument trimming
The first repair left 11 real-child assertions failing because CommandLine.Argument trims its stored value even with handleQuoting=false. Preserve a separate literal vector at the native launch boundary; do not relax whitespace/newline assertions. No implicit shell parsing, quoting, or substitution is added.
1 parent c93a25c commit 6f830b4

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.github.easy4j.opencli.core;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
import org.apache.commons.exec.CommandLine;
7+
8+
/**
9+
* Internal literal argv bridge. Commons Exec's Argument constructor trims even
10+
* when handleQuoting is false, so raw values cannot be stored in its argument list.
11+
* Keep the original vector and supply it directly to the native launcher instead.
12+
*
13+
* @author <a href="https://github.com/loong10k">Loong Wan</a>
14+
* @since 3.0.0
15+
*/
16+
final class LiteralCommandLine extends CommandLine {
17+
private final List<String> literalArguments = new ArrayList<>();
18+
19+
LiteralCommandLine(String executable) {
20+
super(executable);
21+
}
22+
23+
@Override
24+
public CommandLine addArgument(String argument, boolean handleQuoting) {
25+
if (handleQuoting) {
26+
throw new IllegalArgumentException("Literal argv does not support implicit quoting");
27+
}
28+
literalArguments.add(Objects.requireNonNull(argument, "argument"));
29+
return this;
30+
}
31+
32+
@Override
33+
public String[] getArguments() {
34+
return literalArguments.toArray(new String[0]);
35+
}
36+
37+
@Override
38+
public String[] toStrings() {
39+
String[] result = new String[literalArguments.size() + 1];
40+
result[0] = getExecutable();
41+
for (int i = 0; i < literalArguments.size(); i++) {
42+
result[i + 1] = literalArguments.get(i);
43+
}
44+
return result;
45+
}
46+
}

src/main/java/io/github/easy4j/opencli/core/OpenCliExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ private CommandLine buildCommandLine(List<String> adapterAndRest) {
112112
if (OpenCliStrings.isBlank(exe)) {
113113
throw new IllegalStateException("opencli.executable must not be blank");
114114
}
115-
CommandLine cmd = new CommandLine(exe.trim());
115+
CommandLine cmd = new LiteralCommandLine(exe.trim());
116116
appendLiteralArgs(cmd, properties.getLeadingArguments(), "leadingArguments");
117117
appendLiteralArgs(cmd, adapterAndRest, "adapterAndRest");
118118
return cmd;

0 commit comments

Comments
 (0)