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

michaelo pushed a commit to branch MNG-7034_3.8.x
in repository https://gitbox.apache.org/repos/asf/maven.git

commit 8931800cb10ad1b4b5a811b3fdad022f0cbe13ee
Author: Guillaume Nodet <[email protected]>
AuthorDate: Wed Nov 25 20:12:04 2020 +0100

    [MNG-7034] StackOverflowError thrown if a cycle exists in BOM imports
    
    This closes #399
---
 .../maven/model/building/DefaultModelBuilder.java  |  11 +-
 .../model/building/DefaultModelBuilderTest.java    | 146 +++++++++++++++++++++
 2 files changed, 155 insertions(+), 2 deletions(-)

diff --git 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index f981944..70c9ed5 100644
--- 
a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ 
b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -249,6 +249,13 @@ public class DefaultModelBuilder
     public ModelBuildingResult build( ModelBuildingRequest request )
         throws ModelBuildingException
     {
+        return build( request, new LinkedHashSet<String>() );
+    }
+
+    @SuppressWarnings( "checkstyle:methodlength" )
+    protected ModelBuildingResult build( ModelBuildingRequest request, 
Collection<String> importIds )
+        throws ModelBuildingException
+    {
         // phase 1
         DefaultModelBuildingResult result = new DefaultModelBuildingResult();
 
@@ -427,7 +434,7 @@ public class DefaultModelBuilder
 
         if ( !request.isTwoPhaseBuilding() )
         {
-            build( request, result );
+            build( request, result, importIds );
         }
 
         return result;
@@ -1296,7 +1303,7 @@ public class DefaultModelBuilder
                     final ModelBuildingResult importResult;
                     try
                     {
-                        importResult = build( importRequest );
+                        importResult = build( importRequest, importIds );
                     }
                     catch ( ModelBuildingException e )
                     {
diff --git 
a/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java
 
b/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java
new file mode 100644
index 0000000..b4b0a5b
--- /dev/null
+++ 
b/maven-model-builder/src/test/java/org/apache/maven/model/building/DefaultModelBuilderTest.java
@@ -0,0 +1,146 @@
+package org.apache.maven.model.building;
+
+  /*
+ * 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.
+ */
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.resolution.InvalidRepositoryException;
+import org.apache.maven.model.resolution.ModelResolver;
+import org.apache.maven.model.resolution.UnresolvableModelException;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Guillaume Nodet
+ */
+public class DefaultModelBuilderTest
+{
+
+    private static final String BASE1_ID = "thegroup:base1:pom";
+
+    private static final String BASE1 = "<project>\n" +
+            "  <modelVersion>4.0.0</modelVersion>\n" +
+            "  <groupId>thegroup</groupId>\n" +
+            "  <artifactId>base1</artifactId>\n" +
+            "  <version>1</version>\n" +
+            "  <packaging>pom</packaging>\n" +
+            "  <dependencyManagement>\n" +
+            "    <dependencies>\n" +
+            "      <dependency>\n" +
+            "        <groupId>thegroup</groupId>\n" +
+            "        <artifactId>base2</artifactId>\n" +
+            "        <version>1</version>\n" +
+            "        <type>pom</type>\n" +
+            "        <scope>import</scope>\n" +
+            "      </dependency>\n" +
+            "    </dependencies>\n" +
+            "  </dependencyManagement>\n" +
+            "</project>\n";
+
+    private static final String BASE2_ID = "thegroup:base2:pom";
+
+    private static final String BASE2 = "<project>\n" +
+            "  <modelVersion>4.0.0</modelVersion>\n" +
+            "  <groupId>thegroup</groupId>\n" +
+            "  <artifactId>base2</artifactId>\n" +
+            "  <version>1</version>\n" +
+            "  <packaging>pom</packaging>\n" +
+            "  <dependencyManagement>\n" +
+            "    <dependencies>\n" +
+            "      <dependency>\n" +
+            "        <groupId>thegroup</groupId>\n" +
+            "        <artifactId>base1</artifactId>\n" +
+            "        <version>1</version>\n" +
+            "        <type>pom</type>\n" +
+            "        <scope>import</scope>\n" +
+            "      </dependency>\n" +
+            "    </dependencies>\n" +
+            "  </dependencyManagement>\n" +
+            "</project>\n";
+
+    @Test( expected = ModelBuildingException.class )
+    public void testCycleInImports()
+            throws Exception
+    {
+        ModelBuilder builder = new DefaultModelBuilderFactory().newInstance();
+        assertNotNull( builder );
+
+        DefaultModelBuildingRequest request = new 
DefaultModelBuildingRequest();
+        request.setModelSource( new StringModelSource( BASE1 ) );
+        request.setModelResolver( new CycleInImportsResolver() );
+
+        builder.build( request );
+    }
+
+    static class CycleInImportsResolver extends BaseModelResolver
+    {
+        @Override
+        public ModelSource resolveModel(Dependency dependency) throws 
UnresolvableModelException
+        {
+            switch ( dependency.getManagementKey() )
+            {
+                case BASE1_ID: return new StringModelSource( BASE1 );
+                case BASE2_ID: return new StringModelSource( BASE2 );
+            }
+            return null;
+        }
+    }
+
+    static class BaseModelResolver implements ModelResolver
+    {
+        @Override
+        public ModelSource resolveModel( String groupId, String artifactId, 
String version )
+                throws UnresolvableModelException
+        {
+            return null;
+        }
+
+        @Override
+        public ModelSource resolveModel( Parent parent ) throws 
UnresolvableModelException
+        {
+            return null;
+        }
+
+        @Override
+        public ModelSource resolveModel( Dependency dependency ) throws 
UnresolvableModelException
+        {
+            return null;
+        }
+
+        @Override
+        public void addRepository( Repository repository ) throws 
InvalidRepositoryException
+        {
+        }
+
+        @Override
+        public void addRepository(Repository repository, boolean replace) 
throws InvalidRepositoryException
+        {
+        }
+
+        @Override
+        public ModelResolver newCopy()
+        {
+            return this;
+        }
+    }
+
+}

Reply via email to