diff --git a/apache-maven/src/assembly/maven/bin/mvn b/apache-maven/src/assembly/maven/bin/mvn index 1a8e6a2fdccc..914f61a42b78 100755 --- a/apache-maven/src/assembly/maven/bin/mvn +++ b/apache-maven/src/assembly/maven/bin/mvn @@ -275,7 +275,7 @@ handle_args() { handle_args "$@" MAVEN_MAIN_CLASS=${MAVEN_MAIN_CLASS:=org.apache.maven.cling.MavenCling} -# Build command string for eval +# Build base command string for eval (only contains Maven-controlled values) cmd="\"$JAVACMD\" \ $MAVEN_OPTS \ $MAVEN_DEBUG_OPTS \ @@ -289,14 +289,12 @@ cmd="\"$JAVACMD\" \ $LAUNCHER_CLASS \ $MAVEN_ARGS" -# Add remaining arguments with proper quoting -for arg in "$@"; do - cmd="$cmd \"$arg\"" -done - if [ -n "$MAVEN_DEBUG_SCRIPT" ]; then echo "[DEBUG] Launching JVM with command:" >&2 - echo "[DEBUG] $cmd" >&2 + echo "[DEBUG] $cmd" "$@" >&2 fi -eval exec "$cmd" +# User arguments ("$@") are passed directly to preserve literal values +# like ${...} Maven property placeholders without shell expansion. +# Only the base command uses eval for MAVEN_OPTS word splitting. +eval exec "$cmd" '"$@"' diff --git a/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11978PlaceholderInCliArgTest.java b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11978PlaceholderInCliArgTest.java new file mode 100644 index 000000000000..2262fb2f86e1 --- /dev/null +++ b/its/core-it-suite/src/test/java/org/apache/maven/it/MavenITgh11978PlaceholderInCliArgTest.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.it; + +import java.nio.file.Path; +import java.util.Properties; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * This is a test set for gh-11978. + * + * Verifies that the launcher script does not expand ${...} patterns + * in CLI arguments. Regression test for the {@code eval exec} shell expansion + * that broke any argument containing Maven property placeholders. + */ +class MavenITgh11978PlaceholderInCliArgTest extends AbstractMavenIntegrationTestCase { + + @Test + void testIt() throws Exception { + Path basedir = extractResources("/gh-11978-placeholder-in-cli-arg") + .getAbsoluteFile() + .toPath(); + + Verifier verifier = newVerifier(basedir.toString()); + verifier.setForkJvm(true); // NOTE: We want to go through the launcher script + // CLI argument with ${...} placeholder that the shell must NOT expand + verifier.addCliArgument("-Dtest.placeholder=value_${some.placeholder}"); + verifier.addCliArgument("validate"); + verifier.execute(); + verifier.verifyErrorFreeLog(); + + Properties props = verifier.loadProperties("target/pom.properties"); + // Maven property substitution then resolves ${some.placeholder} (empty here). + // The key point: the script did not crash with "bad substitution" and the + // literal ${...} arrived at Java for Maven to handle. + assertEquals("-value_-", props.getProperty("project.properties.pom.placeholder")); + } +} diff --git a/its/core-it-suite/src/test/resources/gh-11978-placeholder-in-cli-arg/pom.xml b/its/core-it-suite/src/test/resources/gh-11978-placeholder-in-cli-arg/pom.xml new file mode 100644 index 000000000000..b55ef8a12088 --- /dev/null +++ b/its/core-it-suite/src/test/resources/gh-11978-placeholder-in-cli-arg/pom.xml @@ -0,0 +1,58 @@ + + + + 4.0.0 + + org.apache.maven.its.gh11978 + test + 1.0 + + Maven Integration Test :: GH-11978 + Verify that the launcher script does not expand ${...} placeholders in CLI arguments. + + + -${test.placeholder}- + + + + + + org.apache.maven.its.plugins + maven-it-plugin-expression + 2.1-SNAPSHOT + + + test + + eval + + validate + + target/pom.properties + + project/properties + + + + + + + +