EscapeUtil.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package com.ruoyi.common.utils.html;
  2. import com.ruoyi.common.utils.StringUtils;
  3. /**
  4. * 转义和反转义工具类
  5. *
  6. * @author ruoyi
  7. */
  8. public class EscapeUtil {
  9. public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
  10. private static final char[][] TEXT = new char[64][];
  11. static {
  12. for (int i = 0; i < 64; i++) {
  13. TEXT[i] = new char[]{(char) i};
  14. }
  15. // special HTML characters
  16. TEXT['\''] = "&#039;".toCharArray(); // 单引号
  17. TEXT['"'] = "&#34;".toCharArray(); // 双引号
  18. TEXT['&'] = "&#38;".toCharArray(); // &符
  19. TEXT['<'] = "&#60;".toCharArray(); // 小于号
  20. TEXT['>'] = "&#62;".toCharArray(); // 大于号
  21. }
  22. /**
  23. * 转义文本中的HTML字符为安全的字符
  24. *
  25. * @param text 被转义的文本
  26. * @return 转义后的文本
  27. */
  28. public static String escape(String text) {
  29. return encode(text);
  30. }
  31. /**
  32. * 还原被转义的HTML特殊字符
  33. *
  34. * @param content 包含转义符的HTML内容
  35. * @return 转换后的字符串
  36. */
  37. public static String unescape(String content) {
  38. return decode(content);
  39. }
  40. /**
  41. * 清除所有HTML标签,但是不删除标签内的内容
  42. *
  43. * @param content 文本
  44. * @return 清除标签后的文本
  45. */
  46. public static String clean(String content) {
  47. return new HTMLFilter().filter(content);
  48. }
  49. /**
  50. * Escape编码
  51. *
  52. * @param text 被编码的文本
  53. * @return 编码后的字符
  54. */
  55. private static String encode(String text) {
  56. if (StringUtils.isEmpty(text)) {
  57. return StringUtils.EMPTY;
  58. }
  59. final StringBuilder tmp = new StringBuilder(text.length() * 6);
  60. char c;
  61. for (int i = 0; i < text.length(); i++) {
  62. c = text.charAt(i);
  63. if (c < 256) {
  64. tmp.append("%");
  65. if (c < 16) {
  66. tmp.append("0");
  67. }
  68. tmp.append(Integer.toString(c, 16));
  69. } else {
  70. tmp.append("%u");
  71. if (c <= 0xfff) {
  72. // issue#I49JU8@Gitee
  73. tmp.append("0");
  74. }
  75. tmp.append(Integer.toString(c, 16));
  76. }
  77. }
  78. return tmp.toString();
  79. }
  80. /**
  81. * Escape解码
  82. *
  83. * @param content 被转义的内容
  84. * @return 解码后的字符串
  85. */
  86. public static String decode(String content) {
  87. if (StringUtils.isEmpty(content)) {
  88. return content;
  89. }
  90. StringBuilder tmp = new StringBuilder(content.length());
  91. int lastPos = 0, pos = 0;
  92. char ch;
  93. while (lastPos < content.length()) {
  94. pos = content.indexOf("%", lastPos);
  95. if (pos == lastPos) {
  96. if (content.charAt(pos + 1) == 'u') {
  97. ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
  98. tmp.append(ch);
  99. lastPos = pos + 6;
  100. } else {
  101. ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
  102. tmp.append(ch);
  103. lastPos = pos + 3;
  104. }
  105. } else {
  106. if (pos == -1) {
  107. tmp.append(content.substring(lastPos));
  108. lastPos = content.length();
  109. } else {
  110. tmp.append(content.substring(lastPos, pos));
  111. lastPos = pos;
  112. }
  113. }
  114. }
  115. return tmp.toString();
  116. }
  117. public static void main(String[] args) {
  118. String html = "<script>alert(1);</script>";
  119. String escape = EscapeUtil.escape(html);
  120. // String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>";
  121. // String html = "<123";
  122. // String html = "123>";
  123. System.out.println("clean: " + EscapeUtil.clean(html));
  124. System.out.println("escape: " + escape);
  125. System.out.println("unescape: " + EscapeUtil.unescape(escape));
  126. }
  127. }