mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
增加ParseConfig,通过增加maxNestingDepth参数避免StackOverflowError问题,修复CVE-2022-45688漏洞
This commit is contained in:
parent
69206406d7
commit
30fafaa5de
@ -39,20 +39,23 @@ public class JSONXMLParser {
|
||||
public static void parseJSONObject(final String xmlStr, final JSONObject jo, final ParseConfig parseConfig) throws JSONException {
|
||||
final XMLTokener x = new XMLTokener(xmlStr, jo.config());
|
||||
while (x.more() && x.skipPast("<")) {
|
||||
parse(x, jo, null, parseConfig);
|
||||
parse(x, jo, null, parseConfig, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描XML内容,并解析到JSONObject中。
|
||||
*
|
||||
* @param x {@link XMLTokener}
|
||||
* @param context {@link JSONObject}
|
||||
* @param name 标签名,null表示从根标签开始解析
|
||||
* @param x {@link XMLTokener}
|
||||
* @param context {@link JSONObject}
|
||||
* @param name 标签名,null表示从根标签开始解析
|
||||
* @param parseConfig 解析选项
|
||||
* @param currentNestingDepth 当前层级
|
||||
* @return {@code true}表示解析完成
|
||||
* @throws JSONException JSON异常
|
||||
*/
|
||||
private static boolean parse(final XMLTokener x, final JSONObject context, final String name, final ParseConfig parseConfig) throws JSONException {
|
||||
private static boolean parse(final XMLTokener x, final JSONObject context, final String name,
|
||||
final ParseConfig parseConfig, final int currentNestingDepth) throws JSONException {
|
||||
final char c;
|
||||
int i;
|
||||
final JSONObject jsonobject;
|
||||
@ -175,7 +178,14 @@ public class JSONXMLParser {
|
||||
|
||||
} else if (token == XmlConstants.C_LT) {
|
||||
// Nested element
|
||||
if (parse(x, jsonobject, tagName, parseConfig)) {
|
||||
// issue#2748 of CVE-2022-45688
|
||||
final int maxNestingDepth = parseConfig.getMaxNestingDepth();
|
||||
if (maxNestingDepth > -1 && currentNestingDepth >= maxNestingDepth) {
|
||||
throw x.syntaxError("Maximum nesting depth of " + maxNestingDepth + " reached");
|
||||
}
|
||||
|
||||
// Nested element
|
||||
if (parse(x, jsonobject, tagName, parseConfig, currentNestingDepth + 1)) {
|
||||
if (jsonobject.isEmpty()) {
|
||||
context.append(tagName, StrUtil.EMPTY);
|
||||
} else if (jsonobject.size() == 1 && jsonobject.get("content") != null) {
|
||||
|
@ -44,7 +44,7 @@ public class ParseConfig implements Serializable {
|
||||
/**
|
||||
* 最大嵌套深度,用于解析时限制解析层级,当大于这个层级时抛出异常,-1表示无限制
|
||||
*/
|
||||
private int maxNestingDepth;
|
||||
private int maxNestingDepth = -1;
|
||||
|
||||
/**
|
||||
* 是否保持值为String类型,如果为{@code false},则尝试转换为对应类型(numeric, boolean, string)
|
||||
|
@ -0,0 +1,18 @@
|
||||
package org.dromara.hutool.json.xml;
|
||||
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.json.JSONException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class Issue2748Test {
|
||||
|
||||
@Test
|
||||
void toJSONObjectTest() {
|
||||
final String s = StrUtil.repeat("<a>", 600);
|
||||
|
||||
Assertions.assertThrows(JSONException.class, () -> {
|
||||
JSONXMLUtil.toJSONObject(s, ParseConfig.of().setMaxNestingDepth(512));
|
||||
});
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user