Skip to content

Commit 0c506e3

Browse files
Copilotslachiewicz
andcommitted
Replace Runtime.exec with ProcessBuilder to fix shell metacharacter expansion
Co-authored-by: slachiewicz <[email protected]>
1 parent 3fea7c7 commit 0c506e3

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

src/main/java/org/codehaus/plexus/util/cli/Commandline.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -581,19 +581,39 @@ public Process execute() throws CommandLineException {
581581
File workingDir = shell.getWorkingDirectory();
582582

583583
try {
584-
if (workingDir == null) {
585-
process = Runtime.getRuntime().exec(getCommandline(), environment, workingDir);
586-
} else {
584+
if (workingDir != null) {
587585
if (!workingDir.exists()) {
588586
throw new CommandLineException(
589587
"Working directory \"" + workingDir.getPath() + "\" does not exist!");
590588
} else if (!workingDir.isDirectory()) {
591589
throw new CommandLineException(
592590
"Path \"" + workingDir.getPath() + "\" does not specify a directory.");
593591
}
592+
}
594593

595-
process = Runtime.getRuntime().exec(getCommandline(), environment, workingDir);
594+
// Use ProcessBuilder instead of Runtime.exec() to avoid shell interpretation
595+
// This prevents shell metacharacter expansion (e.g., *, ?, wildcards)
596+
String[] commandline = getRawCommandline();
597+
ProcessBuilder processBuilder = new ProcessBuilder(commandline);
598+
599+
if (workingDir != null) {
600+
processBuilder.directory(workingDir);
596601
}
602+
603+
// Set environment variables
604+
if (environment != null && environment.length > 0) {
605+
Map<String, String> env = processBuilder.environment();
606+
for (String envVar : environment) {
607+
int idx = envVar.indexOf('=');
608+
if (idx > 0) {
609+
String key = envVar.substring(0, idx);
610+
String value = envVar.substring(idx + 1);
611+
env.put(key, value);
612+
}
613+
}
614+
}
615+
616+
process = processBuilder.start();
597617
} catch (IOException ex) {
598618
throw new CommandLineException("Error while executing process.", ex);
599619
}

src/test/java/org/codehaus/plexus/util/cli/CommandlineTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,43 @@ private static void createAndCallScript(File dir, String content) throws Excepti
483483
executeCommandLine(cmd);
484484
}
485485

486+
/**
487+
* Test that asterisk and other special characters are NOT expanded by shell.
488+
* This test verifies the fix for SCM-763 where passwords with asterisks were being expanded.
489+
*/
490+
@Test
491+
void executeWithAsteriskInArgument() throws Exception {
492+
Commandline cmd = new Commandline();
493+
cmd.setWorkingDirectory(baseDir);
494+
cmd.setExecutable("echo");
495+
// Add an argument with asterisk that should NOT be expanded
496+
cmd.createArg().setValue("S8p3r*S3cr3t");
497+
498+
Process process = cmd.execute();
499+
String output = IOUtil.toString(process.getInputStream()).trim();
500+
501+
// The output should contain the literal asterisk, not expanded files
502+
assertEquals("S8p3r*S3cr3t", output);
503+
}
504+
505+
/**
506+
* Test that question mark is NOT expanded by shell.
507+
*/
508+
@Test
509+
void executeWithQuestionMarkInArgument() throws Exception {
510+
Commandline cmd = new Commandline();
511+
cmd.setWorkingDirectory(baseDir);
512+
cmd.setExecutable("echo");
513+
// Add an argument with question mark that should NOT be expanded
514+
cmd.createArg().setValue("test?value");
515+
516+
Process process = cmd.execute();
517+
String output = IOUtil.toString(process.getInputStream()).trim();
518+
519+
// The output should contain the literal question mark, not expanded files
520+
assertEquals("test?value", output);
521+
}
522+
486523
/**
487524
* Execute the command line
488525
*

0 commit comments

Comments
 (0)