diff options
author | Elliott Hughes <enh@google.com> | 2009-11-17 18:05:40 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2009-11-18 14:01:02 -0800 |
commit | ff42219e3ea3d712f931ae7f26af236339b5cf23 (patch) | |
tree | e7804dad30bb57b124eb5ce42aae8b7d0cd5d150 /xml/src/main/java/org/kxml2 | |
parent | 6afd1e297342111db635163614383d62937ce5eb (diff) | |
download | libcore-ff42219e3ea3d712f931ae7f26af236339b5cf23.zip libcore-ff42219e3ea3d712f931ae7f26af236339b5cf23.tar.gz libcore-ff42219e3ea3d712f931ae7f26af236339b5cf23.tar.bz2 |
Fix KXmlSerializer so it won't generate invalid XML.
We were allowing arbitrary characters to be output (which, surprisingly,
XML does not), and we weren't correctly escaping CDATA sections that
contained "]]>".
Pull out some of my test helpers from DocumentBuilderTest into Support_Xml,
because they're more generally useful when writing tests involving XML.
Also correct a bunch of spelling mistakes in XmlSerializer's javadoc, since
I happened to be reading through.
Diffstat (limited to 'xml/src/main/java/org/kxml2')
-rw-r--r-- | xml/src/main/java/org/kxml2/io/KXmlSerializer.java | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java index d63ed04..1f13357 100644 --- a/xml/src/main/java/org/kxml2/io/KXmlSerializer.java +++ b/xml/src/main/java/org/kxml2/io/KXmlSerializer.java @@ -124,18 +124,33 @@ public class KXmlSerializer implements XmlSerializer { break; } default : - //if(c < ' ') - // throw new IllegalArgumentException("Illegal control code:"+((int) c)); - - if (c >= ' ' && c !='@' && (c < 127 || unicode)) + // BEGIN android-changed: refuse to output invalid characters + // See http://www.w3.org/TR/REC-xml/#charsets for definition. + // No other Java XML writer we know of does this, but no Java + // XML reader we know of is able to parse the bad output we'd + // otherwise generate. + // Note: tab, newline, and carriage return have already been + // handled above. + boolean valid = (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd); + if (!valid) { + reportInvalidCharacter(c); + } + if (unicode || c < 127) { writer.write(c); - else + } else { writer.write("&#" + ((int) c) + ";"); - + } + // END android-changed } } } + // BEGIN android-added + private static void reportInvalidCharacter(char ch) { + throw new IllegalArgumentException("Illegal character (" + Integer.toHexString((int) ch) + ")"); + } + // END android-added + /* private final void writeIndent() throws IOException { writer.write("\r\n"); @@ -540,9 +555,23 @@ public class KXmlSerializer implements XmlSerializer { public void cdsect(String data) throws IOException { check(false); + // BEGIN android-changed: ]]> is not allowed within a CDATA, + // so break and start a new one when necessary. + data = data.replace("]]>", "]]]]><![CDATA[>"); + char[] chars = data.toCharArray(); + // We also aren't allowed any invalid characters. + for (char ch : chars) { + boolean valid = (ch >= 0x20 && ch <= 0xd7ff) || + (ch == '\t' || ch == '\n' || ch == '\r') || + (ch >= 0xe000 && ch <= 0xfffd); + if (!valid) { + reportInvalidCharacter(ch); + } + } writer.write("<![CDATA["); - writer.write(data); + writer.write(chars, 0, chars.length); writer.write("]]>"); + // END android-changed } public void comment(String comment) throws IOException { |