• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.xml;
18 
19 import static com.google.common.escape.testing.EscaperAsserts.assertEscaping;
20 import static com.google.common.escape.testing.EscaperAsserts.assertUnescaped;
21 
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.escape.CharEscaper;
24 
25 import junit.framework.TestCase;
26 
27 /**
28  * Tests for the {@link XmlEscapers} class.
29  *
30  * @author Alex Matevossian
31  * @author David Beaumont
32  */
33 @GwtCompatible
34 public class XmlEscapersTest extends TestCase {
35 
testXmlContentEscaper()36   public void testXmlContentEscaper() throws Exception {
37     CharEscaper xmlContentEscaper = (CharEscaper) XmlEscapers.xmlContentEscaper();
38     assertBasicXmlEscaper(xmlContentEscaper, false, false);
39     // Test quotes are not escaped.
40     assertEquals("\"test\"", xmlContentEscaper.escape("\"test\""));
41     assertEquals("'test'", xmlContentEscaper.escape("'test'"));
42   }
43 
testXmlAttributeEscaper()44   public void testXmlAttributeEscaper() throws Exception {
45     CharEscaper xmlAttributeEscaper = (CharEscaper) XmlEscapers.xmlAttributeEscaper();
46     assertBasicXmlEscaper(xmlAttributeEscaper, true, true);
47     // Test quotes are escaped.
48     assertEquals(""test"", xmlAttributeEscaper.escape("\"test\""));
49     assertEquals("'test'", xmlAttributeEscaper.escape("\'test'"));
50     // Test all escapes
51     assertEquals("a"b<c>d&e"f'",
52         xmlAttributeEscaper.escape("a\"b<c>d&e\"f'"));
53     // Test '\t', '\n' and '\r' are escaped.
54     assertEquals("a&#x9;b&#xA;c&#xD;d", xmlAttributeEscaper.escape("a\tb\nc\rd"));
55   }
56 
57   // Helper to assert common properties of xml escapers.
assertBasicXmlEscaper(CharEscaper xmlEscaper, boolean shouldEscapeQuotes, boolean shouldEscapeWhitespaceChars)58   private void assertBasicXmlEscaper(CharEscaper xmlEscaper,
59       boolean shouldEscapeQuotes, boolean shouldEscapeWhitespaceChars) {
60     // Simple examples (smoke tests)
61     assertEquals("xxx", xmlEscaper.escape("xxx"));
62     assertEquals("test &amp; test &amp; test",
63         xmlEscaper.escape("test & test & test"));
64     assertEquals("test &lt;&lt; 1", xmlEscaper.escape("test << 1"));
65     assertEquals("test &gt;&gt; 1", xmlEscaper.escape("test >> 1"));
66     assertEquals("&lt;tab&gt;", xmlEscaper.escape("<tab>"));
67 
68     // Test all non-escaped ASCII characters.
69     String s = "!@#$%^*()_+=-/?\\|]}[{,.;:" +
70         "abcdefghijklmnopqrstuvwxyz" +
71         "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
72         "1234567890";
73     assertEquals(s, xmlEscaper.escape(s));
74 
75     // Test ASCII control characters.
76     for (char ch = 0; ch < 0x20; ch++) {
77       if (ch == '\t' || ch == '\n' || ch == '\r') {
78         // Only these whitespace chars are permitted in XML,
79         if (shouldEscapeWhitespaceChars) {
80           assertEscaping(xmlEscaper, "&#x" + Integer.toHexString(ch).toUpperCase() + ";", ch);
81         } else {
82           assertUnescaped(xmlEscaper, ch);
83         }
84       } else {
85         // and everything else is replaced with FFFD.
86         assertEscaping(xmlEscaper, "\uFFFD", ch);
87       }
88     }
89 
90     // Test _all_ allowed characters (including surrogate values).
91     for (char ch = 0x20; ch <= 0xFFFD; ch++) {
92       // There are a small number of cases to consider, so just do it manually.
93       if (ch == '&') {
94         assertEscaping(xmlEscaper, "&amp;", ch);
95       } else if (ch == '<') {
96         assertEscaping(xmlEscaper, "&lt;", ch);
97       } else if (ch == '>') {
98         assertEscaping(xmlEscaper, "&gt;", ch);
99       } else if (shouldEscapeQuotes && ch == '\'') {
100         assertEscaping(xmlEscaper, "&apos;", ch);
101       } else if (shouldEscapeQuotes && ch == '"') {
102         assertEscaping(xmlEscaper, "&quot;", ch);
103       } else {
104         String input = String.valueOf(ch);
105         String escaped = xmlEscaper.escape(input);
106         assertEquals(
107             "char 0x" + Integer.toString(ch, 16) + " should not be escaped",
108             input, escaped);
109       }
110     }
111 
112     // Test that 0xFFFE and 0xFFFF are replaced with 0xFFFD
113     assertEscaping(xmlEscaper, "\uFFFD", '\uFFFE');
114     assertEscaping(xmlEscaper, "\uFFFD", '\uFFFF');
115 
116     assertEquals("0xFFFE is forbidden and should be replaced during escaping",
117         "[\uFFFD]", xmlEscaper.escape("[\ufffe]"));
118     assertEquals("0xFFFF is forbidden and should be replaced during escaping",
119         "[\uFFFD]", xmlEscaper.escape("[\uffff]"));
120   }
121 }
122