Spec: EncodeUtils.java

File EncodeUtils.java, 7.7 KB (added by chenchongqi, 12 years ago)
Line 
1/*
2 * Copyright 1997-2011
3 *
4 * http://www.pconline.com.cn
5 *
6 */
7package org.gelivable.web;
8
9import java.net.URLEncoder;
10
11/**
12 * EncodeUtils for encode the data use in browser prevent attack like XSS ...
13 *
14 * @author cuiyulong@pconline.com.cn
15 * @author chenxiaohu@pconline.com.cn
16 */
17public class EncodeUtils {
18
19    /**
20     * Encode data for use in HTML using HTML entity encoding
21     * Only encode 6 base chars.
22     *
23     * @param   input the text to encode for HTML
24     * @return  input encoded for HTML
25     */
26    public static String encodeForHTML(String input) {
27        if (input == null) {
28            return input;
29        }
30
31        StringBuilder sb = new StringBuilder(input.length());
32
33        for (int i = 0, c = input.length(); i < c; i++) {
34            char ch = input.charAt(i);
35            switch (ch) {
36                case '&':
37                    sb.append("&amp;");
38                    break;
39                case '<':
40                    sb.append("&lt;");
41                    break;
42                case '>':
43                    sb.append("&gt;");
44                    break;
45                case '"':
46                    sb.append("&quot;");
47                    break;
48                case '\'':
49                    sb.append("&#x27;");
50                    break;
51                case '/':
52                    sb.append("&#x2F;");
53                    break;
54                default:
55                    sb.append(ch);
56            }
57        }
58        return sb.toString();
59    }
60
61    /**
62     * Encode data for insertion inside a data value or function argument in JavaScript. Including user data
63     * directly inside a script is quite dangerous. Great care must be taken to prevent including user data
64     * directly into script code itself, as no amount of encoding will prevent attacks there.
65     *
66     * @param   input the text to encode for JavaScript
67     * @return  input encoded for use in JavaScript
68     */
69    public static String encodeForJavascript(String input) {
70        if (input == null) {
71            return input;
72        }
73
74        StringBuilder sb = new StringBuilder(input.length());
75
76        for (int i = 0, c = input.length(); i < c; i++) {
77            char ch = input.charAt(i);
78
79            // do not encode alphanumeric characters and ',' '.' '_'
80            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' ||
81                    ch >= '0' && ch <= '9' ||
82                    ch == ',' || ch == '.' || ch == '_') {
83                sb.append(ch);
84            } else {
85                String temp = Integer.toHexString(ch);
86
87                // encode up to 256 with \\xHH
88                if (ch < 256) {
89                    sb.append('\\').append('x');
90                    if (temp.length() == 1) {
91                        sb.append('0');
92                    }
93                    sb.append(temp.toLowerCase());
94
95                // otherwise encode with \\uHHHH
96                } else {
97                    sb.append('\\').append('u');
98                    for (int j = 0, d = 4 - temp.length(); j < d; j ++) {
99                        sb.append('0');
100                    }
101                    sb.append(temp.toUpperCase());
102                }
103            }
104        }
105
106        return sb.toString();
107    }
108
109    /**
110         * Encode data for use in Cascading Style Sheets (CSS) content.
111         *
112         * @see <a href="http://www.w3.org/TR/CSS21/syndata.html#escaped-characters">CSS Syntax [w3.org]</a>
113         *
114         * @param input
115         *              the text to encode for CSS
116         *
117         * @return input encoded for CSS
118         */
119    public static String encodeForCSS(String input) {
120        if (input == null) {
121            return input;
122        }
123
124        StringBuilder sb = new StringBuilder(input.length());
125
126        for (int i = 0, c = input.length(); i < c; i++) {
127            char ch = input.charAt(i);
128
129            // check for alphanumeric characters
130            if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' ||
131                    ch >= '0' && ch <= '9') {
132                sb.append(ch);
133            } else {
134                // return the hex and end in whitespace to terminate
135                sb.append('\\').append(Integer.toHexString(ch)).append(' ');
136            }
137        }
138        return sb.toString();
139    }
140
141    /**
142         * Encode parameter for use in a URL. This method performs
143     * <a href="http://en.wikipedia.org/wiki/Percent-encoding">URL encoding</a>
144         * on the entire string.
145         *
146         * @see <a href="http://en.wikipedia.org/wiki/Percent-encoding">URL encoding</a>
147         *
148         * @param input
149         *              the text to encode for use in a URL
150         *
151         * @return input
152         *              encoded for use in a URL
153         */
154    public static String encodeURIComponent(String input) {
155        return encodeURIComponent(input, "utf-8");
156    }
157
158    /**
159         * Encode parameter for use in a URL. This method performs
160     * <a href="http://en.wikipedia.org/wiki/Percent-encoding">URL encoding</a>
161         * on the entire string.
162         *
163         * @see <a href="http://en.wikipedia.org/wiki/Percent-encoding">URL encoding</a>
164         *
165         * @param input
166         *              the text to encode for use in a URL
167     * @param encoding
168     *      encoding to use
169         *
170         * @return input
171         *              encoded for use in a URL
172         */
173    public static String encodeURIComponent(String input, String encoding) {
174        if (input == null) {
175            return input;
176        }
177        String result;
178        try {
179            result = URLEncoder.encode(input, encoding);
180        } catch (Exception e) {
181            result = "";
182        }
183        return result;
184    }
185
186    /**
187     * Check is input a valid URL
188     * URL must starts with http://, https:// or ftp://
189     * URL must not contains char '\'' and '\"'
190     *
191     * @param input URL to check
192     * @return check result
193     */
194    public static boolean isValidURL(String input) {
195        if (input == null || input.length() < 8) {
196            return false;
197        }
198        char ch0 = input.charAt(0);
199        if (ch0 == 'h') {
200            if (input.charAt(1) == 't' &&
201                input.charAt(2) == 't' &&
202                input.charAt(3) == 'p') {
203                char ch4 = input.charAt(4);
204                if (ch4 == ':') {
205                    if (input.charAt(5) == '/' &&
206                        input.charAt(6) == '/') {
207           
208                        return isValidURLChar(input, 7);
209                    } else {
210                        return false;
211                    }
212                } else if (ch4 == 's') {
213                    if (input.charAt(5) == ':' &&
214                        input.charAt(6) == '/' &&
215                        input.charAt(7) == '/') {
216
217                        return isValidURLChar(input, 8);
218                    } else {
219                        return false;
220                    }
221                } else {
222                    return false;
223                }
224            } else {
225                return false;
226            }
227           
228        } else if (ch0 == 'f') {
229            if( input.charAt(1) == 't' &&
230                input.charAt(2) == 'p' &&
231                input.charAt(3) == ':' &&
232                input.charAt(4) == '/' &&
233                input.charAt(5) == '/') {
234               
235                return isValidURLChar(input, 6);
236            } else {
237                return false;
238            }
239        }
240        return false;
241    }
242
243    static boolean isValidURLChar(String url, int start) {
244        for (int i = start, c = url.length(); i < c; i ++) {
245            char ch = url.charAt(i);
246            if (ch == '"' || ch == '\'') {
247                return false;
248            }
249        }
250        return true;
251    }
252
253}