Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package apache-ivy for openSUSE:Factory 
checked in at 2023-08-23 14:56:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/apache-ivy (Old)
 and      /work/SRC/openSUSE:Factory/.apache-ivy.new.1766 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "apache-ivy"

Wed Aug 23 14:56:37 2023 rev:22 rq:1105156 version:2.5.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/apache-ivy/apache-ivy.changes    2022-11-15 
13:20:41.460573264 +0100
+++ /work/SRC/openSUSE:Factory/.apache-ivy.new.1766/apache-ivy.changes  
2023-08-23 14:56:38.657886111 +0200
@@ -1,0 +2,12 @@
+Mon Aug 21 23:30:17 UTC 2023 - Fridrich Strba <[email protected]>
+
+- Upgrade to version 2.5.2 (bsc#1214422)
+  * Fixes:
+    + ivy:retrieve could fail because of a 'NullPointerException' 
+      (jira:IVY-1641[])
+    + reading POMs may loose dependencies when multiple Maven
+      dependencies only differ in 'classifier' (jira:IVY-1642[])
+    + CVE-2022-46751: Apache Ivy Is Vulnerable to XML External
+      Entity Injections
+
+-------------------------------------------------------------------

Old:
----
  apache-ivy-2.5.1-src.tar.gz
  ivy-2.5.1.pom

New:
----
  apache-ivy-2.5.2-src.tar.gz
  ivy-2.5.2.pom

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ apache-ivy.spec ++++++
--- /var/tmp/diff_new_pack.9OO76n/_old  2023-08-23 14:56:39.601887798 +0200
+++ /var/tmp/diff_new_pack.9OO76n/_new  2023-08-23 14:56:39.613887820 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package apache-ivy
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -21,7 +21,7 @@
 %bcond_without  sftp
 %bcond_without  vfs
 Name:           apache-ivy
-Version:        2.5.1
+Version:        2.5.2
 Release:        0
 Summary:        Java-based dependency manager
 License:        Apache-2.0

++++++ apache-ivy-2.5.1-src.tar.gz -> apache-ivy-2.5.2-src.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/NOTICE new/apache-ivy-2.5.2/NOTICE
--- old/apache-ivy-2.5.1/NOTICE 2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/NOTICE 2023-08-17 17:02:59.000000000 +0200
@@ -1,5 +1,5 @@
 Apache Ivy (TM)
-Copyright 2007-2019,2022 The Apache Software Foundation
+Copyright 2007-2019,2022-2023 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/asciidoc/release-notes.adoc 
new/apache-ivy-2.5.2/asciidoc/release-notes.adoc
--- old/apache-ivy-2.5.1/asciidoc/release-notes.adoc    2022-11-01 
10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/asciidoc/release-notes.adoc    2023-08-17 
17:02:59.000000000 +0200
@@ -19,7 +19,7 @@
 
 = Ivy Release Announcement
 
-XXXX Date XXXX - The Apache Ivy project is pleased to announce its 2.5.1 
release.
+XXXX Date XXXX - The Apache Ivy project is pleased to announce its 2.5.2 
release.
 
 == What is Ivy?
 Apache Ivy is a tool for managing (recording, tracking, resolving and 
reporting) project dependencies, characterized by flexibility,
@@ -34,26 +34,16 @@
 
 == Key features in this release
 
-Key features of this 2.5.1 release are:
-
-    * Ivy now requires a minimum of Java 8 runtime.
+Key features of this 2.5.2 release are:
 
+- FIX: reading POMs may loose dependencies when multiple Maven
+  dependencies only differ in `classifier` (jira:IVY-1642[])
 
 == List of Changes in this Release
 
 For details about the following changes, check our JIRA install at 
link:https://issues.apache.org/jira/browse/IVY[]
 
-*List of changes since Ivy 2.5.0:*
-
-- BREAKING: Removed old fr\jayasoft\ivy\ant\antlib.xml AntLib definition file 
(jira:IVY-1612[])
-- FIX: ResolveEngine resets dictator resolver to null in the global 
configuration (jira:IVY-1618[])
-- FIX: ConcurrentModificationException in MessageLoggerHelper.sumupProblems 
(jira:IVY-1628[])
-- FIX: useOrigin="true" fails with file-based ibiblio (jira:IVY-1616[])
-- FIX: ivy:retrieve Ant task didn't create an empty fileset when no files were 
retrieved to a non-empty directory (jira:IVY-1631[])
-- FIX: ivy:retrieve Ant task relied on the default HTTP header "Accept" which 
caused problems with servers that interpret it strictly (e.g. AWS CodeArtifact) 
(jira:IVY-1632[])
-
-- IMPROVEMENT: Ivy command now accepts a URL for the -settings option 
(jira:IVY-1615[])
-
+*List of changes since Ivy 2.5.1:*
 
 ////
  Samples :
@@ -63,6 +53,11 @@
 - DOCUMENTATION: bla bla bla (jira:IVY-1234[]) (Thanks to Jane Doe)
 ////
 
+- FIX: ivy:retrieve could fail because of a `NullPointerException` 
(jira:IVY-1641[])
+- FIX: reading POMs may loose dependencies when multiple Maven
+  dependencies only differ in `classifier` (jira:IVY-1642[])
+- IMPROVEMENT: Upgrade Apache HttpClient to 4.5.13 (jira:IVY-1644[])
+
 == Committers and Contributors
 
 Here is the list of people who have contributed source code and documentation 
up to this release. Many thanks to all of them, and also to the whole IvyDE 
community contributing ideas and feedback, and promoting the use of Apache Ivy !
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/asciidoc/settings.adoc 
new/apache-ivy-2.5.2/asciidoc/settings.adoc
--- old/apache-ivy-2.5.1/asciidoc/settings.adoc 2022-11-01 10:24:51.000000000 
+0100
+++ new/apache-ivy-2.5.2/asciidoc/settings.adoc 2023-08-17 17:02:59.000000000 
+0200
@@ -23,6 +23,8 @@
 
 Settings are specified through an XML file, usually called `ivysettings.xml`. 
To configure Ivy from Ant, you just have to use the 
link:use/settings{outfilesuffix}[settings] datatype with the path of your 
settings file.
 
+In addition certain link:systemproperties{outfilesuffix}[Java system 
properties] affect the XML parsing behavior of Ivy.
+
 Here is an example of the settings file:
 
 [source, xml]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/asciidoc/systemproperties.adoc 
new/apache-ivy-2.5.2/asciidoc/systemproperties.adoc
--- old/apache-ivy-2.5.1/asciidoc/systemproperties.adoc 1970-01-01 
01:00:00.000000000 +0100
+++ new/apache-ivy-2.5.2/asciidoc/systemproperties.adoc 2023-08-17 
17:02:59.000000000 +0200
@@ -0,0 +1,67 @@
+////
+   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
+
+     https://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.
+////
+
+= Java System Properties Affecting Ivy
+
+== XML Parser Settings
+
+Starting with Ivy 2.5.2 Ivy's XML parser can be controlled via the use
+of two newly introduced system properties.
+
+If you want to restore the default behavior of Ivy 2.5.1 and earlier
+you need to set `ivy.xml.allow-doctype-processing` to `true` and
+`ivy.xml.external-resources` to `ALL`.
+
+=== `ivy.xml.allow-doctype-processing`
+
+This system property accepts `true` or `false` as values. When set to
+`false` Ivy will not allow any processing of doctype declarations at
+all, while setting it to `true` enables it.
+
+The default is to allow doctype processing if and only if Ivy is
+parsing a Maven POM file.
+
+=== `ivy.xml.external-resources`
+
+This system property controls if external resources are read during
+doctype processing - and if so, where they can be loadad from. The
+value of this system property is only ever used if
+`ivy.xml.allow-doctype-processing` is not `false`.
+
+The accepted values are
+
+* `PROHIBIT` makes Ivy fail if any doctype tries to load an external
+  resource.
+* `IGNORE` makes Ivy ignore any external resource that the doctype
+  declaration wants to load.
+* `LOCAL_ONLY` allows external resources to be loaded via `file:` or
+  `jar:file` URIs only.
+* `ALL` allows external resources to be loaded from any URI.
+
+The default behavior is to not allow doctype processing at all, but if
+it is enabled the value `PROHIBIT` is assumed unless the property has
+been set explicitly.
+
+When reading Maven POMs a specific internal system id is recognized as
+resource and will be loaded from a resource shipping with the Ivy
+distribution in order to deal with invalid POM files accepted by
+Apache Maven - and the default value for this property is
+`IGNORE`in that case. See
+link:https://issues.apache.org/jira/browse/IVY-921[IVY-921] for
+details.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/asciidoc/toc.json 
new/apache-ivy-2.5.2/asciidoc/toc.json
--- old/apache-ivy-2.5.1/asciidoc/toc.json      2022-11-01 10:24:51.000000000 
+0100
+++ new/apache-ivy-2.5.2/asciidoc/toc.json      2023-08-17 17:02:59.000000000 
+0200
@@ -151,6 +151,11 @@
                       ]
                   },
                   {
+                      "id": "systemproperties",
+                      "title": "System Properties",
+                      "children": []
+                  },
+                  {
                     "id":"settings",
                     "title":"Settings Files",
                     "children": [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/doap_Ivy.rdf 
new/apache-ivy-2.5.2/doap_Ivy.rdf
--- old/apache-ivy-2.5.1/doap_Ivy.rdf   2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/doap_Ivy.rdf   2023-08-17 17:02:59.000000000 +0200
@@ -36,6 +36,20 @@
     <category 
rdf:resource="http://projects.apache.org/category/build-management"; />
     <release>
       <Version>
+        <name>Apache Ivy 2.5.1</name>
+        <created>2022-11-04</created>
+        <revision>2.5.1</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <name>Apache Ivy 2.5.0</name>
+        <created>2019-10-20</created>
+        <revision>2.5.0</revision>
+      </Version>
+    </release>
+    <release>
+      <Version>
         <name>Apache Ivy 2.4.0</name>
         <created>2014-12-26</created>
         <revision>2.4.0</revision>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/ant/IvyArtifactReport.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/ant/IvyArtifactReport.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/ant/IvyArtifactReport.java     
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/ant/IvyArtifactReport.java     
2023-08-17 17:02:59.000000000 +0200
@@ -28,8 +28,6 @@
 
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
@@ -43,6 +41,7 @@
 import org.apache.ivy.core.resolve.ResolveOptions;
 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
 import org.apache.ivy.core.retrieve.RetrieveOptions;
+import org.apache.ivy.util.XMLHelper;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
 import org.xml.sax.SAXException;
@@ -170,10 +169,8 @@
     }
 
     private TransformerHandler createTransformerHandler(FileOutputStream 
fileOutputStream)
-            throws TransformerFactoryConfigurationError, 
TransformerConfigurationException {
-        SAXTransformerFactory transformerFact = (SAXTransformerFactory) 
SAXTransformerFactory
-                .newInstance();
-        TransformerHandler saxHandler = 
transformerFact.newTransformerHandler();
+            throws TransformerConfigurationException {
+        TransformerHandler saxHandler = XMLHelper.getTransformerHandler();
         saxHandler.getTransformer().setOutputProperty(OutputKeys.ENCODING, 
"UTF-8");
         saxHandler.getTransformer().setOutputProperty(OutputKeys.INDENT, 
"yes");
         saxHandler.setResult(new StreamResult(fileOutputStream));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/ant/IvyReport.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/ant/IvyReport.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/ant/IvyReport.java     
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/ant/IvyReport.java     
2023-08-17 17:02:59.000000000 +0200
@@ -33,7 +33,6 @@
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.stream.StreamResult;
 import javax.xml.transform.stream.StreamSource;
 
@@ -48,6 +47,7 @@
 import org.apache.ivy.plugins.report.XmlReportParser;
 import org.apache.ivy.util.FileUtil;
 import org.apache.ivy.util.Message;
+import org.apache.ivy.util.XMLHelper;
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.taskdefs.XSLTProcess;
 import org.apache.tools.ant.util.JAXPUtils;
@@ -313,8 +313,7 @@
             Source xsltSource = new StreamSource(xsltStream, 
JAXPUtils.getSystemId(style));
 
             // create transformer
-            TransformerFactory tFactory = TransformerFactory.newInstance();
-            Transformer transformer = tFactory.newTransformer(xsltSource);
+            Transformer transformer = XMLHelper.getTransformer(xsltSource);
 
             // add standard parameters
             transformer.setParameter("confs", conf);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/resolve/IvyNode.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/resolve/IvyNode.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/resolve/IvyNode.java      
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/resolve/IvyNode.java      
2023-08-17 17:02:59.000000000 +0200
@@ -49,6 +49,7 @@
 import org.apache.ivy.core.module.descriptor.MDArtifact;
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ArtifactId;
+import org.apache.ivy.core.module.id.ArtifactRevisionId;
 import org.apache.ivy.core.module.id.ModuleId;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
 import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
@@ -873,6 +874,7 @@
 
         // now exclude artifacts that aren't accepted by any caller
         Iterator<Artifact> iter = artifacts.iterator();
+        Set<ArtifactRevisionId> artifactRevisionsSeen = new 
HashSet<ArtifactRevisionId>();
         while (iter.hasNext()) {
             Artifact artifact = iter.next();
             boolean excluded = callers.doesCallersExclude(rootModuleConf, 
artifact);
@@ -880,6 +882,10 @@
                 Message.debug(this + " in " + rootModuleConf + ": excluding " 
+ artifact);
                 iter.remove();
             }
+            if (!artifactRevisionsSeen.add(artifact.getId())) {
+                Message.debug(this + " in " + rootModuleConf + ": skipping 
duplicate " + artifact);
+                iter.remove();
+            }
         }
         return artifacts.toArray(new Artifact[artifacts.size()]);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/resolve/IvyNodeUsage.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/resolve/IvyNodeUsage.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/resolve/IvyNodeUsage.java 
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/resolve/IvyNodeUsage.java 
2023-08-17 17:02:59.000000000 +0200
@@ -24,15 +24,10 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
 import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
 import org.apache.ivy.core.module.descriptor.IncludeRule;
 import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
-import org.apache.ivy.core.module.id.ArtifactId;
-import org.apache.ivy.core.module.id.ModuleId;
-import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
-import org.apache.ivy.plugins.matcher.PatternMatcher;
 
 /**
  * Class collecting usage data for an IvyNode.
@@ -243,35 +238,15 @@
         if (dependersInConf == null) {
             return null;
         }
-        final Set<IncludeRule> dependencyIncludes = new HashSet<>();
-        // true if the depedency descriptor of any of the depender *doesn't* 
have an explicit
-        // "<artifact>" or an "<include>". false otherwise
-        boolean atLeastOneDependerNeedsAllArtifacts = false;
-        // true if the dependency descriptor of any of the depender either has 
an explicit "<artifact>"
-        // or an "<include>". false otherwise
-        boolean atLeastOneDependerHasSpecificArtifactSelection = false;
-        for (final Depender depender : dependersInConf) {
-            final DependencyArtifactDescriptor dads[] = 
depender.dd.getDependencyArtifacts(depender.dd.getModuleConfigurations());
-            final boolean declaresArtifacts = dads != null && dads.length > 0;
-            final IncludeRule[] rules = 
depender.dd.getIncludeRules(depender.dependerConf);
-            final boolean hasIncludeRule = rules != null && rules.length > 0;
-            if (hasIncludeRule) {
-                dependencyIncludes.addAll(Arrays.asList(rules));
-            }
-            if (declaresArtifacts || hasIncludeRule) {
-                atLeastOneDependerHasSpecificArtifactSelection = true;
-            }
-            if (!hasIncludeRule && !declaresArtifacts) {
-                atLeastOneDependerNeedsAllArtifacts = true;
+        Set<IncludeRule> dependencyIncludes = new HashSet<>();
+        for (Depender depender : dependersInConf) {
+            IncludeRule[] rules = 
depender.dd.getIncludeRules(depender.dependerConf);
+            if (rules == null || rules.length == 0) {
+                // no include rule in at least one depender -> we must include 
everything,
+                // and so return no include rule at all
+                return null;
             }
-        }
-        // so there's at least one depender D1 which has a specific artifact 
dependency and at the
-        // same time there's a depender D2 which doesn't have any explicit 
artifact/includes.
-        // so it is expected that an implicit "include all artifacts" is 
applied so that dependencies
-        // such as D2 get (all) the artifacts that are published by the 
dependency's module
-        if (atLeastOneDependerHasSpecificArtifactSelection && 
atLeastOneDependerNeedsAllArtifacts) {
-            // add a "include all artifacts" rule
-            dependencyIncludes.add(includeAllArtifacts());
+            dependencyIncludes.addAll(Arrays.asList(rules));
         }
         return dependencyIncludes;
     }
@@ -338,13 +313,4 @@
         return false;
     }
 
-    private static IncludeRule includeAllArtifacts() {
-        final ArtifactId aid = new ArtifactId(
-                new ModuleId(PatternMatcher.ANY_EXPRESSION, 
PatternMatcher.ANY_EXPRESSION),
-                PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
-                PatternMatcher.ANY_EXPRESSION);
-        return new DefaultIncludeRule(aid, ExactPatternMatcher.INSTANCE, null);
-    }
-
-
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
   2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
   2023-08-17 17:02:59.000000000 +0200
@@ -32,8 +32,6 @@
 import java.util.List;
 import java.util.Map;
 
-import javax.xml.parsers.SAXParserFactory;
-
 import org.apache.ivy.core.IvyPatternHelper;
 import org.apache.ivy.core.cache.RepositoryCacheManager;
 import org.apache.ivy.core.module.status.StatusManager;
@@ -46,6 +44,7 @@
 import org.apache.ivy.util.Configurator;
 import org.apache.ivy.util.FileResolver;
 import org.apache.ivy.util.Message;
+import org.apache.ivy.util.XMLHelper;
 import org.apache.ivy.util.url.CredentialsStore;
 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
 import org.apache.ivy.util.url.URLHandlerRegistry;
@@ -151,10 +150,8 @@
     @SuppressWarnings("deprecation")
     private void doParse(URL settingsUrl) throws IOException, ParseException {
         this.settings = settingsUrl;
-        try (InputStream stream = 
URLHandlerRegistry.getDefault().openStream(settingsUrl)) {
-            InputSource inSrc = new InputSource(stream);
-            inSrc.setSystemId(settingsUrl.toExternalForm());
-            
SAXParserFactory.newInstance().newSAXParser().parse(settingsUrl.toExternalForm(),
 this);
+        try {
+            XMLHelper.parse(settingsUrl, null, this);
             ivy.validate();
         } catch (IOException e) {
             throw e;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java 
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java 
2023-08-17 17:02:59.000000000 +0200
@@ -22,9 +22,7 @@
 import java.util.Set;
 
 import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.sax.SAXTransformerFactory;
 import javax.xml.transform.sax.TransformerHandler;
 import javax.xml.transform.stream.StreamResult;
 
@@ -45,6 +43,7 @@
 import org.apache.ivy.osgi.util.Version;
 import org.apache.ivy.osgi.util.VersionRange;
 import org.apache.ivy.util.Message;
+import org.apache.ivy.util.XMLHelper;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.AttributesImpl;
@@ -53,12 +52,10 @@
 
     public static ContentHandler newHandler(OutputStream out, String encoding, 
boolean indent)
             throws TransformerConfigurationException {
-        SAXTransformerFactory tf = (SAXTransformerFactory) 
SAXTransformerFactory.newInstance();
-        TransformerHandler hd = tf.newTransformerHandler();
-        Transformer serializer = tf.newTransformer();
+        TransformerHandler hd = XMLHelper.getTransformerHandler();
+        hd.getTransformer().setOutputProperty(OutputKeys.ENCODING, encoding);
+        hd.getTransformer().setOutputProperty(OutputKeys.INDENT, indent ? 
"yes" : "no");
         StreamResult stream = new StreamResult(out);
-        serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
-        serializer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
         hd.setResult(stream);
         return hd;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
      2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java
      2023-08-17 17:02:59.000000000 +0200
@@ -305,6 +305,8 @@
         // the same dependency mrid could appear twice in the module 
descriptor,
         // so we check if we already have created a dependency descriptor for 
the dependency mrid
         final DependencyDescriptor existing = 
this.ivyModuleDescriptor.depDescriptors.get(moduleRevId);
+        final String[] existingConfigurations = existing == null ? new 
String[0]
+            : existing.getModuleConfigurations();
         final DefaultDependencyDescriptor dd = (existing != null && existing 
instanceof DefaultDependencyDescriptor)
                 ? (DefaultDependencyDescriptor) existing
                 : new PomDependencyDescriptor(dep, ivyModuleDescriptor, 
moduleRevId, !excludeAllTransitiveDeps);
@@ -314,7 +316,14 @@
         ConfMapper mapping = MAVEN2_CONF_MAPPING.get(scope);
         mapping.addMappingConfs(dd, dep.isOptional());
         Map<String, String> extraAtt = new HashMap<>();
-        if (dep.getClassifier() != null || dep.getType() != null && 
!"jar".equals(dep.getType())) {
+        final String optionalizedScope = dep.isOptional() ? "optional" : scope;
+        if (isNonDefaultArtifact(dep)) {
+            if (existing != null && 
existing.getAllDependencyArtifacts().length == 0) {
+                String moduleConfiguration = existingConfigurations.length == 1
+                    ? existingConfigurations[0] : optionalizedScope;
+                // previously added dependency has been the "default artifact"
+                dd.addDependencyArtifact(moduleConfiguration, 
createDefaultArtifact(dd));
+            }
             String type = "jar";
             if (dep.getType() != null) {
                 type = dep.getType();
@@ -339,9 +348,11 @@
                     dd, dd.getDependencyId().getName(), type, ext, null, 
extraAtt);
             // here we have to assume a type and ext for the artifact, so this 
is a limitation
             // compared to how m2 behave with classifiers
-            final String optionalizedScope = dep.isOptional() ? "optional" : 
scope;
             depArtifact.addConfiguration(optionalizedScope);
             dd.addDependencyArtifact(optionalizedScope, depArtifact);
+        } else if (existing != null) {
+            // this is the "default" artifact and some non-default artifact 
has already been added
+            dd.addDependencyArtifact(optionalizedScope, 
createDefaultArtifact(dd));
         }
 
         for (ModuleId excludedModule : excluded) {
@@ -362,6 +373,15 @@
         }
     }
 
+    private boolean isNonDefaultArtifact(PomDependencyData dep) {
+        return dep.getClassifier() != null || dep.getType() != null && 
!"jar".equals(dep.getType());
+    }
+
+    private DefaultDependencyArtifactDescriptor 
createDefaultArtifact(DefaultDependencyDescriptor dd) {
+        return new DefaultDependencyArtifactDescriptor(dd, 
dd.getDependencyId().getName(),
+            "jar", "jar", null, null);
+    }
+
     private static boolean shouldExcludeAllTransitiveDeps(final List<ModuleId> 
exclusions) {
         if (exclusions == null || exclusions.isEmpty()) {
             return false;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java   
    2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/m2/PomReader.java   
    2023-08-17 17:02:59.000000000 +0200
@@ -130,12 +130,13 @@
                 public InputSource resolveEntity(String publicId, String 
systemId)
                         throws SAXException, IOException {
                     if (systemId != null && 
systemId.endsWith("m2-entities.ent")) {
+                        // IVY-921: return an InputSource for our local 
packaged m2-entities.ent file
                         return new InputSource(
                                 
PomReader.class.getResourceAsStream("m2-entities.ent"));
                     }
                     return null;
                 }
-            });
+            }, true, XMLHelper.ExternalResources.IGNORE);
             projectElement = pomDomDoc.getDocumentElement();
             if (!PROJECT.equals(projectElement.getNodeName())
                     && !MODEL.equals(projectElement.getNodeName())) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
      2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParser.java
      2023-08-17 17:02:59.000000000 +0200
@@ -17,9 +17,13 @@
  */
 package org.apache.ivy.plugins.parser.xml;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -80,6 +84,7 @@
 import org.apache.ivy.util.XMLHelper;
 import org.apache.ivy.util.extendable.ExtendableItemHelper;
 import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 
 import static 
org.apache.ivy.core.module.descriptor.Configuration.Visibility.getVisibility;
@@ -216,6 +221,8 @@
         protected static final List<String> ALLOWED_VERSIONS = 
Arrays.asList("1.0",
                 "1.1", "1.2", "1.3", "1.4", "2.0", "2.1", "2.2", "2.3", "2.4");
 
+        private static final String IVY_XSD_CONTENT;
+
         /* how and what do we have to parse */
         private ParserSettings settings;
 
@@ -248,6 +255,40 @@
 
         private Stack<ExtraInfoHolder> extraInfoStack = new Stack<>();
 
+        static {
+            String ivyXSDContent = null;
+            final InputStream is = Parser.class.getResourceAsStream("ivy.xsd");
+            if (is != null) {
+                final StringBuilder sb = new StringBuilder();
+                try {
+                    try {
+                        final BufferedReader reader = new BufferedReader(new 
InputStreamReader(is, "UTF-8"));
+                        String line = null;
+                        while ((line = reader.readLine()) != null) {
+                            if (sb.length() != 0) {
+                                sb.append("\n");
+                            }
+                            sb.append(line);
+                        }
+                    } catch (UnsupportedEncodingException e) {
+                        // ignore
+                        ivyXSDContent = null;
+                    } catch (IOException e) {
+                        // ignore
+                        ivyXSDContent = null;
+                    }
+                } finally {
+                    try {
+                        is.close();
+                    } catch (Exception e) {
+                        // ignore
+                    }
+                }
+                ivyXSDContent = sb.length() == 0 ? null : sb.toString();
+            }
+            IVY_XSD_CONTENT = ivyXSDContent;
+        }
+
         public Parser(ModuleDescriptorParser parser, ParserSettings 
ivySettings) {
             super(parser);
             settings = ivySettings;
@@ -268,10 +309,14 @@
         public void parse() throws ParseException {
             try {
                 URL schemaURL = validate ? getSchemaURL() : null;
+                XMLHelper.ExternalResources e =
+                    validate && 
System.getProperty(XMLHelper.EXTERNAL_RESOURCES) == null
+                    ? XMLHelper.ExternalResources.IGNORE
+                    : XMLHelper.ExternalResources.fromSystemProperty();
                 if (descriptorURL != null) {
-                    XMLHelper.parse(descriptorURL, schemaURL, this);
+                    XMLHelper.parse(descriptorURL, schemaURL, this, null, e);
                 } else {
-                    XMLHelper.parse(descriptorInput, schemaURL, this, null);
+                    XMLHelper.parse(descriptorInput, schemaURL, this, null, e);
                 }
                 checkConfigurations();
                 replaceConfigurationWildcards();
@@ -297,6 +342,26 @@
         }
 
         @Override
+        public InputSource resolveEntity(final String publicId, final String 
systemId)
+                throws IOException, SAXException {
+            if (isApacheOrgIvyXSDSystemId(systemId) && IVY_XSD_CONTENT != 
null) {
+                // redirect the schema location to local file based ivy.xsd 
whose content
+                // we have already read and is available in-memory.
+                final InputSource source = new InputSource(new 
StringReader(IVY_XSD_CONTENT));
+                return source;
+            }
+            return super.resolveEntity(publicId, systemId);
+        }
+
+        private static boolean isApacheOrgIvyXSDSystemId(final String 
systemId) {
+            if (systemId == null) {
+                return false;
+            }
+            return systemId.equals("http://ant.apache.org/ivy/schemas/ivy.xsd";)
+                    || 
systemId.equals("https://ant.apache.org/ivy/schemas/ivy.xsd";);
+        }
+
+        @Override
         public void startElement(String uri, String localName, String qName, 
Attributes attributes)
                 throws SAXException {
             try {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/report/XmlReportParser.java
 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/report/XmlReportParser.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/plugins/report/XmlReportParser.java
    2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/plugins/report/XmlReportParser.java
    2023-08-17 17:02:59.000000000 +0200
@@ -27,9 +27,6 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
 import org.apache.ivy.core.cache.ArtifactOrigin;
 import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
@@ -38,6 +35,7 @@
 import org.apache.ivy.core.report.DownloadStatus;
 import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
 import org.apache.ivy.util.DateUtil;
+import org.apache.ivy.util.XMLHelper;
 import org.apache.ivy.util.extendable.ExtendableItemHelper;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
@@ -242,8 +240,7 @@
         }
 
         public void parse() throws Exception {
-            SAXParser saxParser = 
SAXParserFactory.newInstance().newSAXParser();
-            saxParser.parse(report, new XmlReportParserHandler());
+            XMLHelper.parse(report.toURI().toURL(), null, new 
XmlReportParserHandler());
         }
 
         private static boolean parseBoolean(String str) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/util/XMLHelper.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/util/XMLHelper.java
--- old/apache-ivy-2.5.1/src/java/org/apache/ivy/util/XMLHelper.java    
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/src/java/org/apache/ivy/util/XMLHelper.java    
2023-08-17 17:02:59.000000000 +0200
@@ -19,6 +19,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.StringReader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -28,13 +29,24 @@
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
 
 import org.apache.ivy.util.url.URLHandlerRegistry;
 import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
 import org.xml.sax.EntityResolver;
 import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
 import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -50,49 +62,38 @@
 
     static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";;
 
-    private static boolean canUseSchemaValidation = true;
-
-    private static Boolean canDisableExternalDtds = null;
-
-    private static SAXParser newSAXParser(URL schema, InputStream schemaStream,
-            boolean loadExternalDtds) throws ParserConfigurationException, 
SAXException {
-        SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+    private static final String XML_ACCESS_EXTERNAL_SCHEMA = 
"http://javax.xml.XMLConstants/property/accessExternalSchema";;
+    private static final String XML_ACCESS_EXTERNAL_DTD = 
"http://javax.xml.XMLConstants/property/accessExternalDTD";;
+    public static final String ALLOW_DOCTYPE_PROCESSING = 
"ivy.xml.allow-doctype-processing";
+    public static final String EXTERNAL_RESOURCES = 
"ivy.xml.external-resources";
+
+    private static SAXParser newSAXParser(final URL schema, final InputStream 
schemaStream,
+        final boolean allowXmlDoctypeProcessing, final ExternalResources 
externalResources)
+        throws ParserConfigurationException, SAXException {
+        final SAXParserFactory parserFactory = SAXParserFactory.newInstance();
         parserFactory.setNamespaceAware(true);
-        parserFactory.setValidating(canUseSchemaValidation && (schema != 
null));
-        if (!loadExternalDtds && canDisableExternalDtds(parserFactory)) {
-            parserFactory.setFeature(XERCES_LOAD_EXTERNAL_DTD, false);
-        }
-        SAXParser parser = parserFactory.newSAXParser();
+        parserFactory.setValidating(schema != null);
+        configureSafeFeatures(parserFactory, allowXmlDoctypeProcessing, 
externalResources);
 
-        if (canUseSchemaValidation && schema != null) {
+        SAXParser parser = parserFactory.newSAXParser();
+        if (schema != null) {
             try {
                 parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
                 parser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream);
             } catch (SAXNotRecognizedException ex) {
                 Message.warn("problem while setting JAXP validating property 
on SAXParser... "
                         + "XML validation will not be done", ex);
-                canUseSchemaValidation = false;
                 parserFactory.setValidating(false);
                 parser = parserFactory.newSAXParser();
             }
         }
-
-        parser.getXMLReader().setFeature(XML_NAMESPACE_PREFIXES, true);
+        final XMLReader reader = parser.getXMLReader();
+        reader.setFeature(XML_NAMESPACE_PREFIXES, true);
+        reader.setProperty(XML_ACCESS_EXTERNAL_SCHEMA, 
externalResources.getAllowedProtocols());
+        reader.setProperty(XML_ACCESS_EXTERNAL_DTD, 
externalResources.getAllowedProtocols());
         return parser;
     }
 
-    private static boolean canDisableExternalDtds(SAXParserFactory 
parserFactory) {
-        if (canDisableExternalDtds == null) {
-            try {
-                parserFactory.getFeature(XERCES_LOAD_EXTERNAL_DTD);
-                canDisableExternalDtds = Boolean.TRUE;
-            } catch (Exception ex) {
-                canDisableExternalDtds = Boolean.FALSE;
-            }
-        }
-        return canDisableExternalDtds;
-    }
-
     /**
      * Convert an URL to a valid systemId according to RFC 2396.
      *
@@ -116,36 +117,58 @@
         parse(xmlURL, schema, handler, null);
     }
 
-    @SuppressWarnings("deprecation")
     public static void parse(URL xmlURL, URL schema, DefaultHandler handler, 
LexicalHandler lHandler)
             throws SAXException, IOException, ParserConfigurationException {
+        parse(xmlURL, schema, handler, lHandler, 
ExternalResources.fromSystemProperty());
+    }
+
+    @SuppressWarnings("deprecation")
+    public static void parse(URL xmlURL, URL schema, DefaultHandler handler, 
LexicalHandler lHandler,
+            final ExternalResources externalResources)
+            throws SAXException, IOException, ParserConfigurationException {
         try (InputStream xmlStream = 
URLHandlerRegistry.getDefault().openStream(xmlURL)) {
             InputSource inSrc = new InputSource(xmlStream);
             inSrc.setSystemId(toSystemId(xmlURL));
-            parse(inSrc, schema, handler, lHandler);
+            parse(inSrc, schema, handler, lHandler, externalResources);
         }
     }
 
     public static void parse(InputStream xmlStream, URL schema, DefaultHandler 
handler,
             LexicalHandler lHandler) throws SAXException, IOException, 
ParserConfigurationException {
+        parse(xmlStream, schema, handler, lHandler, 
ExternalResources.fromSystemProperty());
+    }
+
+    public static void parse(InputStream xmlStream, URL schema, DefaultHandler 
handler,
+            LexicalHandler lHandler, final ExternalResources externalResources)
+            throws SAXException, IOException, ParserConfigurationException {
         parse(new InputSource(xmlStream), schema, handler, lHandler);
     }
 
     public static void parse(InputSource xmlStream, URL schema, DefaultHandler 
handler,
             LexicalHandler lHandler) throws SAXException, IOException, 
ParserConfigurationException {
-        parse(xmlStream, schema, handler, lHandler, true);
+        parse(xmlStream, schema, handler, lHandler, 
ExternalResources.fromSystemProperty());
+    }
+
+    public static void parse(final InputSource xmlStream, final URL schema,
+                             final DefaultHandler handler, final 
LexicalHandler lHandler,
+                             final boolean loadExternalDtds) throws 
SAXException, IOException,
+            ParserConfigurationException {
+        parse(xmlStream, schema, handler, lHandler,
+            loadExternalDtds ? ExternalResources.LOCAL_ONLY : 
ExternalResources.PROHIBIT);
     }
 
     @SuppressWarnings("deprecation")
-    public static void parse(InputSource xmlStream, URL schema, DefaultHandler 
handler,
-            LexicalHandler lHandler, boolean loadExternalDtds) throws 
SAXException, IOException,
+    public static void parse(final InputSource xmlStream, final URL schema,
+                             final DefaultHandler handler, final 
LexicalHandler lHandler,
+                             final ExternalResources externalResources) throws 
SAXException, IOException,
             ParserConfigurationException {
         InputStream schemaStream = null;
         try {
             if (schema != null) {
                 schemaStream = 
URLHandlerRegistry.getDefault().openStream(schema);
             }
-            SAXParser parser = XMLHelper.newSAXParser(schema, schemaStream, 
loadExternalDtds);
+            SAXParser parser = XMLHelper.newSAXParser(schema, schemaStream,
+                    isXmlDoctypeProcessingAllowed(), externalResources);
 
             if (lHandler != null) {
                 try {
@@ -157,7 +180,10 @@
                 }
             }
 
-            parser.parse(xmlStream, handler);
+            DefaultHandler h = externalResources == ExternalResources.IGNORE
+                ? new NoopEntityResolverDefaultHandler(handler)
+                : handler;
+            parser.parse(xmlStream, h);
         } finally {
             if (schemaStream != null) {
                 try {
@@ -170,7 +196,7 @@
     }
 
     public static boolean canUseSchemaValidation() {
-        return canUseSchemaValidation;
+        return true;
     }
 
     /**
@@ -216,15 +242,33 @@
 
     public static Document parseToDom(InputSource source, EntityResolver 
entityResolver)
             throws IOException, SAXException {
-        DocumentBuilder docBuilder = getDocBuilder(entityResolver);
+        return parseToDom(source, entityResolver, 
isXmlDoctypeProcessingAllowed(),
+            ExternalResources.fromSystemProperty());
+    }
+
+    public static Document parseToDom(InputSource source, EntityResolver 
entityResolver,
+            boolean allowXmlDoctypeProcessing, ExternalResources 
externalResources)
+            throws IOException, SAXException {
+        DocumentBuilder docBuilder = getDocBuilder(entityResolver, 
allowXmlDoctypeProcessing,
+            externalResources);
         return docBuilder.parse(source);
     }
 
     public static DocumentBuilder getDocBuilder(EntityResolver entityResolver) 
{
+        return getDocBuilder(entityResolver, isXmlDoctypeProcessingAllowed(),
+            ExternalResources.fromSystemProperty());
+    }
+
+    public static DocumentBuilder getDocBuilder(EntityResolver entityResolver,
+            boolean allowXmlDoctypeProcessing, ExternalResources 
externalResources) {
         try {
-            DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance();
+            final DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance();
             factory.setValidating(false);
+            configureSafeFeatures(factory, allowXmlDoctypeProcessing, 
externalResources);
             DocumentBuilder docBuilder = factory.newDocumentBuilder();
+            if (externalResources == ExternalResources.IGNORE) {
+                entityResolver = new NoopEntityResolver(entityResolver);
+            }
             if (entityResolver != null) {
                 docBuilder.setEntityResolver(entityResolver);
             }
@@ -234,7 +278,335 @@
         }
     }
 
+    public static Transformer getTransformer(Source source) throws 
TransformerConfigurationException {
+        TransformerFactory factory = getTransformerFactory();
+        return factory.newTransformer(source);
+    }
+
+    public static TransformerHandler getTransformerHandler() throws 
TransformerConfigurationException {
+        SAXTransformerFactory factory = getTransformerFactory();
+        return factory.newTransformerHandler();
+    }
+
+    public enum ExternalResources {
+        PROHIBIT(""),
+        // technically the URIs for IGNORE will never get resolved at all.
+        // "all" pacifies some version of Java that check the property before 
delegating to the EntityResolver (which is
+        // going to return an empty content anyway)
+        IGNORE("all"),
+        LOCAL_ONLY("file, jar:file"),
+        ALL("all");
+
+        private final String allowedProtocols;
+
+        private ExternalResources(String allowedProtocols) {
+            this.allowedProtocols = allowedProtocols;
+        }
+
+        private String getAllowedProtocols() {
+            return allowedProtocols;
+        }
+
+        public static ExternalResources fromSystemProperty() {
+            final String val = System.getProperty(EXTERNAL_RESOURCES);
+            if (val != null) {
+                if (val.equalsIgnoreCase("ignore")) {
+                    return IGNORE;
+                }
+                if (val.equalsIgnoreCase("all")) {
+                    return ALL;
+                }
+                if (val.equalsIgnoreCase("local-only") || 
val.equalsIgnoreCase("local_only")) {
+                    return LOCAL_ONLY;
+                }
+            }
+            return PROHIBIT;
+        }
+    }
+
+    public static boolean isXmlDoctypeProcessingAllowed() {
+        return "true".equals(System.getProperty(ALLOW_DOCTYPE_PROCESSING));
+    }
+
     private XMLHelper() {
     }
 
+    private static SAXTransformerFactory getTransformerFactory() {
+        TransformerFactory factory = SAXTransformerFactory.newInstance();
+        configureSafeFeatures(factory);
+        return (SAXTransformerFactory) factory;
+    }
+
+    private static void configureSafeFeatures(final DocumentBuilderFactory 
factory,
+            final boolean allowXmlDoctypeProcessing, final ExternalResources 
externalResources) {
+        final String DISALLOW_DOCTYPE_DECL = 
"http://apache.org/xml/features/disallow-doctype-decl";;
+        trySetFeature(factory, DISALLOW_DOCTYPE_DECL, 
!allowXmlDoctypeProcessing);
+
+        // available since Java 6, as XMLConstants.FEATURE_SECURE_PROCESSING. 
We can't use Java 6
+        // at compile time, in current version, so inline the constant here
+        final String FEATURE_SECURE_PROCESSING = 
"http://javax.xml.XMLConstants/feature/secure-processing";;
+        trySetFeature(factory, FEATURE_SECURE_PROCESSING, true);
+
+        final String ALLOW_EXTERNAL_GENERAL_ENTITIES = 
"http://xml.org/sax/features/external-general-entities";;
+        trySetFeature(factory, ALLOW_EXTERNAL_GENERAL_ENTITIES, false);
+
+        final String ALLOW_EXTERNAL_PARAM_ENTITIES = 
"http://xml.org/sax/features/external-parameter-entities";;
+        trySetFeature(factory, ALLOW_EXTERNAL_PARAM_ENTITIES, false);
+
+        final String LOAD_EXTERNAL_DTD = 
"http://apache.org/xml/features/nonvalidating/load-external-dtd";;
+        trySetFeature(factory, LOAD_EXTERNAL_DTD, externalResources != 
ExternalResources.PROHIBIT);
+
+        try {
+            factory.setXIncludeAware(false);
+        } catch (Exception e) {
+            // ignore
+        }
+        try {
+            factory.setExpandEntityReferences(false);
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+    private static void configureSafeFeatures(final SAXParserFactory factory,
+            final boolean allowXmlDoctypeProcessing, final ExternalResources 
externalResources) {
+        final String DISALLOW_DOCTYPE_DECL = 
"http://apache.org/xml/features/disallow-doctype-decl";;
+        trySetFeature(factory, DISALLOW_DOCTYPE_DECL, 
!allowXmlDoctypeProcessing);
+
+        // available since Java 6, as XMLConstants.FEATURE_SECURE_PROCESSING. 
We can't use Java 6
+        // at compile time, in current version, so inline the constant here
+        final String FEATURE_SECURE_PROCESSING = 
"http://javax.xml.XMLConstants/feature/secure-processing";;
+        trySetFeature(factory, FEATURE_SECURE_PROCESSING, true);
+
+        final boolean allowEntities = externalResources == 
ExternalResources.LOCAL_ONLY
+            || externalResources == ExternalResources.ALL;
+        final String ALLOW_EXTERNAL_GENERAL_ENTITIES = 
"http://xml.org/sax/features/external-general-entities";;
+        trySetFeature(factory, ALLOW_EXTERNAL_GENERAL_ENTITIES, allowEntities);
+
+        final String ALLOW_EXTERNAL_PARAM_ENTITIES = 
"http://xml.org/sax/features/external-parameter-entities";;
+        trySetFeature(factory, ALLOW_EXTERNAL_PARAM_ENTITIES, allowEntities);
+        final String LOAD_EXTERNAL_DTD = 
"http://apache.org/xml/features/nonvalidating/load-external-dtd";;
+        trySetFeature(factory, LOAD_EXTERNAL_DTD, externalResources != 
ExternalResources.PROHIBIT);
+        try {
+            factory.setXIncludeAware(false);
+        } catch (Exception e) {
+            // ignore
+        }
+    }
+
+    private static void configureSafeFeatures(final TransformerFactory 
factory) {
+        // available since Java 7, as XMLConstants.ACCESS_EXTERNAL_DTD, 
ACCESS_EXTERNAL_SCHEMA and
+        // ACCESS_EXTERNAL_STYLESHEET respectively.
+        // We can't use Java 7 at compile time, in current version, so inline 
the constants here
+        trySetAttribute(factory, XML_ACCESS_EXTERNAL_DTD, "");
+        trySetAttribute(factory, XML_ACCESS_EXTERNAL_SCHEMA, "");
+        trySetAttribute(factory, 
"http://javax.xml.XMLConstants/property/accessExternalStylesheet";, "");
+    }
+
+    private static boolean isFeatureSupported(final SAXParserFactory factory, 
final String feature) {
+        try {
+            factory.getFeature(feature);
+            return true;
+        } catch (ParserConfigurationException e) {
+            return false;
+        } catch (SAXNotRecognizedException e) {
+            return false;
+        } catch (SAXNotSupportedException e) {
+            return false;
+        }
+    }
+
+    private static boolean isFeatureSupported(final DocumentBuilderFactory 
factory, final String feature) {
+        try {
+            factory.getFeature(feature);
+            return true;
+        } catch (ParserConfigurationException e) {
+            return false;
+        }
+    }
+
+    private static boolean isAttributeSupported(final TransformerFactory 
factory, final String attribute) {
+        try {
+            factory.getAttribute(attribute);
+            return true;
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    private static boolean trySetFeature(final DocumentBuilderFactory factory,
+                                               final String feature, final 
boolean val) {
+        if (!isFeatureSupported(factory, feature)) {
+            return false;
+        }
+        try {
+            factory.setFeature(feature, val);
+            return true;
+        } catch (ParserConfigurationException e) {
+            // log and continue
+            Message.warn("Failed to set feature " + feature + " on 
DocumentBuilderFactory", e);
+            return false;
+        }
+    }
+
+    private static boolean trySetFeature(final SAXParserFactory factory,
+                                         final String feature, final boolean 
val) {
+        if (!isFeatureSupported(factory, feature)) {
+            return false;
+        }
+        try {
+            factory.setFeature(feature, val);
+            return true;
+        } catch (ParserConfigurationException e) {
+            // log and continue
+            Message.warn("Failed to set feature " + feature + " on 
SAXParserFactory", e);
+            return false;
+        } catch (SAXNotRecognizedException e) {
+            // log and continue
+            Message.warn("Failed to set feature " + feature + " on 
SAXParserFactory", e);
+            return false;
+        } catch (SAXNotSupportedException e) {
+            // log and continue
+            Message.warn("Failed to set feature " + feature + " on 
SAXParserFactory", e);
+            return false;
+        }
+    }
+
+    private static boolean trySetAttribute(final TransformerFactory factory,
+                                         final String attribute, final String 
val) {
+        if (!isAttributeSupported(factory, attribute)) {
+            return false;
+        }
+        try {
+            factory.setAttribute(attribute, val);
+            return true;
+        } catch (IllegalArgumentException e) {
+            // log and continue
+            Message.warn("Failed to set attribute " + attribute + " on 
TransformerFactory", e);
+            return false;
+        }
+    }
+
+    private static final InputSource EMPTY_INPUT_SOURCE = new InputSource(new 
StringReader(""));
+
+    private static class NoopEntityResolver implements EntityResolver {
+        private EntityResolver wrapped;
+
+        private NoopEntityResolver(EntityResolver wrapped) {
+            this.wrapped = wrapped;
+        }
+
+        @Override
+        public InputSource resolveEntity(String publicId, String systemId) 
throws SAXException, IOException {
+            if (wrapped != null) {
+                InputSource s = wrapped.resolveEntity(publicId, systemId);
+                if (s != null) {
+                    return s;
+                }
+            }
+            return EMPTY_INPUT_SOURCE;
+        }
+    }
+
+    private static class NoopEntityResolverDefaultHandler extends 
DefaultHandler {
+
+        private DefaultHandler wrapped;
+
+        private NoopEntityResolverDefaultHandler(DefaultHandler wrapped) {
+            this.wrapped = wrapped;
+        }
+
+        @Override
+        public InputSource resolveEntity(String publicId, String systemId) 
throws SAXException, IOException {
+            if (wrapped != null) {
+                InputSource s = wrapped.resolveEntity(publicId, systemId);
+                if (s != null) {
+                    return s;
+                }
+            }
+            return EMPTY_INPUT_SOURCE;
+        }
+
+        @Override
+        public void notationDecl(String name, String publicId, String 
systemId) throws SAXException {
+            wrapped.notationDecl(name, publicId, systemId);
+        }
+
+        @Override
+        public void unparsedEntityDecl(String name, String publicId, String 
systemId, String notationName)
+            throws SAXException {
+            wrapped.unparsedEntityDecl(name, publicId, systemId, notationName);
+        }
+
+        @Override
+        public void setDocumentLocator(Locator locator) {
+            wrapped.setDocumentLocator(locator);
+        }
+
+        @Override
+        public void startDocument() throws SAXException {
+            wrapped.startDocument();
+        }
+
+        @Override
+        public void endDocument() throws SAXException {
+            wrapped.endDocument();
+        }
+
+        @Override
+        public void startPrefixMapping(String prefix, String uri) throws 
SAXException {
+            wrapped.startPrefixMapping(prefix, uri);
+        }
+
+        @Override
+        public void endPrefixMapping(String prefix) throws SAXException {
+            wrapped.endPrefixMapping(prefix);
+        }
+
+        @Override
+        public void startElement(String uri, String localName, String qName, 
Attributes attributes)
+            throws SAXException {
+            wrapped.startElement(uri, localName, qName, attributes);
+        }
+
+        @Override
+        public void endElement(String uri, String localName, String qName) 
throws SAXException {
+            wrapped.endElement(uri, localName, qName);
+        }
+
+        @Override
+        public void characters(char[] ch, int start, int length) throws 
SAXException {
+            wrapped.characters(ch, start, length);
+        }
+
+        @Override
+        public void ignorableWhitespace(char[] ch, int start, int length) 
throws SAXException {
+            wrapped.ignorableWhitespace(ch, start, length);
+        }
+
+        @Override
+        public void processingInstruction(String target, String data) throws 
SAXException {
+            wrapped.processingInstruction(target, data);
+        }
+
+        @Override
+        public void skippedEntity(String name) throws SAXException {
+            wrapped.skippedEntity(name);
+        }
+
+        @Override
+        public void warning(SAXParseException e) throws SAXException {
+            wrapped.warning(e);
+        }
+
+        @Override
+        public void error(SAXParseException e) throws SAXException {
+            wrapped.error(e);
+        }
+
+        @Override
+        public void fatalError(SAXParseException e) throws SAXException {
+            wrapped.fatalError(e);
+        }
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/util/url/HttpClientHandler.java 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/util/url/HttpClientHandler.java
--- 
old/apache-ivy-2.5.1/src/java/org/apache/ivy/util/url/HttpClientHandler.java    
    2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/src/java/org/apache/ivy/util/url/HttpClientHandler.java    
    2023-08-17 17:02:59.000000000 +0200
@@ -239,8 +239,9 @@
             if (checkStatusCode(httpMethod, url, response)) {
                 final HttpEntity responseEntity = response.getEntity();
                 final Charset charSet = 
ContentType.getOrDefault(responseEntity).getCharset();
+                final String charSetName = charSet != null ? charSet.name() : 
null;
                 return new URLInfo(true, responseEntity == null ? 0 : 
responseEntity.getContentLength(),
-                        getLastModified(response), charSet.name());
+                        getLastModified(response), charSetName);
             }
         } catch (IOException | IllegalArgumentException e) {
             // IllegalArgumentException is thrown by HttpClient library to 
indicate the URL is not valid,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/core/resolve/ResolveTest.java
--- old/apache-ivy-2.5.1/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
2022-11-01 10:24:51.000000000 +0100
+++ new/apache-ivy-2.5.2/test/java/org/apache/ivy/core/resolve/ResolveTest.java 
2023-08-17 17:02:59.000000000 +0200
@@ -51,6 +51,7 @@
 import org.apache.ivy.util.CacheCleaner;
 import org.apache.ivy.util.FileUtil;
 import org.apache.ivy.util.MockMessageLogger;
+import org.apache.ivy.util.XMLHelper;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -74,6 +75,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -309,21 +311,58 @@
 
     @Test
     public void testResolveWithXmlEntities() {
+        testResolveWithXmlEntities(null, 0);
+        testResolveWithXmlEntities("prohibit", 0);
+        testResolveWithXmlEntities("ignore", 0);
+        testResolveWithXmlEntities("local-only", 2);
+        testResolveWithXmlEntities("LOCAL_ONLY", 2);
+        testResolveWithXmlEntities("all", 2);
+    }
+
+    private void testResolveWithXmlEntities(String 
externalResourcesSystemProperty,
+            int expectedNumberOfDependencies) {
         Ivy ivy = new Ivy();
         Throwable th = null;
+        Properties p = System.getProperties();
         try {
+            System.setProperties(new Properties());
+            System.setProperty(XMLHelper.ALLOW_DOCTYPE_PROCESSING, "true");
+            if (externalResourcesSystemProperty != null) {
+                System.setProperty(XMLHelper.EXTERNAL_RESOURCES, 
externalResourcesSystemProperty);
+            }
             ivy.configure(new 
File("test/repositories/xml-entities/ivysettings.xml"));
             ResolveReport report = ivy.resolve(new 
File("test/repositories/xml-entities/ivy.xml"),
                 getResolveOptions(new String[] {"*"}));
             assertNotNull(report);
             assertFalse(report.hasError());
+            assertNotNull(report.getDependencies());
+            assertEquals("number of dependencies while setting " + 
externalResourcesSystemProperty,
+                expectedNumberOfDependencies, report.getDependencies().size());
         } catch (Throwable e) {
             th = e;
+        } finally {
+            System.setProperties(p);
         }
         assertNull(th);
     }
 
     @Test
+    public void testResolveWithXmlEntitiesButNoSystemProperty() {
+        Ivy ivy = new Ivy();
+        Throwable th = null;
+        try {
+            ivy.configure(new 
File("test/repositories/xml-entities/ivysettings.xml"));
+            ResolveReport report = ivy.resolve(new 
File("test/repositories/xml-entities/ivy.xml"),
+                getResolveOptions(new String[] {"*"}));
+            assertNotNull(report);
+            assertFalse(report.hasError());
+        } catch (Throwable e) {
+            th = e;
+        }
+        assertNotNull(th);
+    }
+
+    @Test
     public void testResolveNoRevisionInPattern() throws Exception {
         // module1 depends on latest version of module2, for which there is no 
revision in the
         // pattern
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/core/retrieve/RetrieveTest.java 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/core/retrieve/RetrieveTest.java
--- 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/core/retrieve/RetrieveTest.java   
    2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/core/retrieve/RetrieveTest.java   
    2023-08-17 17:02:59.000000000 +0200
@@ -68,6 +68,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 public class RetrieveTest {
 
@@ -174,9 +175,13 @@
         ModuleRevisionId id = ModuleRevisionId.newInstance("fake", "a", "1.1");
         ModuleDescriptor fake = DefaultModuleDescriptor.newDefaultInstance(id);
         String pattern = 
"build/[organisation]/../../../[artifact]-[revision].[ext]";
-        testIvy.retrieve(fake.getModuleRevisionId(),
-            getRetrieveOptions().setDestArtifactPattern(pattern));
-        mockLogger.assertLogContains("not retrieving artifact");
+        try {
+            testIvy.retrieve(fake.getModuleRevisionId(),
+                             
getRetrieveOptions().setDestArtifactPattern(pattern));
+            fail("expected an exception");
+        } catch (RuntimeException ex) {
+            assertTrue(ex.getCause() instanceof IllegalArgumentException);
+        }
     }
 
     @Test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParserTest.java
 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParserTest.java
--- 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParserTest.java
  2022-11-01 10:24:51.000000000 +0100
+++ 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorParserTest.java
  2023-08-17 17:02:59.000000000 +0200
@@ -21,6 +21,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.fail;
 
 import java.io.File;
@@ -343,6 +344,94 @@
         assertEquals(extraAtt, 
dds[0].getAllDependencyArtifacts()[0].getExtraAttributes());
     }
 
+    /**
+     * @see "https://issues.apache.org/jira/browse/IVY-1642";
+     */
+    @Test
+    public void testDependenciesWithAndWithoutClassifier() throws Exception {
+        ModuleDescriptor md = 
PomModuleDescriptorParser.getInstance().parseDescriptor(settings,
+            
getClass().getResource("test-dependencies-with-and-without-classifier.pom"), 
true);
+        assertNotNull(md);
+
+        assertEquals(ModuleRevisionId.newInstance("org.apache", "test", "1.0"),
+            md.getModuleRevisionId());
+
+        DependencyDescriptor[] dds = md.getDependencies();
+        assertNotNull(dds);
+        assertEquals(5, dds.length);
+        Map<String, String> extraAtt = Collections.singletonMap("classifier", 
"asl");
+        assertEquals(ModuleRevisionId.newInstance("commons-logging", 
"commons-logging", "1.0.4"),
+            dds[0].getDependencyRevisionId());
+        DependencyArtifactDescriptor[] dads = 
dds[0].getAllDependencyArtifacts();
+        assertEquals(2, dads.length);
+        assertEquals(Collections.emptyMap(), dads[0].getExtraAttributes());
+        assertEquals(extraAtt, dads[1].getExtraAttributes());
+
+        assertEquals(ModuleRevisionId.newInstance("commons-logging", 
"commons-logging2", "1.0.4"),
+            dds[1].getDependencyRevisionId());
+        dads = dds[1].getAllDependencyArtifacts();
+        assertEquals(2, dads.length);
+        assertEquals(Collections.emptyMap(), dads[1].getExtraAttributes());
+        assertEquals(extraAtt, dads[0].getExtraAttributes());
+
+        assertEquals(ModuleRevisionId.newInstance("commons-logging", 
"commons-logging3", "1.0.4"),
+            dds[2].getDependencyRevisionId());
+        dads = dds[2].getAllDependencyArtifacts();
+        assertEquals(2, dads.length);
+        assertEquals(extraAtt, dads[0].getExtraAttributes());
+        assertEquals(Collections.singletonMap("classifier", "foo"),
+                     dads[1].getExtraAttributes());
+
+        assertEquals(ModuleRevisionId.newInstance("commons-logging", 
"commons-logging4", "1.0.4"),
+            dds[3].getDependencyRevisionId());
+        dads = dds[3].getAllDependencyArtifacts();
+        assertEquals(2, dads.length);
+        assertEquals(Collections.emptyMap(), dads[0].getExtraAttributes());
+        assertEquals(extraAtt, dads[1].getExtraAttributes());
+        DependencyArtifactDescriptor[] providedDads = 
dds[3].getDependencyArtifacts("provided");
+        assertEquals(1, providedDads.length);
+        assertSame(dads[0], providedDads[0]);
+        DependencyArtifactDescriptor[] compileDads = 
dds[3].getDependencyArtifacts("compile");
+        assertEquals(1, compileDads.length);
+        assertSame(dads[1], compileDads[0]);
+
+        assertEquals(ModuleRevisionId.newInstance("commons-logging", 
"commons-logging5", "1.0.4"),
+            dds[4].getDependencyRevisionId());
+        dads = dds[4].getAllDependencyArtifacts();
+        assertEquals(2, dads.length);
+        assertEquals(extraAtt, dads[0].getExtraAttributes());
+        assertEquals(Collections.emptyMap(), dads[1].getExtraAttributes());
+        providedDads = dds[4].getDependencyArtifacts("provided");
+        assertEquals(1, providedDads.length);
+        assertSame(dads[1], providedDads[0]);
+        compileDads = dds[4].getDependencyArtifacts("compile");
+        assertEquals(1, compileDads.length);
+        assertSame(dads[0], compileDads[0]);
+
+        // now we verify the conversion to an Ivy file
+        PomModuleDescriptorParser.getInstance().toIvyFile(
+            
getClass().getResource("test-dependencies-with-and-without-classifier.pom").openStream(),
+            new 
URLResource(getClass().getResource("test-dependencies-with-and-without-classifier.pom")),
 dest,
+            md);
+
+        assertTrue(dest.exists());
+
+        // the converted Ivy file should be parsable with validate=true
+        ModuleDescriptor md2 = 
XmlModuleDescriptorParser.getInstance().parseDescriptor(
+            new IvySettings(), dest.toURI().toURL(), true);
+
+        // and the parsed module descriptor should be similar to the original
+        assertNotNull(md2);
+        assertEquals(md.getModuleRevisionId(), md2.getModuleRevisionId());
+        dds = md2.getDependencies();
+        assertEquals(5, dds.length);
+        for (int i = 0; i < dds.length; i++) {
+            assertEquals(2, dds[i].getAllDependencyArtifacts().length);
+            int withExt = i == 0 || i == 3 ? 1: 0;
+            assertEquals(extraAtt, 
dds[i].getAllDependencyArtifacts()[withExt].getExtraAttributes());
+        }
+    }
+
     @Test
     public void testDependenciesWithType() throws Exception {
         ModuleDescriptor md = 
PomModuleDescriptorParser.getInstance().parseDescriptor(settings,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/plugins/parser/m2/test-dependencies-with-and-without-classifier.pom
 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/plugins/parser/m2/test-dependencies-with-and-without-classifier.pom
--- 
old/apache-ivy-2.5.1/test/java/org/apache/ivy/plugins/parser/m2/test-dependencies-with-and-without-classifier.pom
   1970-01-01 01:00:00.000000000 +0100
+++ 
new/apache-ivy-2.5.2/test/java/org/apache/ivy/plugins/parser/m2/test-dependencies-with-and-without-classifier.pom
   2023-08-17 17:02:59.000000000 +0200
@@ -0,0 +1,91 @@
+<?xml version="1.0"?>
+<!--
+   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
+
+     https://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.
+-->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache</groupId>
+  <artifactId>test</artifactId>
+  <name>Test Module for Ivy M2 parsing</name>
+  <version>1.0</version>
+  <url>http://ant.apache.org/ivy</url>
+  <organization>
+    <name>Apache</name>
+    <url>http://ant.apache.org/ivy</url>
+  </organization>
+  <dependencies>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.4</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.4</version>
+      <classifier>asl</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging2</artifactId>
+      <version>1.0.4</version>
+      <classifier>asl</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging2</artifactId>
+      <version>1.0.4</version>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging3</artifactId>
+      <version>1.0.4</version>
+      <classifier>asl</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging3</artifactId>
+      <version>1.0.4</version>
+      <classifier>foo</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging4</artifactId>
+      <version>1.0.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging4</artifactId>
+      <version>1.0.4</version>
+      <classifier>asl</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging5</artifactId>
+      <version>1.0.4</version>
+      <classifier>asl</classifier>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging5</artifactId>
+      <version>1.0.4</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/apache-ivy-2.5.1/version.properties 
new/apache-ivy-2.5.2/version.properties
--- old/apache-ivy-2.5.1/version.properties     2022-11-01 10:24:51.000000000 
+0100
+++ new/apache-ivy-2.5.2/version.properties     2023-08-17 17:02:59.000000000 
+0200
@@ -16,9 +16,9 @@
 #       * specific language governing permissions and limitations
 #       * under the License.
 #       ***************************************************************
-target.ivy.version=2.5.1
+target.ivy.version=2.5.2
 # Following OSGi spec: have to be 3 numbers separated by dots
-target.ivy.bundle.version=2.5.1
+target.ivy.bundle.version=2.5.2
 # in case we want to add a qualifier such as alpha, beta, etc...
 # if non empty, add a '_' at the end of the qualifier, so the version would 
look like 1.2.3.alpha_200901011200
 # NB: be careful with naming, OSGi orders version alphabetically. Suggested 
values: alpha_, beta_, cr1_ (for RC-1), final_
@@ -29,15 +29,15 @@
 #----------------------------------
 # 'ant.version' is a built in name containing the version of the current 
 # running Ant, so we could not use that name here.
-apache-ant.version=1.9.14
+apache-ant.version=1.9.16
 ant-contrib.version=1.0b3
-bouncycastle.version=1.64
+bouncycastle.version=1.70
 commons-vfs2.version=2.2
 hamcrest.version=1.3
-httpclient.version=4.5.10
+httpclient.version=4.5.13
 jacoco.version=0.8.6
 jsch.agentproxy.version=0.0.9
 jsch.version=0.1.55
-junit.version=4.12
+junit.version=4.13.2
 oro.version=2.0.8
 xmlunit.version=1.6

++++++ ivy-2.5.1.pom -> ivy-2.5.2.pom ++++++
--- /work/SRC/openSUSE:Factory/apache-ivy/ivy-2.5.1.pom 2022-11-15 
13:20:41.480573367 +0100
+++ /work/SRC/openSUSE:Factory/.apache-ivy.new.1766/ivy-2.5.2.pom       
2023-08-23 14:56:38.677886146 +0200
@@ -28,7 +28,7 @@
   </parent>
   <groupId>org.apache.ivy</groupId>
   <artifactId>ivy</artifactId>
-  <version>2.5.1</version>
+  <version>2.5.2</version>
   <name>Apache Ivy</name>
   <url>http://ant.apache.org/ivy/</url>
   <scm>
@@ -60,13 +60,13 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant</artifactId>
-      <version>1.9.14</version>
+      <version>1.9.16</version>
       <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
-      <version>4.5.10</version>
+      <version>4.5.13</version>
       <optional>true</optional>
     </dependency>
     <dependency>
@@ -108,19 +108,19 @@
     <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcpg-jdk15on</artifactId>
-      <version>1.64</version>
+      <version>1.70</version>
       <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcprov-jdk15on</artifactId>
-      <version>1.64</version>
+      <version>1.70</version>
       <optional>true</optional>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.12</version>
+      <version>4.13.2</version>
       <scope>test</scope>
     </dependency>
     <dependency>
@@ -138,7 +138,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant-testutil</artifactId>
-      <version>1.9.14</version>
+      <version>1.9.16</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>
@@ -150,7 +150,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant-launcher</artifactId>
-      <version>1.9.14</version>
+      <version>1.9.16</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>
@@ -162,7 +162,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant-junit</artifactId>
-      <version>1.9.14</version>
+      <version>1.9.16</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>
@@ -174,7 +174,7 @@
     <dependency>
       <groupId>org.apache.ant</groupId>
       <artifactId>ant-junit4</artifactId>
-      <version>1.9.14</version>
+      <version>1.9.16</version>
       <scope>test</scope>
       <exclusions>
         <exclusion>

Reply via email to