diff --git a/src/main/java/org/codehaus/plexus/util/xml/PrettyPrintXMLWriter.java b/src/main/java/org/codehaus/plexus/util/xml/PrettyPrintXMLWriter.java
index 332bdaf..f602668 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/PrettyPrintXMLWriter.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/PrettyPrintXMLWriter.java
@@ -23,9 +23,9 @@
import java.util.regex.Pattern;
/**
- * Implementation of XMLWriter which emits nicely formatted documents.
- *
+ *
Implementation of XMLWriter which emits nicely formatted documents.
*
+ * C0n control characters except \n
, \r
, and \t
are omitted from output
*/
public class PrettyPrintXMLWriter implements XMLWriter {
/** Line separator ("\n" on UNIX) */
@@ -185,7 +185,7 @@ private void writeText(String text, boolean escapeXml) {
finishTag();
if (escapeXml) {
- text = escapeXml(text);
+ text = escapeXmlText(text);
}
write(StringUtils.unifyLineSeparators(text, lineSeparator));
@@ -225,10 +225,12 @@ private static String escapeXml(String text) {
private static final Pattern crlf = Pattern.compile(crlf_str);
- private static final Pattern lowers = Pattern.compile("([\000-\037])");
+ private static final Pattern lowers = Pattern.compile("([\\x00-\\x1F])");
+
+ private static final Pattern illegalC0Characters = Pattern.compile("([\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F])");
private static String escapeXmlAttribute(String text) {
- text = escapeXml(text);
+ text = escapeXmlText(text);
// Windows
Matcher crlfmatcher = crlf.matcher(text);
@@ -246,6 +248,19 @@ private static String escapeXmlAttribute(String text) {
return b.toString();
}
+ private static String escapeXmlText(String text) {
+ text = escapeXml(text);
+
+ Matcher matcher = illegalC0Characters.matcher(text);
+ StringBuffer b = new StringBuffer();
+ while (matcher.find()) {
+ matcher = matcher.appendReplacement(b, "");
+ }
+ matcher.appendTail(b);
+
+ return b.toString();
+ }
+
/** {@inheritDoc} */
@Override
public void addAttribute(String key, String value) {
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
index e69d28f..ffd0ede 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
@@ -24,6 +24,7 @@
* PROPERTY_SERIALIZER_INDENTATION
* PROPERTY_SERIALIZER_LINE_SEPARATOR
*
+ * C0n control characters except \n
, \r
, and \t
are omitted from output
*/
public class MXSerializer implements XmlSerializer {
protected static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
@@ -943,19 +944,9 @@ protected void writeElementContent(String text, Writer out) throws IOException {
// out.write(';');
// pos = i + 1;
} else {
- throw new IllegalStateException(
- "character " + Integer.toString(ch) + " is not allowed in output" + getLocation());
- // in XML 1.1 legal are [#x1-#xD7FF]
- // if(ch > 0) {
- // if(i > pos) out.write(text.substring(pos, i));
- // out.write("");
- // out.write(Integer.toString(ch));
- // out.write(';');
- // pos = i + 1;
- // } else {
- // throw new IllegalStateException(
- // "character zero is not allowed in XML 1.1 output"+getLocation());
- // }
+ // skip special char
+ if (i > pos) out.write(text.substring(pos, i));
+ pos = i + 1;
}
}
if (seenBracket) {
diff --git a/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomWriterTest.java b/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomWriterTest.java
index 7f7f321..233bdd5 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomWriterTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/Xpp3DomWriterTest.java
@@ -82,6 +82,12 @@ private String createExpectedXML(boolean escape) {
buf.append(LS);
buf.append(" ");
buf.append(LS);
+ if (escape) {
+ buf.append(" special-char-");
+ } else {
+ buf.append(" special-char-" + (char) 7 + "");
+ }
+ buf.append(LS);
buf.append("");
return buf.toString();
@@ -95,7 +101,7 @@ private Xpp3Dom createXpp3Dom() {
dom.addChild(el1);
Xpp3Dom el2 = new Xpp3Dom("el2");
- el2.setAttribute("att2", "attribute2\nnextline");
+ el2.setAttribute("att2", "attribute2\nnextline" + (char) 7);
dom.addChild(el2);
Xpp3Dom el3 = new Xpp3Dom("el3");
@@ -119,6 +125,10 @@ private Xpp3Dom createXpp3Dom() {
el7.setValue("element7\n&\"\'<>");
el6.addChild(el7);
+ Xpp3Dom el8 = new Xpp3Dom("el8");
+ el8.setValue("special-char-" + (char) 7);
+
+ dom.addChild(el8);
return dom;
}
}
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXSerializerTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXSerializerTest.java
new file mode 100644
index 0000000..8b66c23
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXSerializerTest.java
@@ -0,0 +1,58 @@
+package org.codehaus.plexus.util.xml.pull;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Arrays;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class MXSerializerTest {
+
+ @Test
+ void testSerialize() throws Exception {
+
+ StringWriter writer = new StringWriter();
+
+ MXSerializer sr = new MXSerializer();
+ sr.setOutput(writer);
+
+ sr.startDocument(null, Boolean.TRUE);
+ sr.startTag(null, "root");
+ for (int i : Arrays.asList(8, 9, 10, 11, 13, 15)) {
+ sr.startTag(null, "char");
+ sr.text(Character.getName(i) + ": " + ((char) i));
+ sr.endTag(null, "char");
+ }
+
+ sr.endTag(null, "root");
+ sr.endDocument();
+ assertEquals(expectedOutput(), writer.toString());
+ }
+
+ @Test
+ void testDeserialize() throws Exception {
+ MXParser parser = new MXParser();
+ parser.setInput(new StringReader(expectedOutput()));
+ int eventType = parser.getEventType();
+
+ while (eventType != XmlPullParser.END_DOCUMENT) {
+ eventType = parser.next();
+ }
+ }
+
+ private String expectedOutput() {
+ StringBuilder out = new StringBuilder();
+ out.append("");
+ out.append("");
+ out.append("BACKSPACE: ");
+ out.append("CHARACTER TABULATION: \t");
+ out.append("LINE FEED (LF): \n");
+ out.append("LINE TABULATION: ");
+ out.append("CARRIAGE RETURN (CR): \r");
+ out.append("SHIFT IN: ");
+ out.append("");
+ return out.toString();
+ }
+}