1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.views.util;
19
20
21 /***
22 * This class handles HTML escaping of text.
23 * It was written and optimized to be as fast as possible.
24 *
25 */
26 public class TextUtil {
27
28 protected static final int MAX_LENGTH = 300;
29
30 /***
31 * We use arrays of char in the lookup table because it is faster
32 * appending this to a StringBuffer than appending a String
33 */
34 protected static final char[][] _stringChars = new char[MAX_LENGTH][];
35
36 static {
37
38 initMapping();
39 }
40
41
42 /***
43 * Call escapeHTML(s, false)
44 */
45 public static final String escapeHTML(String s) {
46 return escapeHTML(s, false);
47 }
48
49 /***
50 * Escape HTML.
51 *
52 * @param s string to be escaped
53 * @param escapeEmpty if true, then empty string will be escaped.
54 */
55 public static final String escapeHTML(String s, boolean escapeEmpty) {
56 int len = s.length();
57
58 if (len == 0) {
59 return s;
60 }
61
62 if (!escapeEmpty) {
63 String trimmed = s.trim();
64
65 if ((trimmed.length() == 0) || ("\"\"").equals(trimmed)) {
66 return s;
67 }
68 }
69
70 int i = 0;
71
72
73
74 do {
75 int index = s.charAt(i);
76
77 if (index >= MAX_LENGTH) {
78 if (index != 0x20AC) {
79
80 continue;
81 }
82
83 break;
84 } else if (_stringChars[index] != null) {
85 break;
86 }
87 } while (++i < len);
88
89
90
91 if (i == len) {
92 return s;
93 }
94
95
96
97
98
99 StringBuffer sb = new StringBuffer(len + 40);
100 char[] chars = new char[len];
101
102
103 s.getChars(0, len, chars, 0);
104
105
106 sb.append(chars, 0, i);
107
108 int last = i;
109 char[] subst;
110
111 for (; i < len; i++) {
112 char c = chars[i];
113 int index = c;
114
115 if (index < MAX_LENGTH) {
116 subst = _stringChars[index];
117
118
119 if (subst != null) {
120 if (i > last) {
121 sb.append(chars, last, i - last);
122 }
123
124 sb.append(subst);
125 last = i + 1;
126 }
127 }
128
129
130 else if (index == 0x20AC) {
131 if (i > last) {
132 sb.append(chars, last, i - last);
133 }
134
135 sb.append("€");
136 last = i + 1;
137 }
138 }
139
140 if (i > last) {
141 sb.append(chars, last, i - last);
142 }
143
144 return sb.toString();
145 }
146
147 protected static void addMapping(int c, String txt, String[] strings) {
148 strings[c] = txt;
149 }
150
151 protected static void initMapping() {
152 String[] strings = new String[MAX_LENGTH];
153
154 addMapping(0x22, """, strings);
155 addMapping(0x26, "&", strings);
156 addMapping(0x3c, "<", strings);
157 addMapping(0x3e, ">", strings);
158
159 addMapping(0xa1, "¡", strings);
160 addMapping(0xa2, "¢", strings);
161 addMapping(0xa3, "£", strings);
162 addMapping(0xa9, "©", strings);
163 addMapping(0xae, "®", strings);
164 addMapping(0xbf, "¿", strings);
165
166 addMapping(0xc0, "À", strings);
167 addMapping(0xc1, "Á", strings);
168 addMapping(0xc2, "Â", strings);
169 addMapping(0xc3, "Ã", strings);
170 addMapping(0xc4, "Ä", strings);
171 addMapping(0xc5, "Å", strings);
172 addMapping(0xc6, "Æ", strings);
173 addMapping(0xc7, "Ç", strings);
174 addMapping(0xc8, "È", strings);
175 addMapping(0xc9, "É", strings);
176 addMapping(0xca, "Ê", strings);
177 addMapping(0xcb, "Ë", strings);
178 addMapping(0xcc, "Ì", strings);
179 addMapping(0xcd, "Í", strings);
180 addMapping(0xce, "Î", strings);
181 addMapping(0xcf, "Ï", strings);
182
183 addMapping(0xd0, "Ð", strings);
184 addMapping(0xd1, "Ñ", strings);
185 addMapping(0xd2, "Ò", strings);
186 addMapping(0xd3, "Ó", strings);
187 addMapping(0xd4, "Ô", strings);
188 addMapping(0xd5, "Õ", strings);
189 addMapping(0xd6, "Ö", strings);
190 addMapping(0xd7, "×", strings);
191 addMapping(0xd8, "Ø", strings);
192 addMapping(0xd9, "Ù", strings);
193 addMapping(0xda, "Ú", strings);
194 addMapping(0xdb, "Û", strings);
195 addMapping(0xdc, "Ü", strings);
196 addMapping(0xdd, "Ý", strings);
197 addMapping(0xde, "Þ", strings);
198 addMapping(0xdf, "ß", strings);
199
200 addMapping(0xe0, "à", strings);
201 addMapping(0xe1, "á", strings);
202 addMapping(0xe2, "â", strings);
203 addMapping(0xe3, "ã", strings);
204 addMapping(0xe4, "ä", strings);
205 addMapping(0xe5, "å", strings);
206 addMapping(0xe6, "æ", strings);
207 addMapping(0xe7, "ç", strings);
208 addMapping(0xe8, "è", strings);
209 addMapping(0xe9, "é", strings);
210 addMapping(0xea, "ê", strings);
211 addMapping(0xeb, "ë", strings);
212 addMapping(0xec, "ì", strings);
213 addMapping(0xed, "í", strings);
214 addMapping(0xee, "î", strings);
215 addMapping(0xef, "ï", strings);
216
217 addMapping(0xf0, "ð", strings);
218 addMapping(0xf1, "ñ", strings);
219 addMapping(0xf2, "ò", strings);
220 addMapping(0xf3, "ó", strings);
221 addMapping(0xf4, "ô", strings);
222 addMapping(0xf5, "õ", strings);
223 addMapping(0xf6, "ö", strings);
224 addMapping(0xf7, "÷", strings);
225 addMapping(0xf8, "ø", strings);
226 addMapping(0xf9, "ù", strings);
227 addMapping(0xfa, "ú", strings);
228 addMapping(0xfb, "û", strings);
229 addMapping(0xfc, "ü", strings);
230 addMapping(0xfd, "ý", strings);
231 addMapping(0xfe, "þ", strings);
232 addMapping(0xff, "ÿ", strings);
233
234 for (int i = 0; i < strings.length; i++) {
235 String str = strings[i];
236
237 if (str != null) {
238 _stringChars[i] = str.toCharArray();
239 }
240 }
241 }
242 }