diff --git a/pmd-core/pom.xml b/pmd-core/pom.xml
index 0089efa13a..18669acb64 100644
--- a/pmd-core/pom.xml
+++ b/pmd-core/pom.xml
@@ -134,6 +134,10 @@
org.apache.commons
commons-lang3
+
+ org.apache.commons
+ commons-text
+
org.ow2.asm
asm
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
index 33230152d9..5390e9410f 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/XMLRenderer.java
@@ -18,6 +18,7 @@ import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.text.StringEscapeUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
@@ -140,7 +141,7 @@ public final class XMLRenderer implements Renderer, CPDRenderer {
// the code snippet has normalized line endings
String platformSpecific = codeSnippet.replace("\n", System.lineSeparator());
Element codefragment = doc.createElement("codefragment");
- codefragment.appendChild(doc.createCDATASection(platformSpecific));
+ codefragment.appendChild(doc.createCDATASection(StringEscapeUtils.escapeXml10(platformSpecific)));
duplication.appendChild(codefragment);
}
return duplication;
diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
index 22eca255a7..a7ddbb5474 100644
--- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
+++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/XMLRendererTest.java
@@ -5,6 +5,7 @@
package net.sourceforge.pmd.cpd;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -196,6 +197,23 @@ public class XMLRendererTest {
assertTrue(report.contains(espaceChar));
}
+ @Test
+ public void testRendererXMLEscaping() throws IOException {
+ String formfeed = "\u000C";
+ String codefragment = "code fragment" + formfeed + "\nline2\nline3";
+ CPDRenderer renderer = new XMLRenderer();
+ List list = new ArrayList<>();
+ Mark mark1 = createMark("public", "file1", 1, 2, codefragment);
+ Mark mark2 = createMark("public", "file2", 5, 2, codefragment);
+ Match match1 = new Match(75, mark1, mark2);
+ list.add(match1);
+
+ StringWriter sw = new StringWriter();
+ renderer.render(list.iterator(), sw);
+ String report = sw.toString();
+ assertFalse(report.contains(formfeed));
+ }
+
private Mark createMark(String image, String tokenSrcID, int beginLine, int lineCount, String code) {
Mark result = new Mark(new TokenEntry(image, tokenSrcID, beginLine));
@@ -214,8 +232,4 @@ public class XMLRendererTest {
result.setSourceCode(new SourceCode(new SourceCode.StringCodeLoader(code)));
return result;
}
-
- public static junit.framework.Test suite() {
- return new junit.framework.JUnit4TestAdapter(XMLRendererTest.class);
- }
}
diff --git a/pmd-doc/pom.xml b/pmd-doc/pom.xml
index 22f43c9c0b..e57272388c 100644
--- a/pmd-doc/pom.xml
+++ b/pmd-doc/pom.xml
@@ -95,7 +95,6 @@
org.apache.commons
commons-text
- 1.6
org.yaml
diff --git a/pom.xml b/pom.xml
index 277c3f1a07..69ee3c3c4d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -669,6 +669,11 @@
commons-lang3
3.8.1
+
+ org.apache.commons
+ commons-text
+ 1.6
+
org.slf4j
slf4j-api