Merge pull request #2755 from LuisStruggle/v5-dev

HtmlUtil中escape方法,增加不断开空格(nbsp)转译,防止xss攻击
This commit is contained in:
Golden Looly 2022-11-28 10:23:11 +08:00 committed by GitHub
commit 5f10d2d025
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 6 deletions

View File

@ -176,7 +176,7 @@ public interface StrPool {
/**
* 字符串常量HTML 空格转义 {@code " " -> " "}
* 字符串常量HTML 不间断空格转义 {@code " " -> " "}
*/
String HTML_NBSP = XmlUtil.NBSP;

View File

@ -67,7 +67,7 @@ import java.util.Map;
public class XmlUtil {
/**
* 字符串常量XML 空格转义 {@code " " -> " "}
* 字符串常量XML 不间断空格转义 {@code " " -> " "}
*/
public static final String NBSP = " ";

View File

@ -26,19 +26,21 @@ public class HtmlUtil {
public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
public static final String RE_SCRIPT = "<[\\s]*?script[^>]*?>.*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
private static final char[][] TEXT = new char[64][];
private static final char[][] TEXT = new char[256][];
static {
for (int i = 0; i < 64; i++) {
// ascii码值最大的是0x7f=127扩展ascii码值最大的是0xFF=255因为ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符标准ASCII码也叫基础ASCII码
for (int i = 0; i < 256; i++) {
TEXT[i] = new char[] { (char) i };
}
// special HTML characters
TEXT['\''] = "&#039;".toCharArray(); // 单引号 ('&apos;' doesn't work - it is not by the w3 specs)
TEXT['"'] = QUOTE.toCharArray(); // 引号
TEXT['"'] = QUOTE.toCharArray(); // 引号
TEXT['&'] = AMP.toCharArray(); // &
TEXT['<'] = LT.toCharArray(); // 小于号
TEXT['>'] = GT.toCharArray(); // 大于号
TEXT[' '] = NBSP.toCharArray(); // 不断开空格non-breaking space缩写nbspASCII值是32是用键盘输入的空格ASCII值是160不间断空格 &nbsp所产生的空格作用是在页面换行时不被打断
}
/**
@ -190,7 +192,7 @@ public class HtmlUtil {
char c;
for (int i = 0; i < len; i++) {
c = text.charAt(i);
if (c < 64) {
if (c < 256) {
buffer.append(TEXT[c]);
} else {
buffer.append(c);

View File

@ -134,6 +134,16 @@ public class HtmlUtilTest {
Assert.assertEquals("'", HtmlUtil.unescape("&apos;"));
}
@Test
public void escapeTest2() {
char c = ' '; // 不断开空格non-breaking space缩写nbsp)
Assert.assertEquals(c, 160);
String html = "<html><body> </body></html>";
String escape = HtmlUtil.escape(html);
Assert.assertEquals("&lt;html&gt;&lt;body&gt;&nbsp;&lt;/body&gt;&lt;/html&gt;", escape);
Assert.assertEquals(" ", HtmlUtil.unescape("&nbsp;"));
}
@Test
public void filterTest() {
String html = "<alert></alert>";