View Javadoc

1   /*
2    * Copyright 2007 The Apache Software Foundation.
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 org.apache.myfaces.shared.renderkit.html.util;
18  
19  import java.io.CharArrayWriter;
20  import java.io.IOException;
21  import java.io.StringWriter;
22  
23  import org.apache.myfaces.test.base.AbstractJsfTestCase;
24  
25  /**
26   * <code>HTMLEncoderTest</code> tests <code>org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder</code>.
27   */
28  public class HTMLEncoderWriterTest extends AbstractJsfTestCase {
29    private String stringNoSpecialChars = "Hello, this is MyFaces speaking!";
30    private String stringNoSpecialCharsEncoded = "Hello, this is MyFaces speaking!";
31    private String stringNoSpecialCharsEncodedPartial = "lo, this is MyFaces speakin";
32    private String stringSpecialChars1 = "<\"Hello\", this is MyFaces speaking!>";
33    private String stringSpecialChars1Encoded = "&lt;&quot;Hello&quot;, this is MyFaces speaking!&gt;";
34    private String stringSpecialChars2 = "Hello & this is MyFaces speaking!>";
35    private String stringSpecialChars2Encoded = "Hello &amp; this is MyFaces speaking!&gt;";
36    private String stringLineBreak = "Hell\u00F6\nthis is MyFaces speaking!>";
37    private String stringLineBreakEncoded1 = "Hell&ouml;<br/>this is MyFaces speaking!&gt;";
38    private String stringLineBreakEncoded2 = "Hell&ouml;\nthis is MyFaces speaking!&gt;";
39    private String stringLineBreakEncoded2Partial = "&ouml;\nthis is MyFaces speaking!";
40    private String stringBlanks = "<Hello   this is MyFaces speaking!>";
41    private String stringBlanksEncoded = "&lt;Hello   this is MyFaces speaking!&gt";
42  
43    private StringWriter sw;
44    
45    public HTMLEncoderWriterTest(String name) {
46      super(name);
47    }
48  
49      @Override
50      protected void setUp() throws Exception {
51          super.setUp();
52          sw = new StringWriter(40);
53      }
54  
55      @Override
56      protected void tearDown() throws Exception {
57          super.tearDown();
58          sw = null;
59      }
60  
61    /**
62     * Test method for
63     * {@link org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder#encode(String)}.
64     */
65    public void testEncodeStringNoSpecialChars() throws Exception {
66      HTMLEncoder.encode(sw, stringNoSpecialChars);
67      assertEquals(stringNoSpecialCharsEncoded, sw.toString());
68    }
69  
70    public void testEncodeStringSpecialChars1() throws Exception {
71      HTMLEncoder.encode(sw, stringSpecialChars1);
72      assertEquals(stringSpecialChars1Encoded, sw.toString());
73    }
74  
75    public void testEncodeStringSpecialChars2() throws Exception {
76      HTMLEncoder.encode(sw, stringSpecialChars2);
77      assertEquals(stringSpecialChars2Encoded, sw.toString());
78    }
79  
80    public void testEncodeStringLineBreak1() throws Exception {
81      HTMLEncoder.encode(sw, stringLineBreak, true);
82      assertEquals(stringLineBreakEncoded1, sw.toString());
83    }
84  
85    public void testEncodeStringLineBreak2() throws Exception {
86      HTMLEncoder.encode(sw, stringLineBreak, false);
87      assertEquals(stringLineBreakEncoded2, sw.toString());
88    }
89  
90    public void testEncodeStringEmpty() throws Exception {
91      HTMLEncoder.encode(sw, "");
92      assertEquals("", sw.toString());
93    }
94  
95    public void testEncodeStringNull() throws Exception {
96      HTMLEncoder.encode(sw, null);
97      assertEquals("", sw.toString());
98    }
99  
100   public void testEncodeArrayNoSpecialChars() throws Exception {
101     try {
102       CharArrayWriter writer = new CharArrayWriter();
103       char[] source = stringNoSpecialChars.toCharArray();
104       HTMLEncoder.encode(source, 0, source.length, writer);
105       assertEquals(stringNoSpecialCharsEncoded.toCharArray(), writer.toCharArray());
106     } catch (IOException e) {
107       fail(e.getMessage());
108     }
109   }
110 
111   public void testEncodeArrayNoSpecialCharsPartial() throws Exception {
112     try {
113       CharArrayWriter writer = new CharArrayWriter();
114       char[] source = stringNoSpecialChars.toCharArray();
115       HTMLEncoder.encode(source, 3, source.length - 5, writer);
116       assertEquals(stringNoSpecialCharsEncodedPartial.toCharArray(), writer.toCharArray());
117     } catch (IOException e) {
118       fail(e.getMessage());
119     }
120   }
121 
122   public void testEncodeArraySpecialChars1() throws Exception {
123     try {
124       CharArrayWriter writer = new CharArrayWriter();
125       char[] source = stringSpecialChars1.toCharArray();
126       HTMLEncoder.encode(source, 0, source.length, writer);
127       assertEquals(stringSpecialChars1Encoded.toCharArray(), writer.toCharArray());
128     } catch (IOException e) {
129       fail(e.getMessage());
130     }
131   }
132 
133   public void testEncodeArraySpecialChars2() throws Exception {
134     try {
135       CharArrayWriter writer = new CharArrayWriter();
136       char[] source = stringSpecialChars2.toCharArray();
137       HTMLEncoder.encode(source, 0, source.length, writer);
138       assertEquals(stringSpecialChars2Encoded.toCharArray(), writer.toCharArray());
139     } catch (IOException e) {
140       fail(e.getMessage());
141     }
142   }
143 
144   public void testEncodeArrayEmpty() throws Exception {
145     try {
146       CharArrayWriter writer = new CharArrayWriter();
147       HTMLEncoder.encode(new char[]{}, 0, 1, writer);
148       assertEquals(new char[]{}, writer.toCharArray());
149     } catch (IOException e) {
150       fail(e.getMessage());
151     }
152   }
153 
154   public void testEncodeArrayNull() throws Exception {
155     try {
156       CharArrayWriter writer = new CharArrayWriter();
157       HTMLEncoder.encode(null, 0, 0, writer);
158       assertEquals(new char[]{}, writer.toCharArray());
159     } catch (IOException e) {
160       fail(e.getMessage());
161     }
162   }
163 
164   public void testEncodeArrayWrongIndex1() throws Exception {
165     try {
166       CharArrayWriter writer = new CharArrayWriter();
167       char[] source = stringSpecialChars2.toCharArray();
168       HTMLEncoder.encode(source, 0, source.length - 100, writer);
169       assertEquals(new char[]{}, writer.toCharArray());
170     } catch (IOException e) {
171       fail(e.getMessage());
172     }
173   }
174 
175   public void testEncodeArrayWrongIndex2() throws Exception {
176     try {
177       CharArrayWriter writer = new CharArrayWriter();
178       char[] source = stringSpecialChars2.toCharArray();
179       HTMLEncoder.encode(source, -100, source.length, writer);
180       assertEquals(stringSpecialChars2Encoded.toCharArray(), writer.toCharArray());
181     } catch (IOException e) {
182       fail(e.getMessage());
183     }
184   }
185 
186   public void testEncodeArrayWrongIndex3() throws Exception {
187     try {
188       CharArrayWriter writer = new CharArrayWriter();
189       char[] source = stringSpecialChars2.toCharArray();
190       HTMLEncoder.encode(source, 100000, source.length, writer);
191       assertEquals(new char[]{}, writer.toCharArray());
192     } catch (IOException e) {
193       fail(e.getMessage());
194     }
195   }
196 
197   public void testEncodeArrayLineBreak1() throws Exception {
198     try {
199       CharArrayWriter writer = new CharArrayWriter();
200       char[] source = stringLineBreak.toCharArray();
201       HTMLEncoder.encode(source, 0, source.length, true, writer);
202       assertEquals(stringLineBreakEncoded1.toCharArray(), writer.toCharArray());
203     } catch (IOException e) {
204       fail(e.getMessage());
205     }
206   }
207 
208   public void testEncodeArrayLineBreak2() throws Exception  {
209     try {
210       CharArrayWriter writer = new CharArrayWriter();
211       char[] source = stringLineBreak.toCharArray();
212       HTMLEncoder.encode(source, 0, source.length, false, writer);
213       assertEquals(stringLineBreakEncoded2.toCharArray(), writer.toCharArray());
214     } catch (IOException e) {
215       fail(e.getMessage());
216     }
217   }
218 
219   public void testEncodeArrayLineBreak2WrongIndex() throws Exception  {
220     try {
221       CharArrayWriter writer = new CharArrayWriter();
222       char[] source = stringLineBreak.toCharArray();
223       HTMLEncoder.encode(source, 0, source.length + 5, false, writer);
224       assertEquals(stringLineBreakEncoded2.toCharArray(), writer.toCharArray());
225     } catch (IOException e) {
226       fail(e.getMessage());
227     }
228   }
229 
230   public void testEncodeArrayLineBreakPartial() throws Exception  {
231     try {
232       CharArrayWriter writer = new CharArrayWriter();
233       char[] source = stringLineBreak.toCharArray();
234       HTMLEncoder.encode(source, 4, source.length - 5, writer);
235       char[] expected = stringLineBreakEncoded2Partial.toCharArray();
236       assertEquals(expected, writer.toCharArray());
237     } catch (IOException e) {
238       fail(e.getMessage());
239     }
240   }
241 
242   private void assertEquals(char[] expected, char[] actual) {
243     if ((expected == null ^ actual == null) || expected.length != actual.length) {
244       fail();
245     }
246     for (int i = 0; i < expected.length; i++) {
247       assertEquals(expected[i], actual[i]);
248     }
249   }
250   
251 ;  public void testSimpleWriteURIAttribute() throws Exception
252   {
253       String cad1 = "http://myfaces.apache.org/hello.jsf?key1=val&key2=val2#id";
254       String cad2 = "http://myfaces.apache.org/hello.jsf?key1=val&amp;key2=val2#id";
255       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
256       String cad3 = sw.toString();
257       assertEquals(cad2, cad3);      
258   }
259   
260   public void testUsAsciiEscapedCharactersBeforeQuery() throws Exception
261   {
262       // Escape
263       // - From %00 to %20, 
264       // - <"> %22, "%" %25
265       // - "<" %3C, ">" %3E,
266       // - "\" %5C, "^" %5E, "`" %60 
267       // - "{" %7B, "|" %7C, "}" %7D
268       // - From %7F ad infinitum
269       String cad1 = "?key=\"%<>\\`{|}^\n "; //Omit %
270       String cad2 = "?key=%22%25%3C%3E%5C%60%7B%7C%7D%5E%0A%20";
271       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
272       String cad3 = sw.toString();
273       assertEquals(cad2, cad3);
274       
275       String cad4 = "\"%<>\\`{|}^\n ";
276       String cad5 = "%22%25%3C%3E%5C%60%7B%7C%7D%5E%0A%20";
277       sw = new StringWriter();
278       HTMLEncoder.encodeURIAttribute(sw, cad4,"UTF-8");
279       String cad6 = sw.toString();
280       assertEquals(cad5, cad6);
281       
282       
283   }
284   
285   public void testWriteNonUsAsciiOnURIAttribute() throws Exception
286   {
287       // Character ü in ISO-8859-1 is %FC but on UTF-8 is %C3%BC. In this case,
288       // it should encode as %C3%BC
289 	  byte [] array = new byte[]{(byte)0xFC};
290       String cad1 = new String(array,"ISO-8859-1");//+(char)0xC3BC;//"http://myfaces.apache.org/heüll o.jsf?key=val#id";
291       String cad2 = "%C3%BC";//"http://myfaces.apache.org/he%FCll%20o.jsf?key=val#id";
292       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
293       String cad3 = sw.toString();
294       assertEquals(cad2, cad3);
295 
296   }
297   
298   public void testReservedCharactersOnURIAttribute() throws Exception
299   {
300       //Reserved
301       // Reserved characters (should not be percent-encoded)
302       // reserved    = gen-delims / sub-delims
303       // gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
304       //               %3A   %2F   %3F   %23   %5B   %5D   %40
305       // sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
306       //               %21   %24   %26   %27   %28   %29   %2A   %2B   %2C   %3B   %3D
307       
308       String cad1 = "?key=:/[]@!$'()*+,;="; //Omit &
309       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
310       String cad2 = sw.toString();
311       assertEquals(cad1, cad2);
312       
313       String cad7 = ":/[]@!$&'()*+,;=";
314       sw = new StringWriter(40);
315       HTMLEncoder.encodeURIAttribute(sw, cad7,"UTF-8");
316       String cad8 = sw.toString();
317       assertEquals(cad7, cad8);
318   }
319 
320   public void testNonEncodedCharactersOnURIAttribute() throws Exception
321   {
322       // "... for consistency, percent-encoded octets in the ranges of ALPHA
323       // (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E),
324       // underscore (%5F), or tilde (%7E) should not be created by URI
325       // producers...."
326       String cad1 = "?key=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
327       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
328       String cad2 = sw.toString();
329       assertEquals(cad1, cad2);
330       
331       String cad3 = "#somefile?key=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
332       sw = new StringWriter(40);
333       HTMLEncoder.encodeURIAttribute(sw, cad3,"UTF-8");
334       String cad4 = sw.toString();
335       assertEquals(cad3, cad4);
336       
337       String cad5 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
338       sw = new StringWriter(40);
339       HTMLEncoder.encodeURIAttribute(sw, cad5,"UTF-8");
340       String cad6 = sw.toString();
341       assertEquals(cad5, cad6);
342   }
343 
344   public void testWriteURIAttribute() throws Exception
345   {
346       //Note char 256 or 0x100 should not be passed or percent encoded, because it is not
347       //valid for URIs.
348 	  byte [] array11 = new byte[]{(byte) 0xC2,(byte) 0xA1,(byte) 0xC2,(byte) 0xA2,
349 			  (byte) 0xC2,(byte) 0xA3,(byte) 0xC2,(byte) 0xA4,(byte) 0xC2,(byte) 0xA5,
350 			  (byte) 0xC2,(byte) 0xA6,(byte) 0xC2,(byte) 0xA7,(byte) 0xC2,(byte) 0xA8,
351 			  (byte) 0xC2,(byte) 0xA9,(byte) 0xC2,(byte) 0xAA,(byte) 0xC2,(byte) 0xAB,
352 			  (byte) 0xC2,(byte) 0xAC,(byte) 0xC2,(byte) 0xAD,(byte) 0xC2,(byte) 0xAE,
353 			  (byte) 0xC2,(byte) 0xAF,(byte) 0xC2,(byte) 0xB0,(byte) 0xC2,(byte) 0xB1};
354 	  
355       String cad11 = new String(array11,"UTF-8") + ((char)(0xFF))+((char)(0x100));
356       String cad12 = "%C2%A1%C2%A2%C2%A3%C2%A4%C2%A5%C2%A6%C2%A7%C2%A8%C2%A9%C2%AA%C2%AB%C2%AC%C2%AD"+
357                      "%C2%AE%C2%AF%C2%B0%C2%B1%C3%BF%C4%80";
358       HTMLEncoder.encodeURIAttribute(sw, cad11,"UTF-8");
359       String cad13 = sw.toString();
360       assertEquals(cad12, cad13);
361       
362       String cad1= "?key=" + new String(array11,"UTF-8")+((char)(0xFF))+((char)(0x100));
363       String cad2 = "?key=%C2%A1%C2%A2%C2%A3%C2%A4%C2%A5%C2%A6%C2%A7%C2%A8%C2%A9%C2%AA%C2%AB%C2%AC%C2%AD"+
364                      "%C2%AE%C2%AF%C2%B0%C2%B1%C3%BF%C4%80";
365       sw = new StringWriter(40);
366       HTMLEncoder.encodeURIAttribute(sw, cad1,"UTF-8");
367       String cad3 = sw.toString();
368       assertEquals(cad2, cad3);
369             
370       //String cad14 = "http://myfaces.apache.org/page.jsf?key="+((char)0xFF)+((char)0x100);
371       //String cad15 = HTMLEncoder.encodeURIAttribute(cad14,false);
372       //assertEquals(cad14,cad15);
373   }
374     
375 }