Author: maartenc
Date: Tue Nov 13 13:04:30 2007
New Revision: 594641

URL: http://svn.apache.org/viewvc?rev=594641&view=rev
Log:
Attempt to download a file with & in its name causes SAXParseException in Ivy 
(IVY-635)

Added:
    incubator/ivy/core/trunk/test/repositories/IVY-635/
    incubator/ivy/core/trunk/test/repositories/IVY-635/ivysettings.xml
    incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/
    incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/art1&_.txt
    incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/ivy.xml
Modified:
    incubator/ivy/core/trunk/CHANGES.txt
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
    
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/report/XmlReportOutputter.java
    incubator/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java
    
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/report/XmlReportOutputterTest.java

Modified: incubator/ivy/core/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/CHANGES.txt?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- incubator/ivy/core/trunk/CHANGES.txt (original)
+++ incubator/ivy/core/trunk/CHANGES.txt Tue Nov 13 13:04:30 2007
@@ -53,6 +53,7 @@
 
    version in SVN
 =====================================
+- FIX: Attempt to download a file with & in its name causes SAXParseException 
in Ivy (IVY-635)
 - FIX: Bad IvyContext scope causing memory leak and bad handling of subproject 
builds (IVY-639)
 - FIX: Resolution failure when no ivy.xml file present (IVY-630)
 - FIX: ${parent.version} property is not recognized in maven2 pom (IVY-620)

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorUpdater.java
 Tue Nov 13 13:04:30 2007
@@ -509,13 +509,13 @@
             ModuleRevisionId systemMid = ns == null ? localMid : 
ns.getToSystemTransformer()
                     .transform(localMid);
 
-            write("<info organisation=\"" + systemMid.getOrganisation() + "\" 
module=\""
-                    + systemMid.getName() + "\"");
+            write("<info organisation=\"" + 
XMLHelper.escape(systemMid.getOrganisation()) + "\" module=\""
+                    + XMLHelper.escape(systemMid.getName()) + "\"");
             if (systemMid.getRevision() != null) {
-                write(" revision=\"" + systemMid.getRevision() + "\"");
+                write(" revision=\"" + 
XMLHelper.escape(systemMid.getRevision()) + "\"");
             }
             if (status != null) {
-                write(" status=\"" + status + "\"");
+                write(" status=\"" + XMLHelper.escape(status) + "\"");
             } else {
                 write(" status=\"" + substitute(settings, 
attributes.getValue("status")) + "\"");
             }
@@ -561,7 +561,8 @@
         }
 
         private String substitute(ParserSettings ivy, String value) {
-            return ivy == null ? value : ivy.substitute(value);
+            String result = ivy == null ? value : ivy.substitute(value);
+            return XMLHelper.escape(result);
         }
 
         private String removeConfigurationsFromMapping(String mapping, List 
confsToRemove) {

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorWriter.java
 Tue Nov 13 13:04:30 2007
@@ -35,6 +35,7 @@
 import org.apache.ivy.core.module.descriptor.ExcludeRule;
 import org.apache.ivy.core.module.descriptor.IncludeRule;
 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
+import org.apache.ivy.util.XMLHelper;
 
 /**
  *
@@ -78,11 +79,10 @@
             out.println("\t<dependencies>");
             for (int i = 0; i < dds.length; i++) {
                 out.print("\t\t<dependency");
-                out
-                        .print(" org=\"" + 
dds[i].getDependencyRevisionId().getOrganisation()
+                out.print(" org=\"" + 
XMLHelper.escape(dds[i].getDependencyRevisionId().getOrganisation())
                                 + "\"");
-                out.print(" name=\"" + 
dds[i].getDependencyRevisionId().getName() + "\"");
-                out.print(" rev=\"" + 
dds[i].getDependencyRevisionId().getRevision() + "\"");
+                out.print(" name=\"" + 
XMLHelper.escape(dds[i].getDependencyRevisionId().getName()) + "\"");
+                out.print(" rev=\"" + 
XMLHelper.escape(dds[i].getDependencyRevisionId().getRevision()) + "\"");
                 if (dds[i].isForce()) {
                     out.print(" force=\"" + dds[i].isForce() + "\"");
                 }
@@ -96,9 +96,9 @@
                 String[] modConfs = dds[i].getModuleConfigurations();
                 for (int j = 0; j < modConfs.length; j++) {
                     String[] depConfs = 
dds[i].getDependencyConfigurations(modConfs[j]);
-                    out.print(modConfs[j] + "->");
+                    out.print(XMLHelper.escape(modConfs[j]) + "->");
                     for (int k = 0; k < depConfs.length; k++) {
-                        out.print(depConfs[k]);
+                        out.print(XMLHelper.escape(depConfs[k]));
                         if (k + 1 < depConfs.length) {
                             out.print(",");
                         }
@@ -142,25 +142,25 @@
             for (int j = 0; j < excludes.length; j++) {
                 out.print("\t\t<exclude");
                 out.print(" org=\""
-                        + excludes[j].getId().getModuleId().getOrganisation() 
+ "\"");
-                out.print(" module=\"" + 
excludes[j].getId().getModuleId().getName()
+                        + 
XMLHelper.escape(excludes[j].getId().getModuleId().getOrganisation()) + "\"");
+                out.print(" module=\"" + 
XMLHelper.escape(excludes[j].getId().getModuleId().getName())
                         + "\"");
-                out.print(" artifact=\"" + excludes[j].getId().getName() + 
"\"");
-                out.print(" type=\"" + excludes[j].getId().getType() + "\"");
-                out.print(" ext=\"" + excludes[j].getId().getExt() + "\"");
+                out.print(" artifact=\"" + 
XMLHelper.escape(excludes[j].getId().getName()) + "\"");
+                out.print(" type=\"" + 
XMLHelper.escape(excludes[j].getId().getType()) + "\"");
+                out.print(" ext=\"" + 
XMLHelper.escape(excludes[j].getId().getExt()) + "\"");
                 String[] ruleConfs = excludes[j].getConfigurations();
                 if (!Arrays.asList(ruleConfs).equals(
                     Arrays.asList(md.getConfigurationsNames()))) {
                     out.print(" conf=\"");
                     for (int k = 0; k < ruleConfs.length; k++) {
-                        out.print(ruleConfs[k]);
+                        out.print(XMLHelper.escape(ruleConfs[k]));
                         if (k + 1 < ruleConfs.length) {
                             out.print(",");
                         }
                     }
                     out.print("\"");
                 }
-                out.print(" matcher=\"" + excludes[j].getMatcher().getName() + 
"\"");
+                out.print(" matcher=\"" + 
XMLHelper.escape(excludes[j].getMatcher().getName()) + "\"");
                 out.println("/>");
             }
         }
@@ -173,25 +173,25 @@
             for (int j = 0; j < excludes.length; j++) {
                 out.print("\t\t\t<exclude");
                 out.print(" org=\""
-                        + excludes[j].getId().getModuleId().getOrganisation() 
+ "\"");
-                out.print(" module=\"" + 
excludes[j].getId().getModuleId().getName()
+                        + 
XMLHelper.escape(excludes[j].getId().getModuleId().getOrganisation()) + "\"");
+                out.print(" module=\"" + 
XMLHelper.escape(excludes[j].getId().getModuleId().getName())
                         + "\"");
-                out.print(" name=\"" + excludes[j].getId().getName() + "\"");
-                out.print(" type=\"" + excludes[j].getId().getType() + "\"");
-                out.print(" ext=\"" + excludes[j].getId().getExt() + "\"");
+                out.print(" name=\"" + 
XMLHelper.escape(excludes[j].getId().getName()) + "\"");
+                out.print(" type=\"" + 
XMLHelper.escape(excludes[j].getId().getType()) + "\"");
+                out.print(" ext=\"" + 
XMLHelper.escape(excludes[j].getId().getExt()) + "\"");
                 String[] ruleConfs = excludes[j].getConfigurations();
                 if (!Arrays.asList(ruleConfs).equals(
                     Arrays.asList(md.getConfigurationsNames()))) {
                     out.print(" conf=\"");
                     for (int k = 0; k < ruleConfs.length; k++) {
-                        out.print(ruleConfs[k]);
+                        out.print(XMLHelper.escape(ruleConfs[k]));
                         if (k + 1 < ruleConfs.length) {
                             out.print(",");
                         }
                     }
                     out.print("\"");
                 }
-                out.print(" matcher=\"" + excludes[j].getMatcher().getName() + 
"\"");
+                out.print(" matcher=\"" + 
XMLHelper.escape(excludes[j].getMatcher().getName()) + "\"");
                 out.println("/>");
             }
         }
@@ -202,22 +202,22 @@
         if (includes.length > 0) {
             for (int j = 0; j < includes.length; j++) {
                 out.print("\t\t\t<include");
-                out.print(" name=\"" + includes[j].getId().getName() + "\"");
-                out.print(" type=\"" + includes[j].getId().getType() + "\"");
-                out.print(" ext=\"" + includes[j].getId().getExt() + "\"");
+                out.print(" name=\"" + 
XMLHelper.escape(includes[j].getId().getName()) + "\"");
+                out.print(" type=\"" + 
XMLHelper.escape(includes[j].getId().getType()) + "\"");
+                out.print(" ext=\"" + 
XMLHelper.escape(includes[j].getId().getExt()) + "\"");
                 String[] ruleConfs = includes[j].getConfigurations();
                 if (!Arrays.asList(ruleConfs).equals(
                     Arrays.asList(md.getConfigurationsNames()))) {
                     out.print(" conf=\"");
                     for (int k = 0; k < ruleConfs.length; k++) {
-                        out.print(ruleConfs[k]);
+                        out.print(XMLHelper.escape(ruleConfs[k]));
                         if (k + 1 < ruleConfs.length) {
                             out.print(",");
                         }
                     }
                     out.print("\"");
                 }
-                out.print(" matcher=\"" + includes[j].getMatcher().getName() + 
"\"");
+                out.print(" matcher=\"" + 
XMLHelper.escape(includes[j].getMatcher().getName()) + "\"");
                 out.println("/>");
             }
         }
@@ -228,15 +228,15 @@
         if (depArtifacts.length > 0) {
             for (int j = 0; j < depArtifacts.length; j++) {
                 out.print("\t\t\t<artifact");
-                out.print(" name=\"" + depArtifacts[j].getName() + "\"");
-                out.print(" type=\"" + depArtifacts[j].getType() + "\"");
-                out.print(" ext=\"" + depArtifacts[j].getExt() + "\"");
+                out.print(" name=\"" + 
XMLHelper.escape(depArtifacts[j].getName()) + "\"");
+                out.print(" type=\"" + 
XMLHelper.escape(depArtifacts[j].getType()) + "\"");
+                out.print(" ext=\"" + 
XMLHelper.escape(depArtifacts[j].getExt()) + "\"");
                 String[] dadconfs = depArtifacts[j].getConfigurations();
                 if (!Arrays.asList(dadconfs).equals(
                     Arrays.asList(md.getConfigurationsNames()))) {
                     out.print(" conf=\"");
                     for (int k = 0; k < dadconfs.length; k++) {
-                        out.print(dadconfs[k]);
+                        out.print(XMLHelper.escape(dadconfs[k]));
                         if (k + 1 < dadconfs.length) {
                             out.print(",");
                         }
@@ -246,7 +246,7 @@
                 Map extra = depArtifacts[j].getExtraAttributes();
                 for (Iterator iter = extra.entrySet().iterator(); 
iter.hasNext();) {
                     Map.Entry entry = (Map.Entry) iter.next();
-                    out.print(" " + entry.getKey() + "=\"" + entry.getValue() 
+ "\"");
+                    out.print(" " + entry.getKey() + "=\"" + 
XMLHelper.escape(entry.getValue().toString()) + "\"");
                 }
                 out.println("/>");
             }
@@ -258,10 +258,10 @@
         Artifact[] artifacts = md.getAllArtifacts();
         for (int i = 0; i < artifacts.length; i++) {
             out.print("\t\t<artifact");
-            out.print(" name=\"" + artifacts[i].getName() + "\"");
-            out.print(" type=\"" + artifacts[i].getType() + "\"");
-            out.print(" ext=\"" + artifacts[i].getExt() + "\"");
-            out.print(" conf=\"" + getConfs(md, artifacts[i]) + "\"");
+            out.print(" name=\"" + XMLHelper.escape(artifacts[i].getName()) + 
"\"");
+            out.print(" type=\"" + XMLHelper.escape(artifacts[i].getType()) + 
"\"");
+            out.print(" ext=\"" + XMLHelper.escape(artifacts[i].getExt()) + 
"\"");
+            out.print(" conf=\"" + XMLHelper.escape(getConfs(md, 
artifacts[i])) + "\"");
             out.println("/>");
         }
         out.println("\t</publications>");
@@ -273,16 +273,16 @@
             out.println("\t<configurations>");
             for (int i = 0; i < confs.length; i++) {
                 out.print("\t\t<conf");
-                out.print(" name=\"" + confs[i].getName() + "\"");
-                out.print(" visibility=\"" + confs[i].getVisibility() + "\"");
+                out.print(" name=\"" + XMLHelper.escape(confs[i].getName()) + 
"\"");
+                out.print(" visibility=\"" + 
XMLHelper.escape(confs[i].getVisibility().toString()) + "\"");
                 if (confs[i].getDescription() != null) {
-                    out.print(" description=\"" + confs[i].getDescription() + 
"\"");
+                    out.print(" description=\"" + 
XMLHelper.escape(confs[i].getDescription()) + "\"");
                 }
                 String[] exts = confs[i].getExtends();
                 if (exts.length > 0) {
                     out.print(" extends=\"");
                     for (int j = 0; j < exts.length; j++) {
-                        out.print(exts[j]);
+                        out.print(XMLHelper.escape(exts[j]));
                         if (j + 1 < exts.length) {
                             out.print(",");
                         }
@@ -296,18 +296,18 @@
     }
 
     private static void printInfoTag(ModuleDescriptor md, PrintWriter out) {
-        out.println("\t<info organisation=\"" + 
md.getModuleRevisionId().getOrganisation()
+        out.println("\t<info organisation=\"" + 
XMLHelper.escape(md.getModuleRevisionId().getOrganisation())
                 + "\"");
-        out.println("\t\tmodule=\"" + md.getModuleRevisionId().getName() + 
"\"");
+        out.println("\t\tmodule=\"" + 
XMLHelper.escape(md.getModuleRevisionId().getName()) + "\"");
         String branch = md.getResolvedModuleRevisionId().getBranch();
         if (branch != null) {
-            out.println("\t\tbranch=\"" + branch + "\"");
+            out.println("\t\tbranch=\"" + XMLHelper.escape(branch) + "\"");
         }
         String revision = md.getResolvedModuleRevisionId().getRevision();
         if (revision != null) {
-            out.println("\t\trevision=\"" + revision + "\"");
+            out.println("\t\trevision=\"" + XMLHelper.escape(revision) + "\"");
         }
-        out.println("\t\tstatus=\"" + md.getStatus() + "\"");
+        out.println("\t\tstatus=\"" + XMLHelper.escape(md.getStatus()) + "\"");
         out.println("\t\tpublication=\""
                 + Ivy.DATE_FORMAT.format(md.getResolvedPublicationDate()) + 
"\"");
         if (md.isDefault()) {
@@ -316,7 +316,7 @@
         if (md instanceof DefaultModuleDescriptor) {
             DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) md;
             if (dmd.getNamespace() != null && 
!dmd.getNamespace().getName().equals("system")) {
-                out.println("\t\tnamespace=\"" + dmd.getNamespace().getName() 
+ "\"");
+                out.println("\t\tnamespace=\"" + 
XMLHelper.escape(dmd.getNamespace().getName()) + "\"");
             }
         }
         out.println("\t/>");

Modified: 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/report/XmlReportOutputter.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/report/XmlReportOutputter.java?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/report/XmlReportOutputter.java
 (original)
+++ 
incubator/ivy/core/trunk/src/java/org/apache/ivy/plugins/report/XmlReportOutputter.java
 Tue Nov 13 13:04:30 2007
@@ -46,6 +46,7 @@
 import org.apache.ivy.util.FileUtil;
 import org.apache.ivy.util.Message;
 import org.apache.ivy.util.StringUtils;
+import org.apache.ivy.util.XMLHelper;
 
 /**
  *
@@ -104,19 +105,19 @@
         out.println("<?xml-stylesheet type=\"text/xsl\" 
href=\"ivy-report.xsl\"?>");
         out.println("<ivy-report version=\"1.0\">");
         out.println("\t<info");
-        out.println("\t\torganisation=\"" + mrid.getOrganisation() + "\"");
-        out.println("\t\tmodule=\"" + mrid.getName() + "\"");
-        out.println("\t\trevision=\"" + mrid.getRevision() + "\"");
+        out.println("\t\torganisation=\"" + 
XMLHelper.escape(mrid.getOrganisation()) + "\"");
+        out.println("\t\tmodule=\"" + XMLHelper.escape(mrid.getName()) + "\"");
+        out.println("\t\trevision=\"" + XMLHelper.escape(mrid.getRevision()) + 
"\"");
         if (mrid.getBranch() != null) {
-            out.println("\t\tbranch=\"" + mrid.getBranch() + "\"");
+            out.println("\t\tbranch=\"" + XMLHelper.escape(mrid.getBranch()) + 
"\"");
         }
         Map extraAttributes = mrid.getExtraAttributes();
         for (Iterator it = extraAttributes.entrySet().iterator(); 
it.hasNext();) {
             Map.Entry entry = (Entry) it.next();
-            out.println("\t\textra-" + entry.getKey() + "=\"" + 
entry.getValue() + "\"");
+            out.println("\t\textra-" + entry.getKey() + "=\"" + 
XMLHelper.escape(entry.getValue().toString()) + "\"");
         }
-        out.println("\t\tconf=\"" + report.getConfiguration() + "\"");
-        out.println("\t\tconfs=\"" + StringUtils.join(confs, ", ") + "\"");
+        out.println("\t\tconf=\"" + 
XMLHelper.escape(report.getConfiguration()) + "\"");
+        out.println("\t\tconfs=\"" + XMLHelper.escape(StringUtils.join(confs, 
", ")) + "\"");
         out.println("\t\tdate=\"" + Ivy.DATE_FORMAT.format(report.getDate()) + 
"\"/>");
 
         out.println("\t<dependencies>");
@@ -126,9 +127,9 @@
 
         for (Iterator iter = report.getModuleIds().iterator(); 
iter.hasNext();) {
             ModuleId mid = (ModuleId) iter.next();
-            out.println("\t\t<module organisation=\"" + mid.getOrganisation() 
+ "\"" + " name=\""
-                    + mid.getName() + "\"" + " resolver=\""
-                    + 
report.getResolveEngine().getSettings().getResolverName(mid) + "\">");
+            out.println("\t\t<module organisation=\"" + 
XMLHelper.escape(mid.getOrganisation()) + "\"" + " name=\""
+                    + XMLHelper.escape(mid.getName()) + "\"" + " resolver=\""
+                    + 
XMLHelper.escape(report.getResolveEngine().getSettings().getResolverName(mid)) 
+ "\">");
             for (Iterator it2 = report.getNodes(mid).iterator(); 
it2.hasNext();) {
                 IvyNode dep = (IvyNode) it2.next();
                 ModuleDescriptor md = null;
@@ -137,44 +138,45 @@
                 }
                 StringBuffer details = new StringBuffer();
                 if (dep.isLoaded()) {
-                    details.append(" 
status=\"").append(dep.getDescriptor().getStatus()).append(
-                        "\"").append(" pubdate=\"").append(
-                        Ivy.DATE_FORMAT.format(new 
Date(dep.getPublication()))).append("\"")
-                            .append(" resolver=\"").append(
-                                
dep.getModuleRevision().getResolver().getName()).append("\"")
-                            .append(" artresolver=\"").append(
-                                
dep.getModuleRevision().getArtifactResolver().getName()).append(
-                                "\"");
+                    details.append(" status=\"");
+                    
details.append(XMLHelper.escape(dep.getDescriptor().getStatus()));
+                    details.append("\" pubdate=\"");
+                    details.append(Ivy.DATE_FORMAT.format(new 
Date(dep.getPublication())));
+                    details.append("\" resolver=\"");
+                    
details.append(XMLHelper.escape(dep.getModuleRevision().getResolver().getName()));
+                    details.append("\" artresolver=\"");
+                    
details.append(XMLHelper.escape(dep.getModuleRevision().getArtifactResolver().getName()));
+                    details.append("\"");
                 }
                 if (dep.isEvicted(report.getConfiguration())) {
                     EvictionData ed = 
dep.getEvictedData(report.getConfiguration());
                     if (ed.getConflictManager() != null) {
-                        details.append(" 
evicted=\"").append(ed.getConflictManager()).append("\"");
+                        details.append(" 
evicted=\"").append(XMLHelper.escape(ed.getConflictManager().toString())).append("\"");
                     } else {
                         details.append(" evicted=\"transitive\"");
                     }
                 }
                 if (dep.hasProblem()) {
-                    details.append(" 
error=\"").append(dep.getProblem().getMessage()).append("\"");
+                    details.append(" 
error=\"").append(XMLHelper.escape(dep.getProblem().getMessage())).append("\"");
                 }
                 if (md != null && md.getHomePage() != null) {
-                    details.append(" 
homepage=\"").append(md.getHomePage()).append("\"");
+                    details.append(" 
homepage=\"").append(XMLHelper.escape(md.getHomePage())).append("\"");
                 }
                 extraAttributes = md != null ? md.getExtraAttributes() : 
dep.getResolvedId()
                         .getExtraAttributes();
                 for (Iterator iterator = extraAttributes.keySet().iterator(); 
iterator.hasNext();) {
                     String attName = (String) iterator.next();
                     details.append(" 
extra-").append(attName).append("=\"").append(
-                        extraAttributes.get(attName)).append("\"");
+                        
XMLHelper.escape(extraAttributes.get(attName).toString())).append("\"");
                 }
                 String defaultValue = dep.getDescriptor() != null ? " 
default=\""
                         + dep.getDescriptor().isDefault() + "\"" : "";
                 int position = dependencies.indexOf(dep.getResolvedId());
                 out.println("\t\t\t<revision name=\""
-                        + dep.getResolvedId().getRevision()
+                        + XMLHelper.escape(dep.getResolvedId().getRevision())
                         + "\""
                         + (dep.getResolvedId().getBranch() == null ? "" : " 
branch=\""
-                                + dep.getResolvedId().getBranch() + "\"") + 
details
+                                + 
XMLHelper.escape(dep.getResolvedId().getBranch()) + "\"") + details
                         + " downloaded=\"" + dep.isDownloaded() + "\"" + " 
searched=\""
                         + dep.isSearched() + "\"" + defaultValue + " conf=\""
                         + 
toString(dep.getConfigurations(report.getConfiguration())) + "\""
@@ -184,11 +186,11 @@
                     for (int i = 0; i < licenses.length; i++) {
                         String lurl;
                         if (licenses[i].getUrl() != null) {
-                            lurl = " url=\"" + licenses[i].getUrl() + "\"";
+                            lurl = " url=\"" + 
XMLHelper.escape(licenses[i].getUrl()) + "\"";
                         } else {
                             lurl = "";
                         }
-                        out.println("\t\t\t\t<license name=\"" + 
licenses[i].getName() + "\""
+                        out.println("\t\t\t\t<license name=\"" + 
XMLHelper.escape(licenses[i].getName()) + "\""
                                 + lurl + "/>");
                     }
                 }
@@ -199,7 +201,7 @@
                         for (Iterator it3 = selected.iterator(); 
it3.hasNext();) {
                             IvyNode sel = (IvyNode) it3.next();
                             out.println("\t\t\t\t<evicted-by rev=\""
-                                    + sel.getResolvedId().getRevision() + 
"\"/>");
+                                    + 
XMLHelper.escape(sel.getResolvedId().getRevision()) + "\"/>");
                         }
                     }
                 }
@@ -212,30 +214,30 @@
                             .hasNext();) {
                         String attName = (String) iterator.next();
                         callerDetails.append(" 
extra-").append(attName).append("=\"").append(
-                            callerExtraAttributes.get(attName)).append("\"");
+                            
XMLHelper.escape(callerExtraAttributes.get(attName).toString())).append("\"");
                     }
 
                     out.println("\t\t\t\t<caller organisation=\""
-                            + 
callers[i].getModuleRevisionId().getOrganisation() + "\""
-                            + " name=\"" + 
callers[i].getModuleRevisionId().getName() + "\""
-                            + " conf=\"" + 
toString(callers[i].getCallerConfigurations()) + "\""
-                            + " rev=\"" + 
callers[i].getAskedDependencyId().getRevision() + "\""
+                            + 
XMLHelper.escape(callers[i].getModuleRevisionId().getOrganisation()) + "\""
+                            + " name=\"" + 
XMLHelper.escape(callers[i].getModuleRevisionId().getName()) + "\""
+                            + " conf=\"" + 
XMLHelper.escape(toString(callers[i].getCallerConfigurations())) + "\""
+                            + " rev=\"" + 
XMLHelper.escape(callers[i].getAskedDependencyId().getRevision()) + "\""
                             + callerDetails + "/>");
                 }
                 ArtifactDownloadReport[] adr = 
report.getDownloadReports(dep.getResolvedId());
                 out.println("\t\t\t\t<artifacts>");
                 for (int i = 0; i < adr.length; i++) {
-                    out.print("\t\t\t\t\t<artifact name=\"" + adr[i].getName() 
+ "\" type=\""
-                            + adr[i].getType() + "\" ext=\"" + adr[i].getExt() 
+ "\"");
+                    out.print("\t\t\t\t\t<artifact name=\"" + 
XMLHelper.escape(adr[i].getName()) + "\" type=\""
+                            + XMLHelper.escape(adr[i].getType()) + "\" ext=\"" 
+ XMLHelper.escape(adr[i].getExt()) + "\"");
                     extraAttributes = 
adr[i].getArtifact().getExtraAttributes();
                     for (Iterator iterator = 
extraAttributes.keySet().iterator(); iterator
                             .hasNext();) {
                         String attName = (String) iterator.next();
                         out
-                                .print(" extra-" + attName + "=\"" + 
extraAttributes.get(attName)
+                                .print(" extra-" + attName + "=\"" + 
XMLHelper.escape(extraAttributes.get(attName).toString())
                                         + "\"");
                     }
-                    out.print(" status=\"" + adr[i].getDownloadStatus() + 
"\"");
+                    out.print(" status=\"" + 
XMLHelper.escape(adr[i].getDownloadStatus().toString()) + "\"");
                     out.print(" size=\"" + adr[i].getSize() + "\"");
 
                     ArtifactOrigin origin = adr[i].getArtifactOrigin();
@@ -243,7 +245,7 @@
                         out.println(">");
                         out.println("\t\t\t\t\t\t<origin-location is-local=\""
                                 + String.valueOf(origin.isLocal()) + "\"" + " 
location=\""
-                                + origin.getLocation() + "\"/>");
+                                + XMLHelper.escape(origin.getLocation()) + 
"\"/>");
                         out.println("\t\t\t\t\t</artifact>");
                     } else {
                         out.println("/>");
@@ -267,6 +269,6 @@
                 buf.append(", ");
             }
         }
-        return buf.toString();
+        return XMLHelper.escape(buf.toString());
     }
 }

Modified: incubator/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- incubator/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java 
(original)
+++ incubator/ivy/core/trunk/src/java/org/apache/ivy/util/XMLHelper.java Tue 
Nov 13 13:04:30 2007
@@ -124,5 +124,47 @@
     public static boolean canUseSchemaValidation() {
         return _canUseSchemaValidation;
     }
+    
+    /**
+     * Escapes invalid XML characters in the given character data using XML 
entities.
+     * For the moment, only the following characters are being escaped: (<), 
(&), (') 
+     * and (").
+     * 
+     * Remark: we don't escape the (>) character to keep the readability of the
+     * configuration mapping! The XML spec only requires that the (&) and (<)
+     * characters are being escaped inside character data.
+     * 
+     * @param text the character data to escape
+     * @return the escaped character data
+     */
+    public static String escape(String text) {
+        if (text == null) {
+            return null;
+        }
+        
+        StringBuffer result = new StringBuffer(text.length());
+        
+        char[] chars = text.toCharArray();
+        for (int i = 0; i < chars.length; i++) {
+            switch (chars[i]) {
+                case '&':
+                    result.append("&amp;");
+                    break;
+                case '<':
+                    result.append("&lt;");
+                    break;
+                case '\'':
+                    result.append("&apos;");
+                    break;
+                case '\"':
+                    result.append("&quot;");
+                    break;
+                default:
+                    result.append(chars[i]);
+            }
+        }
+        
+        return result.toString();
+    }
 
 }

Modified: 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/report/XmlReportOutputterTest.java
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/report/XmlReportOutputterTest.java?rev=594641&r1=594640&r2=594641&view=diff
==============================================================================
--- 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/report/XmlReportOutputterTest.java
 (original)
+++ 
incubator/ivy/core/trunk/test/java/org/apache/ivy/plugins/report/XmlReportOutputterTest.java
 Tue Nov 13 13:04:30 2007
@@ -75,6 +75,25 @@
             xml.indexOf(expectedIsLocal) != -1);
     }
 
+    public void testEscapeXml() throws Exception {
+        _ivy.configure(new File("test/repositories/IVY-635/ivysettings.xml"));
+        ResolveReport report = _ivy.resolve(new File(
+                "test/java/org/apache/ivy/plugins/report/ivy-635.xml").toURL(),
+            getResolveOptions(new String[] {"default"}));
+        assertNotNull(report);
+        
+        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        XmlReportOutputter outputter = new XmlReportOutputter();
+        outputter.output(report.getConfigurationReport("default"), buffer);
+        buffer.flush();
+        String xml = buffer.toString();
+        
+        String expectedArtName = "art1&amp;_.txt";
+
+        assertTrue("XML doesn't contain escaped artifact name",
+            xml.indexOf(expectedArtName) != -1);
+    }
+
     public void testWriteModuleInfo() throws Exception {
         ResolveReport report = _ivy.resolve(new File(
                 
"test/java/org/apache/ivy/plugins/report/ivy-with-info.xml").toURL(),

Added: incubator/ivy/core/trunk/test/repositories/IVY-635/ivysettings.xml
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/repositories/IVY-635/ivysettings.xml?rev=594641&view=auto
==============================================================================
--- incubator/ivy/core/trunk/test/repositories/IVY-635/ivysettings.xml (added)
+++ incubator/ivy/core/trunk/test/repositories/IVY-635/ivysettings.xml Tue Nov 
13 13:04:30 2007
@@ -0,0 +1,27 @@
+<!--
+   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.    
+-->
+<ivysettings>
+    <settings defaultResolver="myresolver"/>
+    <resolvers>
+                       <filesystem name="myresolver">
+                               <ivy 
pattern="${ivy.settings.dir}/[module]/ivy.xml" />
+                               <artifact 
pattern="${ivy.settings.dir}/[module]/[artifact].[ext]" />
+                       </filesystem>
+    </resolvers>
+</ivysettings>

Added: incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/art1&_.txt
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/art1%26_.txt?rev=594641&view=auto
==============================================================================
    (empty)

Added: incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/ivy.xml
URL: 
http://svn.apache.org/viewvc/incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/ivy.xml?rev=594641&view=auto
==============================================================================
--- incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/ivy.xml (added)
+++ incubator/ivy/core/trunk/test/repositories/IVY-635/mod1/ivy.xml Tue Nov 13 
13:04:30 2007
@@ -0,0 +1,25 @@
+<!--
+   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.    
+-->
+<ivy-module version="1.0">
+    <info organisation="apache" module="mod1"/>
+    <publications>
+       <artifact name="art1&amp;_" ext="txt" />
+    </publications>
+    <dependencies />
+</ivy-module>


Reply via email to