OLD | NEW |
| (Empty) |
1 // Copyright (C) 2008 Google Inc. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 package com.google.caja.plugin; | |
16 | |
17 import com.google.caja.lang.html.HtmlSchema; | |
18 import com.google.caja.parser.html.Nodes; | |
19 import com.google.caja.reporting.Message; | |
20 import com.google.caja.reporting.MessageLevel; | |
21 import com.google.caja.util.CajaTestCase; | |
22 import com.google.caja.util.MoreAsserts; | |
23 | |
24 import java.util.ArrayList; | |
25 import java.util.Arrays; | |
26 import java.util.List; | |
27 | |
28 import org.w3c.dom.Node; | |
29 | |
30 /** | |
31 * @author mikesamuel@gmail.com (Mike Samuel) | |
32 */ | |
33 public class HtmlSanitizerTest extends CajaTestCase { | |
34 public void testSingleElement() throws Exception { | |
35 assertValid(htmlFragment(fromString("<br/>")), "<br />"); | |
36 } | |
37 public void testText() throws Exception { | |
38 assertValid(htmlFragment(fromString("Hello World")), "Hello World"); | |
39 } | |
40 public void testFormattingElement() throws Exception { | |
41 assertValid(htmlFragment(fromString("<b>Hello</b>")), "<b>Hello</b>"); | |
42 } | |
43 public void testUnknownAttribute() throws Exception { | |
44 assertValid(htmlFragment(fromString("<b unknown=\"bogus\">Hello</b>")), | |
45 "<b>Hello</b>", | |
46 "WARNING: removing unknown attribute unknown on b"); | |
47 } | |
48 public void testKnownAttribute() throws Exception { | |
49 assertValid(htmlFragment(fromString("<b id=\"bold\">Hello</b>")), | |
50 "<b id=\"bold\">Hello</b>"); | |
51 } | |
52 public void testUnknownElement() throws Exception { | |
53 assertValid( | |
54 htmlFragment(fromString("<bogus id=\"bold\">Hello</bogus>")), | |
55 "Hello", | |
56 "WARNING: removing unknown tag bogus", | |
57 "WARNING: removing attribute id when folding bogus into parent"); | |
58 } | |
59 public void testUnknownEverything() throws Exception { | |
60 assertValid( | |
61 htmlFragment(fromString("<bogus unknown=\"bogus\">Hello</bogus>")), | |
62 "Hello", | |
63 "WARNING: removing unknown tag bogus", | |
64 "WARNING: removing unknown attribute unknown on bogus"); | |
65 } | |
66 public void testDisallowedElement() throws Exception { | |
67 assertValid(htmlFragment(fromString("<script>disallowed</script>")), | |
68 "disallowed", | |
69 "WARNING: removing disallowed tag script"); | |
70 } | |
71 public void testAttributeValidity() throws Exception { | |
72 assertValid(htmlFragment(fromString("<form><input type=text></form>")), | |
73 "<form><input type=\"text\" /></form>"); | |
74 } | |
75 public void testAttributePatternsTagSpecific() throws Exception { | |
76 assertValid(htmlFragment(fromString("<input type=text>")), | |
77 "<input type=\"text\" />"); | |
78 assertValid(htmlFragment(fromString("<button type=submit>")), | |
79 "<button type=\"submit\"></button>"); | |
80 assertValid(htmlFragment(fromString("<BUTTON TYPE=SUBMIT>")), | |
81 "<button type=\"SUBMIT\"></button>"); | |
82 assertValid(htmlFragment(fromString("<button type=text>")), | |
83 "<button></button>", | |
84 "WARNING: attribute type cannot have value text"); | |
85 assertValid(htmlFragment(fromString("<BUTTON TYPE=TEXT>")), | |
86 "<button></button>", | |
87 "WARNING: attribute type cannot have value TEXT"); | |
88 } | |
89 public void testIllegalAttributeValue() throws Exception { | |
90 assertValid(htmlFragment(fromString("<form><input type=x></form>")), | |
91 "<form><input /></form>", | |
92 "WARNING: attribute type cannot have value x"); | |
93 } | |
94 public void testDisallowedElement2() throws Exception { | |
95 assertValid(htmlFragment(fromString("<xmp>disallowed</xmp>")), | |
96 "disallowed", | |
97 "WARNING: removing unknown tag xmp"); | |
98 } | |
99 public void testDisallowedElement3() throws Exception { | |
100 assertValid( | |
101 htmlFragment(fromString("<meta http-equiv='refresh' content='1'/>")), | |
102 "", | |
103 "WARNING: removing disallowed tag meta", | |
104 "WARNING: removing attribute content when folding meta into parent", | |
105 "WARNING: removing attribute http-equiv when folding meta into parent"); | |
106 } | |
107 public void testDisallowedElement4() throws Exception { | |
108 assertValid(xmlFragment(fromString("<title>A title</title>")), "", | |
109 "WARNING: removing disallowed tag title"); | |
110 } | |
111 public void testElementFolding1() throws Exception { | |
112 assertValid( | |
113 xmlFragment(fromString("<body bgcolor=\"red\">Zoicks</body>")), | |
114 "Zoicks", | |
115 "WARNING: folding element body into parent", | |
116 "WARNING: removing attribute bgcolor when folding body into parent"); | |
117 } | |
118 public void testElementFolding2() throws Exception { | |
119 assertValid(xmlFragment(fromString("<body>Zoicks</body>")), | |
120 "Zoicks", "WARNING: folding element body into parent"); | |
121 } | |
122 public void testElementFolding3() throws Exception { | |
123 assertValid(xmlFragment(fromString( | |
124 "<html>" | |
125 + "<head>" | |
126 + "<title>Blah</title>" | |
127 + "<p>Foo</p>" | |
128 + "</head>" | |
129 + "<body>" | |
130 + "<p>One</p>" | |
131 + "<p styleo=\"color: red\">Two</p>" | |
132 + "Three" | |
133 + "<x>Four</x>" | |
134 + "</body>" | |
135 + "</html>")), | |
136 "<p>Foo</p><p>One</p><p>Two</p>ThreeFour", | |
137 "WARNING: folding element html into parent", | |
138 "WARNING: folding element head into parent", | |
139 "WARNING: removing disallowed tag title", | |
140 "WARNING: folding element body into parent", | |
141 "WARNING: removing unknown attribute styleo on p", | |
142 "WARNING: removing unknown tag x"); | |
143 } | |
144 public void testElementFolding4() throws Exception { | |
145 assertValid(xmlFragment(fromString( | |
146 "<html>" | |
147 + "<head>" | |
148 + "<title>Blah</title>" | |
149 + "<p>Foo</p>" | |
150 + "</head>" | |
151 + "<body>" | |
152 + "<p>One</p>" | |
153 + "<p>Two</p>" | |
154 + "Three" | |
155 + "<p>Four</p>" | |
156 + "</body>" | |
157 + "</html>")), | |
158 "<p>Foo</p><p>One</p><p>Two</p>Three<p>Four</p>", | |
159 "WARNING: folding element html into parent", | |
160 "WARNING: folding element head into parent", | |
161 "WARNING: removing disallowed tag title", | |
162 "WARNING: folding element body into parent"); | |
163 } | |
164 public void testIgnoredElement() throws Exception { | |
165 assertValid( | |
166 htmlFragment(fromString( | |
167 "<p>Foo" | |
168 + "<noscript>ignorable</noscript>" | |
169 + "<p>Bar")), | |
170 "<p>Foo</p><p>Bar</p>", | |
171 "WARNING: removing disallowed tag noscript"); | |
172 } | |
173 public void testDupeAttrs() throws Exception { | |
174 assertValid( | |
175 xmlFragment(fromString( | |
176 "<font color=\"red\" color=\"blue\">Purple</font>")), | |
177 // ^^^^^ | |
178 // 1 | |
179 // 123456789012 | |
180 "<font color=\"red\">Purple</font>", | |
181 "WARNING: attribute color duplicates one at testDupeAttrs:1+7 - 12"); | |
182 } | |
183 public void testDisallowedAttrs() throws Exception { | |
184 assertValid( | |
185 htmlFragment(fromString( | |
186 "<a href=\"foo.html\" charset=\"utf-7\">foo</a>")), | |
187 "<a href=\"foo.html\">foo</a>", | |
188 "WARNING: removing disallowed attribute charset on tag a"); | |
189 } | |
190 | |
191 private void assertValid(Node input, String golden, String... warnings) | |
192 throws Exception { | |
193 sanitize(input, golden, true, warnings); | |
194 } | |
195 | |
196 private void sanitize( | |
197 Node input, String golden, boolean valid, String... warnings) | |
198 throws Exception { | |
199 boolean validated = new HtmlSanitizer(HtmlSchema.getDefault(mq), mq) | |
200 .sanitize(input); | |
201 | |
202 List<String> actualWarnings = new ArrayList<String>(); | |
203 for (Message msg : mq.getMessages()) { | |
204 if (MessageLevel.WARNING.compareTo(msg.getMessageLevel()) <= 0) { | |
205 String msgText = msg.format(mc); | |
206 msgText = msgText.substring(msgText.indexOf(": ") + 1); | |
207 actualWarnings.add(msg.getMessageLevel().name() + ":" + msgText); | |
208 } | |
209 } | |
210 mq.getMessages().clear(); | |
211 MoreAsserts.assertListsEqual(Arrays.asList(warnings), actualWarnings); | |
212 | |
213 assertEquals(valid, validated); | |
214 | |
215 if (golden != null) { | |
216 assertEquals(golden, Nodes.render(input)); | |
217 } | |
218 } | |
219 } | |
OLD | NEW |