You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.1 KiB
155 lines
4.1 KiB
package com.ruoyi.common.utils.html; |
|
|
|
import com.ruoyi.common.utils.StringUtils; |
|
|
|
/** |
|
* 转义和反转义工具类 |
|
* |
|
* @author ruoyi |
|
*/ |
|
public class EscapeUtil |
|
{ |
|
public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; |
|
|
|
private static final char[][] TEXT = new char[64][]; |
|
|
|
static |
|
{ |
|
for (int i = 0; i < 64; i++) |
|
{ |
|
TEXT[i] = new char[] { (char) i }; |
|
} |
|
|
|
// special HTML characters |
|
TEXT['\''] = "'".toCharArray(); // 单引号 |
|
TEXT['"'] = """.toCharArray(); // 双引号 |
|
TEXT['&'] = "&".toCharArray(); // &符 |
|
TEXT['<'] = "<".toCharArray(); // 小于号 |
|
TEXT['>'] = ">".toCharArray(); // 大于号 |
|
} |
|
|
|
/** |
|
* 转义文本中的HTML字符为安全的字符 |
|
* |
|
* @param text 被转义的文本 |
|
* @return 转义后的文本 |
|
*/ |
|
public static String escape(String text) |
|
{ |
|
return encode(text); |
|
} |
|
|
|
/** |
|
* 还原被转义的HTML特殊字符 |
|
* |
|
* @param content 包含转义符的HTML内容 |
|
* @return 转换后的字符串 |
|
*/ |
|
public static String unescape(String content) |
|
{ |
|
return decode(content); |
|
} |
|
|
|
/** |
|
* 清除所有HTML标签,但是不删除标签内的内容 |
|
* |
|
* @param content 文本 |
|
* @return 清除标签后的文本 |
|
*/ |
|
public static String clean(String content) |
|
{ |
|
return new HTMLFilter().filter(content); |
|
} |
|
|
|
/** |
|
* Escape编码 |
|
* |
|
* @param text 被编码的文本 |
|
* @return 编码后的字符 |
|
*/ |
|
private static String encode(String text) |
|
{ |
|
int len; |
|
if ((text == null) || ((len = text.length()) == 0)) |
|
{ |
|
return StringUtils.EMPTY; |
|
} |
|
StringBuilder buffer = new StringBuilder(len + (len >> 2)); |
|
char c; |
|
for (int i = 0; i < len; i++) |
|
{ |
|
c = text.charAt(i); |
|
if (c < 64) |
|
{ |
|
buffer.append(TEXT[c]); |
|
} |
|
else |
|
{ |
|
buffer.append(c); |
|
} |
|
} |
|
return buffer.toString(); |
|
} |
|
|
|
/** |
|
* Escape解码 |
|
* |
|
* @param content 被转义的内容 |
|
* @return 解码后的字符串 |
|
*/ |
|
public static String decode(String content) |
|
{ |
|
if (StringUtils.isEmpty(content)) |
|
{ |
|
return content; |
|
} |
|
|
|
StringBuilder tmp = new StringBuilder(content.length()); |
|
int lastPos = 0, pos = 0; |
|
char ch; |
|
while (lastPos < content.length()) |
|
{ |
|
pos = content.indexOf("%", lastPos); |
|
if (pos == lastPos) |
|
{ |
|
if (content.charAt(pos + 1) == 'u') |
|
{ |
|
ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); |
|
tmp.append(ch); |
|
lastPos = pos + 6; |
|
} |
|
else |
|
{ |
|
ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); |
|
tmp.append(ch); |
|
lastPos = pos + 3; |
|
} |
|
} |
|
else |
|
{ |
|
if (pos == -1) |
|
{ |
|
tmp.append(content.substring(lastPos)); |
|
lastPos = content.length(); |
|
} |
|
else |
|
{ |
|
tmp.append(content.substring(lastPos, pos)); |
|
lastPos = pos; |
|
} |
|
} |
|
} |
|
return tmp.toString(); |
|
} |
|
|
|
public static void main(String[] args) |
|
{ |
|
String html = "<script>alert(1);</script>"; |
|
// String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>"; |
|
// String html = "<123"; |
|
// String html = "123>"; |
|
System.out.println(EscapeUtil.clean(html)); |
|
System.out.println(EscapeUtil.escape(html)); |
|
System.out.println(EscapeUtil.unescape(html)); |
|
} |
|
}
|
|
|