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

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


The following commit(s) were added to refs/heads/master by this push:
     new fd5dde5  Prevent infinite loop in 
ManifestResourceTransformer.relocate(...) (#789)
fd5dde5 is described below

commit fd5dde5c7f11d56a85a053f74382e6a5204aef12
Author: Konrad Windszus <[email protected]>
AuthorDate: Thu Mar 5 10:32:26 2026 +0100

    Prevent infinite loop in ManifestResourceTransformer.relocate(...) (#789)
    
    Introduce Relocator.relocateAllClasses() to replace all patterns in a
    given string instead of only the first one and use that.
    Otherwise recursively using Relocator.relocateClass() on already
    relocated string over and over again leads to endless loop when pattern
    is a prefix of the shaded pattern.
    
    This closes #478
---
 .../maven/plugins/shade/relocation/Relocator.java  | 12 +++++++-
 .../plugins/shade/relocation/SimpleRelocator.java  |  9 ++++--
 .../resource/ManifestResourceTransformer.java      |  6 +---
 .../shade/relocation/SimpleRelocatorTest.java      | 15 ++++++++++
 .../resource/ManifestResourceTransformerTest.java  | 35 ++++++++++++++++++++--
 5 files changed, 67 insertions(+), 10 deletions(-)

diff --git 
a/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java 
b/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java
index d3027c4..3a38968 100644
--- a/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java
+++ b/src/main/java/org/apache/maven/plugins/shade/relocation/Relocator.java
@@ -28,7 +28,17 @@ public interface Relocator {
 
     boolean canRelocateClass(String clazz);
 
-    String relocateClass(String clazz);
+    /**
+     * Replace the first class pattern match in the given string
+     * @see #relocateAllClasses(String)
+     */
+    String relocateClass(String input);
 
     String applyToSourceContent(String sourceContent);
+
+    /**
+     * Replace all class pattern matches in the given input.
+     * @see #relocateClass(String)
+     */
+    String relocateAllClasses(String input);
 }
diff --git 
a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java 
b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
index 9d49f77..b801fd0 100644
--- 
a/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
+++ 
b/src/main/java/org/apache/maven/plugins/shade/relocation/SimpleRelocator.java
@@ -208,8 +208,13 @@ public class SimpleRelocator implements Relocator {
     }
 
     @Override
-    public String relocateClass(String clazz) {
-        return rawString ? clazz : clazz.replaceFirst(pattern, shadedPattern);
+    public String relocateClass(String input) {
+        return rawString ? input : input.replaceFirst(pattern, shadedPattern);
+    }
+
+    @Override
+    public String relocateAllClasses(String input) {
+        return rawString ? input : input.replaceAll(pattern, shadedPattern);
     }
 
     @Override
diff --git 
a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
 
b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
index 9ef598b..b9d63b3 100644
--- 
a/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
+++ 
b/src/main/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformer.java
@@ -152,11 +152,7 @@ public class ManifestResourceTransformer extends 
AbstractCompatibilityTransforme
     private String relocate(String originalValue, List<Relocator> relocators) {
         String newValue = originalValue;
         for (Relocator relocator : relocators) {
-            String value;
-            do {
-                value = newValue;
-                newValue = relocator.relocateClass(value);
-            } while (!value.equals(newValue));
+            newValue = relocator.relocateAllClasses(newValue);
         }
         return newValue;
     }
diff --git 
a/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
 
b/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
index 9f7c29d..44afee3 100644
--- 
a/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
+++ 
b/src/test/java/org/apache/maven/plugins/shade/relocation/SimpleRelocatorTest.java
@@ -157,6 +157,21 @@ public class SimpleRelocatorTest {
         assertEquals("private.stuff.bar.Class", 
relocator.relocateClass("org.foo.bar.Class"));
     }
 
+    @Test
+    public void testRelocateAllClasses() {
+        SimpleRelocator relocator;
+
+        relocator = new SimpleRelocator("org.foo", null, null, null);
+        assertEquals(
+                "hidden.org.foo.bar.Class, hidden.hidden.org.foo.bar.Class and 
hidden.org.foo.bar.Class",
+                relocator.relocateAllClasses("org.foo.bar.Class, 
hidden.org.foo.bar.Class and org.foo.bar.Class"));
+
+        relocator = new SimpleRelocator("org.foo", "private.stuff", null, 
null);
+        assertEquals(
+                "private.stuff.bar.Class, private.stuff.bar.Class and 
private.stuff.bar.Class",
+                relocator.relocateAllClasses("org.foo.bar.Class, 
private.stuff.bar.Class and org.foo.bar.Class"));
+    }
+
     @Test
     public void testRelocateRawString() {
         SimpleRelocator relocator;
diff --git 
a/src/test/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformerTest.java
 
b/src/test/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformerTest.java
index ed14ed2..76a1ae7 100644
--- 
a/src/test/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformerTest.java
+++ 
b/src/test/java/org/apache/maven/plugins/shade/resource/ManifestResourceTransformerTest.java
@@ -46,8 +46,7 @@ public class ManifestResourceTransformerTest {
         transformer = new ManifestResourceTransformer();
     }
 
-    @Test
-    public void rewriteDefaultAttributes() throws Exception {
+    private Manifest createTestManifest() {
         final Manifest manifest = new Manifest();
         final Attributes attributes = manifest.getMainAttributes();
         attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0");
@@ -79,6 +78,12 @@ public class ManifestResourceTransformerTest {
                         + "osgi.contract;osgi.contract=JavaInject;"
                         + 
"filter:=\"(&(osgi.contract=JavaInject)(version=1.0.0))\","
                         + 
"osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\"");
+        return manifest;
+    }
+
+    @Test
+    public void rewriteDefaultAttributes() throws Exception {
+        final Manifest manifest = createTestManifest();
 
         List<Relocator> relocators = Collections.<Relocator>singletonList(new 
SimpleRelocator(
                 "javax", "jakarta", Collections.<String>emptyList(), 
Collections.<String>emptyList()));
@@ -118,6 +123,32 @@ public class ManifestResourceTransformerTest {
         }
     }
 
+    @Test()
+    public void rewriteDefaultAttributesWithSameSuffix() throws Exception {
+        final Manifest manifest = createTestManifest();
+
+        List<Relocator> relocators = Collections.<Relocator>singletonList(new 
SimpleRelocator(
+                "javax", "shaded.javax", Collections.<String>emptyList(), 
Collections.<String>emptyList()));
+
+        final ByteArrayOutputStream out = transform(manifest, relocators);
+
+        try (JarInputStream jis = new JarInputStream(new 
ByteArrayInputStream(out.toByteArray()))) {
+            Attributes attrs = jis.getManifest().getMainAttributes();
+            assertEquals(
+                    
"shaded.javax.decorator;version=\"2.0\";uses:=\"shaded.javax.enterprise.inject\",shaded.javax.enterprise.context;version=\"2.0\";uses:=\"shaded.javax.enterprise.util,shaded.javax.inject\"",
+                    attrs.getValue("Export-Package"));
+            assertEquals(
+                    
"shaded.javax.el,shaded.javax.enterprise.context;version=\"[2.0,3)\"",
+                    attrs.getValue("Import-Package"));
+            assertEquals(
+                    
"osgi.contract;osgi.contract=JavaCDI;uses:=\"shaded.javax.enterprise.context,shaded.javax.enterprise.context.spi,shaded.javax.enterprise.context.control,shaded.javax.enterprise.util,shaded.javax.enterprise.inject,shaded.javax.enterprise.inject.spi,shaded.javax.enterprise.inject.spi.configurator,shaded.javax.enterprise.inject.literal,shaded.javax.enterprise.inject.se,shaded.javax.enterprise.event,shaded.javax.decorator\";version:List<Version>=\"2.0,1.2,1.1,1.0\"",
+                    attrs.getValue("Provide-Capability"));
+            assertEquals(
+                    
"osgi.serviceloader;filter:=\"(osgi.serviceloader=shaded.javax.enterprise.inject.se.SeContainerInitializer)\";cardinality:=multiple,osgi.serviceloader;filter:=\"(osgi.serviceloader=shaded.javax.enterprise.inject.spi.CDIProvider)\";cardinality:=multiple,osgi.extender;filter:=\"(osgi.extender=osgi.serviceloader.processor)\",osgi.contract;osgi.contract=JavaEL;filter:=\"(&(osgi.contract=JavaEL)(version=2.2.0))\",osgi.contract;osgi.contract=JavaInterceptor;filter:=\"(&(osg
 [...]
+                    attrs.getValue("Require-Capability"));
+        }
+    }
+
     @Test
     public void rewriteAdditionalAttributes() throws Exception {
         final Manifest manifest = new Manifest();

Reply via email to