This is an automated email from the ASF dual-hosted git repository.

elharo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-jlink-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new 3a466c1  [MJLINK-85] Fix issue with single quoting every argument 
(#212)
3a466c1 is described below

commit 3a466c162f28b0ededda1d2fe39e01156de32740
Author: Marios Trivyzas <5058131+mat...@users.noreply.github.com>
AuthorDate: Mon Dec 2 19:05:56 2024 +0100

    [MJLINK-85] Fix issue with single quoting every argument (#212)
    
    Each argument is first double quoted, but because of the default
    configuration of `org.apache.maven.shared.utils.cli.shell.Shell`
    is also single quoted on top. This leads to a shell command line
    which is not executable.
    
    To fix this, leave the double quoting of each argument as it was,
    disable the single quoting of each argument with `Shell` configuration
    and wrap all the arguments as a whole string with single quotes, so
    that they are passed into `bin/sh -c`, example:
    
    ```
    bin/sh -c '"--module-path" "foo:bar" "--add-modules" "mod1,mod2"'
    ```
---
 .../jlink/AbstractJLinkToolchainExecutor.java      | 16 ++++++++++------
 .../apache/maven/plugins/jlink/JLinkMojoTest.java  | 22 +++++++++++++++++++++-
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git 
a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
 
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
index 15fd7db..1401bb5 100644
--- 
a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
+++ 
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
@@ -41,6 +41,7 @@ import java.io.File;
 import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.SystemUtils;
@@ -72,9 +73,7 @@ abstract class AbstractJLinkToolchainExecutor extends 
AbstractJLinkExecutor {
     public int executeJlink(List<String> jlinkArgs) throws 
MojoExecutionException {
         File jlinkExecutable = getJlinkExecutable();
         getLog().info("Toolchain in maven-jlink-plugin: jlink [ " + 
jlinkExecutable + " ]");
-
-        Commandline cmd = createJLinkCommandLine(jlinkArgs);
-        cmd.setExecutable(jlinkExecutable.getAbsolutePath());
+        Commandline cmd = createJLinkCommandLine(jlinkExecutable, jlinkArgs);
 
         return executeCommand(cmd);
     }
@@ -100,10 +99,15 @@ abstract class AbstractJLinkToolchainExecutor extends 
AbstractJLinkExecutor {
         return Optional.of(jmodsFolder);
     }
 
-    private Commandline createJLinkCommandLine(List<String> jlinkArgs) {
+    static Commandline createJLinkCommandLine(File jlinkExecutable, 
List<String> jlinkArgs) {
         Commandline cmd = new Commandline();
-        jlinkArgs.forEach(arg -> cmd.createArg().setValue("\"" + arg + "\""));
+        // Don't quote every argument with single quote, but instead quote 
them with double quotes
+        // and enclose all of them with single quotes to then be passed to the 
shell command as
+        // /bin/sh -c '<all arguments, each one quoted with double quotes>'
+        cmd.getShell().setQuotedArgumentsEnabled(false);
 
+        String jlinkArgsStr = jlinkArgs.stream().map(arg -> "\"" + arg + 
"\"").collect(Collectors.joining(" "));
+        cmd.setExecutable(jlinkExecutable.getAbsolutePath() + " " + 
jlinkArgsStr);
         return cmd;
     }
 
@@ -148,7 +152,7 @@ abstract class AbstractJLinkToolchainExecutor extends 
AbstractJLinkExecutor {
     private int executeCommand(Commandline cmd) throws MojoExecutionException {
         if (getLog().isDebugEnabled()) {
             // no quoted arguments ???
-            
getLog().debug(CommandLineUtils.toString(cmd.getCommandline()).replaceAll("'", 
""));
+            getLog().debug(CommandLineUtils.toString(cmd.getCommandline()));
         }
 
         CommandLineUtils.StringStreamConsumer err = new 
CommandLineUtils.StringStreamConsumer();
diff --git a/src/test/java/org/apache/maven/plugins/jlink/JLinkMojoTest.java 
b/src/test/java/org/apache/maven/plugins/jlink/JLinkMojoTest.java
index 77d670f..d66678c 100644
--- a/src/test/java/org/apache/maven/plugins/jlink/JLinkMojoTest.java
+++ b/src/test/java/org/apache/maven/plugins/jlink/JLinkMojoTest.java
@@ -18,9 +18,11 @@
  */
 package org.apache.maven.plugins.jlink;
 
+import java.io.File;
 import java.lang.reflect.Field;
 import java.util.List;
 
+import org.apache.maven.shared.utils.cli.Commandline;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -28,7 +30,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class JLinkMojoTest {
 
     @Test
-    void quote_every_argument() throws Exception {
+    void double_quote_every_argument() throws Exception {
         // given
         JLinkMojo mojo = new JLinkMojo();
         Field stripDebug = mojo.getClass().getDeclaredField("stripDebug");
@@ -41,4 +43,22 @@ public class JLinkMojoTest {
         // then
         assertThat(jlinkArgs).noneMatch(arg -> arg.trim().isBlank());
     }
+
+    @Test
+    void single_quotes_shell_command() throws Exception {
+        // given
+        JLinkMojo mojo = new JLinkMojo();
+        Field stripDebug = mojo.getClass().getDeclaredField("stripDebug");
+        stripDebug.setAccessible(true);
+        stripDebug.set(mojo, Boolean.TRUE);
+
+        // when
+        List<String> jlinkArgs = mojo.createJlinkArgs(List.of("foo", "bar"), 
List.of("mvn", "jlink"));
+        Commandline cmdLine = JLinkExecutor.createJLinkCommandLine(new 
File("/path/to/jlink"), jlinkArgs);
+
+        // then
+        assertThat(cmdLine.toString())
+                .isEqualTo(
+                        "/bin/sh -c '/path/to/jlink \"--strip-debug\" 
\"--module-path\" \"foo:bar\" \"--add-modules\" \"mvn,jlink\"'");
+    }
 }

Reply via email to