From 6e3ed0e862a92a9c1eec7face53040969d5c0320 Mon Sep 17 00:00:00 2001 From: Paul Barnes Date: Tue, 15 Jul 2025 16:38:30 -0500 Subject: [PATCH] Issue 289: filter file names one component at a time avoid conflicts between the escapeString and the file separator --- .../DefaultMavenResourcesFiltering.java | 46 ++++++++++++------- .../DefaultMavenResourcesFilteringTest.java | 46 ++++++++++++++++++- .../{ => subfolder}/${pom.version}.txt | 32 ++++++------- 3 files changed, 91 insertions(+), 33 deletions(-) rename src/test/units-files/maven-filename-filtering/{ => subfolder}/${pom.version}.txt (98%) diff --git a/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java index 406330c3..7238b49c 100644 --- a/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java +++ b/src/main/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFiltering.java @@ -23,11 +23,13 @@ import java.io.StringReader; import java.io.StringWriter; import java.nio.charset.Charset; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -476,26 +478,38 @@ private String getRelativeOutputDirectory(MavenResourcesExecution execution) { */ private String filterFileName(String name, List wrappers) throws MavenFilteringException { - Reader reader = new StringReader(name); - for (FilterWrapper wrapper : wrappers) { - reader = wrapper.getReader(reader); - } - - try (StringWriter writer = new StringWriter()) { - char[] buffer = new char[BUFFER_LENGTH]; - int nRead; - while ((nRead = reader.read(buffer, 0, buffer.length)) >= 0) { - writer.write(buffer, 0, nRead); + char[] buffer = new char[BUFFER_LENGTH]; + StringBuilder sb = new StringBuilder(); + Path path = Path.of(name); + Iterator iterator = path.iterator(); + while (iterator.hasNext()) { + String component = iterator.next().toString(); + Reader reader = new StringReader(component); + for (FilterWrapper wrapper : wrappers) { + reader = wrapper.getReader(reader); } - String filteredFilename = writer.toString(); + try (StringWriter writer = new StringWriter()) { + int nRead; + while ((nRead = reader.read(buffer, 0, buffer.length)) >= 0) { + writer.write(buffer, 0, nRead); + } + String filteredComponent = writer.toString(); + sb.append(filteredComponent); + if (iterator.hasNext()) { + sb.append(FileSystems.getDefault().getSeparator()); + } - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("renaming filename " + name + " to " + filteredFilename); + } catch (IOException e) { + throw new MavenFilteringException("Failed filtering filename" + name, e); } - return filteredFilename; - } catch (IOException e) { - throw new MavenFilteringException("Failed filtering filename" + name, e); } + + String filteredFilename = sb.toString(); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("renaming filename " + name + " to " + filteredFilename); + } + return filteredFilename; } } diff --git a/src/test/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFilteringTest.java b/src/test/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFilteringTest.java index 11603683..77cbad50 100644 --- a/src/test/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFilteringTest.java +++ b/src/test/java/org/apache/maven/shared/filtering/DefaultMavenResourcesFilteringTest.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -925,7 +926,7 @@ public void testFilterFileName() throws Exception { Resource resource = new Resource(); resource.setDirectory(unitFilesDir); resource.setFiltering(true); - resource.addInclude("${pom.version}*"); + resource.addInclude("**/${pom.version}*"); resource.setTargetPath("testTargetPath"); MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( @@ -943,6 +944,49 @@ public void testFilterFileName() throws Exception { List files = list(targetPathFile); assertEquals(1, files.size()); + assertEquals("subfolder", filename(files.get(0))); + assertTrue(Files.isDirectory(files.get(0))); + + files = list(files.get(0)); + assertEquals(1, files.size()); + assertEquals("1.0.txt", filename(files.get(0))); + } + + @Test + public void testFilterFileNameWithFileSeparatorAsEscape() throws Exception { + + String unitFilesDir = getBasedir() + "/src/test/units-files/maven-filename-filtering"; + + Resource resource = new Resource(); + resource.setDirectory(unitFilesDir); + resource.setFiltering(true); + resource.addInclude("**/${pom.version}*"); + resource.setTargetPath("testTargetPath"); + + MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( + Collections.singletonList(resource), + outputDirectory, + mavenProject, + "UTF-8", + Collections.emptyList(), + Collections.emptyList(), + new StubSession()); + mavenResourcesExecution.setFilterFilenames(true); + + // more likely to occur on windows, where the file + // separator is the same as the common escape string "\" + mavenResourcesExecution.setEscapeString(FileSystems.getDefault().getSeparator()); + mavenResourcesFiltering.filterResources(mavenResourcesExecution); + + Path targetPathFile = outputDirectory.resolve("testTargetPath"); + + List files = list(targetPathFile); + assertEquals(1, files.size()); + assertEquals("subfolder", filename(files.get(0))); + assertTrue(Files.isDirectory(files.get(0))); + + files = list(files.get(0)); + assertEquals(1, files.size()); assertEquals("1.0.txt", filename(files.get(0))); } diff --git a/src/test/units-files/maven-filename-filtering/${pom.version}.txt b/src/test/units-files/maven-filename-filtering/subfolder/${pom.version}.txt similarity index 98% rename from src/test/units-files/maven-filename-filtering/${pom.version}.txt rename to src/test/units-files/maven-filename-filtering/subfolder/${pom.version}.txt index e0533d99..13a83393 100644 --- a/src/test/units-files/maven-filename-filtering/${pom.version}.txt +++ b/src/test/units-files/maven-filename-filtering/subfolder/${pom.version}.txt @@ -1,16 +1,16 @@ -# 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. +# 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.