1   package com.atlassian.core.filters.legacy;
2   
3   import junit.framework.TestCase;
4   import com.atlassian.core.filters.StubEncodingFilter;
5   import com.atlassian.core.filters.ServletStubs;
6   import com.atlassian.core.util.StringUtils;
7   
8   import javax.servlet.FilterChain;
9   import javax.servlet.ServletRequest;
10  import javax.servlet.ServletResponse;
11  import java.util.Map;
12  import java.util.HashMap;
13  
14  public class TestWordCurlyQuotesRequestWrapper extends TestCase
15  {
16      private static final String TEST_STRING = getUnicodePunctuationCharacters() + getLatin1PunctuationCharacters();
17      private static final String ESCAPED_TEST_STRING_UTF_8 = StringUtils.escapeCP1252(TEST_STRING, "UTF-8");
18      private static final String ESCAPED_TEST_STRING_WINDOWS_1252 = StringUtils.escapeCP1252(TEST_STRING, "Windows-1252");
19      private static final String ESCAPED_TEST_STRING_LATIN_1 = StringUtils.escapeCP1252(TEST_STRING, "ISO-8859-1");
20  
21      private StubEncodingFilter encodingFilter;
22      private ServletStubs.Request request;
23      private ServletStubs.Response response;
24      private FilterChain filterChain;
25      private Map<String, Object> result;
26  
27      protected void setUp() throws Exception
28      {
29          super.setUp();
30  
31          request = ServletStubs.getRequestInstance();
32          request.setParameter("param", TEST_STRING);
33          request.addParameter("paramValues", TEST_STRING);
34          request.addParameter("paramValues", TEST_STRING);
35          request.setParameterMap(new HashMap<String, String[]>() {{
36              put("param", new String[]{ "not used -- filter calls getParameterValues" });
37              put("paramValues", new String[]{ "not used -- filter calls getParameterValues" });
38          }});
39  
40          response = ServletStubs.getResponseInstance();
41  
42          encodingFilter = new StubEncodingFilter();
43  
44          result = new HashMap<String, Object>();
45          filterChain = new FilterChain() {
46              public void doFilter(ServletRequest request, ServletResponse response)
47              {
48                  result.put("param", request.getParameter("param"));
49                  result.put("paramValues", request.getParameterValues("paramValues"));
50                  result.put("paramMap", request.getParameterMap());
51              }
52          };
53      }
54  
55      public void testUnicodePunctuationRemovedFromParametersInUtf8() throws Exception
56      {
57          encodingFilter.setEncoding("UTF-8");
58          encodingFilter.doFilter(request, response, filterChain);
59  
60          assertEquals(ESCAPED_TEST_STRING_UTF_8, result.get("param"));
61      }
62  
63      public void testPunctuationRemovedByGetParameterValues() throws Exception
64      {
65          encodingFilter.setEncoding("UTF-8");
66          encodingFilter.doFilter(request, response, filterChain);
67  
68          String[] values = (String[]) result.get("paramValues");
69          assertEquals(2, values.length);
70          assertEquals(ESCAPED_TEST_STRING_UTF_8, values[0]);
71          assertEquals(ESCAPED_TEST_STRING_UTF_8, values[1]);
72      }
73  
74      public void testPunctuationRemovedByGetParameterMap() throws Exception
75      {
76          encodingFilter.setEncoding("UTF-8");
77          encodingFilter.doFilter(request, response, filterChain);
78  
79          //noinspection unchecked
80          Map<String, String[]> map = (Map<String, String[]>) result.get("paramMap");
81          assertEquals(2, map.size());
82          assertEquals(1, map.get("param").length);
83          assertEquals(ESCAPED_TEST_STRING_UTF_8, map.get("param")[0]);
84          assertEquals(2, map.get("paramValues").length);
85          assertEquals(ESCAPED_TEST_STRING_UTF_8, map.get("paramValues")[0]);
86          assertEquals(ESCAPED_TEST_STRING_UTF_8, map.get("paramValues")[1]);
87      }
88  
89      public void testWindows1252PunctuationRemovedFromParametersInLatin1() throws Exception
90      {
91          encodingFilter.setEncoding("ISO-8859-1");
92          encodingFilter.doFilter(request, response, filterChain);
93  
94          assertEquals(ESCAPED_TEST_STRING_LATIN_1, result.get("param"));
95      }
96  
97      public void testUnicodePunctuationRemovedFromParametersInWindows1252() throws Exception
98      {
99          encodingFilter.setEncoding("Windows-1252");
100         encodingFilter.doFilter(request, response, filterChain);
101 
102         assertEquals(ESCAPED_TEST_STRING_WINDOWS_1252, result.get("param"));
103     }
104 
105     public void testParametersUnchangedInUtf16() throws Exception
106     {
107         encodingFilter.setEncoding("UTF-16");
108         encodingFilter.doFilter(request, response, filterChain);
109 
110         assertEquals(TEST_STRING, result.get("param"));
111     }
112 
113     /**
114      * Returns the "General Punctuation" range of characters in Unicode as a String.
115      */
116     private static String getUnicodePunctuationCharacters()
117     {
118         StringBuffer result = new StringBuffer(200);
119         for (char c = '\u2000'; c < '\u2070'; c++) // General Punctuation range
120             result.append(c);
121         return result.toString();
122     }
123 
124     /**
125      * Returns punctuation characters in Latin-1 and Windows-1252 as a String.
126      */
127     private static String getLatin1PunctuationCharacters()
128     {
129         StringBuffer result = new StringBuffer(200);
130         for (char c = '\u0020'; c <= '\u0040'; c++) // ASCII punctuation and digits
131             result.append(c);
132         for (char c = '\u005b'; c <= '\u0060'; c++) // more ASCII punctuation
133             result.append(c);
134         for (char c = '\u007b'; c <= '\u007e'; c++) // more ASCII punctuation
135             result.append(c);
136         for (char c = '\u0080'; c < '\u0100'; c++) // high-bit Latin-1, includes Windows-1252 punctuation
137             result.append(c);
138         return result.toString();
139     }
140 }