fix escape bug

This commit is contained in:
Looly 2020-02-28 14:22:16 +08:00
parent 83d6428db8
commit fbfb124f11
5 changed files with 86 additions and 28 deletions

View File

@ -7,8 +7,10 @@
### 新特性
* 【poi 】 Excel合并单元格读取同一个值不再为空
* 【core 】 增加EscapeUtil.escapeAllissue#758@Github
### Bug修复
* 【core 】 修复EscapeUtil.escape转义错误issue#758@Github
-------------------------------------------------------------------------------------------------------------

View File

@ -29,6 +29,7 @@ public class ReplacerChain extends StrReplacer implements Chain<StrReplacer, Rep
}
}
@SuppressWarnings("NullableProblems")
@Override
public Iterator<StrReplacer> iterator() {
return replacers.iterator();

View File

@ -17,6 +17,7 @@ public abstract class StrReplacer implements Replacer<CharSequence>, Serializabl
/**
* 抽象的字符串替换方法通过传入原字符串和当前位置执行替换逻辑返回处理或替换的字符串长度部分
*
* @param str 被处理的字符串
* @param pos 当前位置
* @param out 输出

View File

@ -1,5 +1,6 @@
package cn.hutool.core.util;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.text.escape.Html4Escape;
import cn.hutool.core.text.escape.Html4Unescape;
@ -12,6 +13,17 @@ import cn.hutool.core.text.escape.Html4Unescape;
*/
public class EscapeUtil {
/**
* 不转义的符号编码
*/
private static final String NOT_ESCAPE_CHARS = "*@-_+./";
private static final Filter<Character> JS_ESCAPE_FILTER = c -> false == (
Character.isDigit(c)
|| Character.isLowerCase(c)
|| Character.isUpperCase(c)
|| StrUtil.contains(NOT_ESCAPE_CHARS, c)
);
/**
* 转义HTML4中的特殊字符
*
@ -19,7 +31,7 @@ public class EscapeUtil {
* @return 转义后的文本
* @since 4.1.5
*/
public static String escapeHtml4(String html) {
public static String escapeHtml4(CharSequence html) {
Html4Escape escape = new Html4Escape();
return escape.replace(html).toString();
}
@ -31,33 +43,52 @@ public class EscapeUtil {
* @return 转义后的文本
* @since 4.1.5
*/
public static String unescapeHtml4(String html) {
public static String unescapeHtml4(CharSequence html) {
Html4Unescape unescape = new Html4Unescape();
return unescape.replace(html).toString();
}
/**
* Escape编码Unicode<br>
* 该方法不会对 ASCII 字母和数字进行编码也不会对下面这些 ASCII 标点符号进行编码 * @ - _ + . / 其他所有的字符都会被转义序列替换
* Escape编码Unicode等同于JS的escape()方法<br>
* 该方法不会对 ASCII 字母和数字进行编码也不会对下面这些 ASCII 标点符号进行编码 * @ - _ + . / <br>
* 其他所有的字符都会被转义序列替换
*
* @param content 被转义的内容
* @return 编码后的字符串
*/
public static String escape(String content) {
if (StrUtil.isBlank(content)) {
return content;
public static String escape(CharSequence content) {
return escape(content, JS_ESCAPE_FILTER);
}
int i;
/**
* Escape编码Unicode<br>
* 该方法不会对 ASCII 字母和数字进行编码其他所有的字符都会被转义序列替换
*
* @param content 被转义的内容
* @return 编码后的字符串
*/
public static String escapeAll(CharSequence content) {
return escape(content, c -> true);
}
/**
* Escape编码Unicode<br>
* 该方法不会对 ASCII 字母和数字进行编码其他所有的字符都会被转义序列替换
*
* @param content 被转义的内容
* @param filter 编码过滤器对于过滤器中accept为false的字符不做编码
* @return 编码后的字符串
*/
public static String escape(CharSequence content, Filter<Character> filter) {
if (StrUtil.isEmpty(content)) {
return StrUtil.str(content);
}
final StringBuilder tmp = new StringBuilder(content.length() * 6);
char j;
StringBuilder tmp = new StringBuilder();
tmp.ensureCapacity(content.length() * 6);
for (i = 0; i < content.length(); i++) {
for (int i = 0; i < content.length(); i++) {
j = content.charAt(i);
if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) {
if (false == filter.accept(j)) {
tmp.append(j);
} else if (j < 256) {
tmp.append("%");

View File

@ -13,5 +13,28 @@ public class EscapeUtilTest {
String result = EscapeUtil.unescapeHtml4("&#25391;&#33633;&#22120;&#31867;&#22411;");
Assert.assertEquals("振荡器类型", result);
String escape = EscapeUtil.escapeHtml4("*@-_+./(123你好)");
Assert.assertEquals("*@-_+./(123你好)", escape);
}
@Test
public void escapeTest(){
String str = "*@-_+./(123你好)ABCabc";
String escape = EscapeUtil.escape(str);
Assert.assertEquals("*@-_+./%28123%u4f60%u597d%29ABCabc", escape);
String unescape = EscapeUtil.unescape(escape);
Assert.assertEquals(str, unescape);
}
@Test
public void escapeAllTest(){
String str = "*@-_+./(123你好)ABCabc";
String escape = EscapeUtil.escapeAll(str);
Assert.assertEquals("%2a%40%2d%5f%2b%2e%2f%28%31%32%33%u4f60%u597d%29%41%42%43%61%62%63", escape);
String unescape = EscapeUtil.unescape(escape);
Assert.assertEquals(str, unescape);
}
}