Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/main/java/org/codehaus/plexus/util/cli/Commandline.java
Original file line number Diff line number Diff line change
Expand Up @@ -581,19 +581,39 @@ public Process execute() throws CommandLineException {
File workingDir = shell.getWorkingDirectory();

try {
if (workingDir == null) {
process = Runtime.getRuntime().exec(getCommandline(), environment, workingDir);
} else {
if (workingDir != null) {
if (!workingDir.exists()) {
throw new CommandLineException(
"Working directory \"" + workingDir.getPath() + "\" does not exist!");
} else if (!workingDir.isDirectory()) {
throw new CommandLineException(
"Path \"" + workingDir.getPath() + "\" does not specify a directory.");
}
}

process = Runtime.getRuntime().exec(getCommandline(), environment, workingDir);
// Use ProcessBuilder instead of Runtime.exec() to avoid shell interpretation
// This prevents shell metacharacter expansion (e.g., *, ?, wildcards)
String[] commandline = getRawCommandline();
ProcessBuilder processBuilder = new ProcessBuilder(commandline);

if (workingDir != null) {
processBuilder.directory(workingDir);
}

// Set environment variables
if (environment != null && environment.length > 0) {
Map<String, String> env = processBuilder.environment();
for (String envVar : environment) {
int idx = envVar.indexOf('=');
if (idx > 0) {
String key = envVar.substring(0, idx);
String value = envVar.substring(idx + 1);
env.put(key, value);
}
}
}

process = processBuilder.start();
} catch (IOException ex) {
throw new CommandLineException("Error while executing process.", ex);
}
Expand Down
37 changes: 37 additions & 0 deletions src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,43 @@ private static void createAndCallScript(File dir, String content) throws Excepti
executeCommandLine(cmd);
}

/**
* Test that asterisk and other special characters are NOT expanded by shell.
* This test verifies the fix for SCM-763 where passwords with asterisks were being expanded.
*/
@Test
void executeWithAsteriskInArgument() throws Exception {
Commandline cmd = new Commandline();
cmd.setWorkingDirectory(baseDir);
cmd.setExecutable("echo");
// Add an argument with asterisk that should NOT be expanded
cmd.createArg().setValue("S8p3r*S3cr3t");

Process process = cmd.execute();
String output = IOUtil.toString(process.getInputStream()).trim();

// The output should contain the literal asterisk, not expanded files
assertEquals("S8p3r*S3cr3t", output);
}

/**
* Test that question mark is NOT expanded by shell.
*/
@Test
void executeWithQuestionMarkInArgument() throws Exception {
Commandline cmd = new Commandline();
cmd.setWorkingDirectory(baseDir);
cmd.setExecutable("echo");
// Add an argument with question mark that should NOT be expanded
cmd.createArg().setValue("test?value");

Process process = cmd.execute();
String output = IOUtil.toString(process.getInputStream()).trim();

// The output should contain the literal question mark, not expanded files
assertEquals("test?value", output);
}

/**
* Execute the command line
*
Expand Down
Loading