Skip to content

Commit

Permalink
修复JSONUtil.parse()溢出问题
Browse files Browse the repository at this point in the history
  • Loading branch information
looly committed Sep 5, 2023
1 parent afbe2ce commit 5c4486b
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# 🚀Changelog

-------------------------------------------------------------------------------------------------------------
# 5.8.22(2023-09-01)
# 5.8.22(2023-09-05)

### 🐣新特性
* 【core 】 NumberUtil.nullToZero增加重载(issue#I7PPD2@Gitee)
Expand Down Expand Up @@ -30,6 +30,7 @@
* 【core 】 修复fillColumns空指针问题(issue#3284@Github)
* 【core 】 修复Convert不能转换Optional和Opt问题(issue#I7WJHH@Gitee)
* 【core 】 修复DateUtil.age年龄计算问题(issue#I7XMYW@Gitee)
* 【core 】 修复JSONUtil.parse()溢出问题(issue#3289@Github)

-------------------------------------------------------------------------------------------------------------
# 5.8.21(2023-07-29)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Matcher;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
Expand Down Expand Up @@ -432,10 +433,8 @@ public static <T> List<T> setOrPadding(List<T> list, int index, T element, T pad
if (index < size) {
list.set(index, element);
} else {
// issue#3286, 增加安全检查,最多增加2倍
if(index > (list.size() + 1) * 2) {
throw new UtilException("Index is too large:", index);
}
// issue#3286, 增加安全检查,最多增加10倍
Validator.checkIndexLimit(index, list.size());
for (int i = size; i < index; i++) {
list.add(paddingElement);
}
Expand Down
19 changes: 19 additions & 0 deletions hutool-core/src/main/java/cn/hutool/core/lang/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -1257,4 +1257,23 @@ public static <T extends CharSequence> T validateCarDrivingLicence(T value, Stri
}
return value;
}

/**
* 检查给定的index是否超出长度限制,默认检查超出倍数(10倍),此方法主要用于内部,检查包括:
* <ul>
* <li>数组调用setOrPadding时,最多允许padding的长度</li>
* <li>List调用setOrPadding时,最多允许padding的长度</li>
* <li>JSONArray调用setOrPadding时,最多允许padding的长度</li>
* </ul>
*
* @param index 索引
* @param size 数组、列表长度
* @since 5.8.22
*/
public static void checkIndexLimit(final int index, final int size) {
// issue#3286, 增加安全检查,最多增加10倍
if (index > (size + 1) * 10) {
throw new ValidateException("Index [{}] is too large for size: [{}]", index, size);
}
}
}
7 changes: 3 additions & 4 deletions hutool-json/src/main/java/cn/hutool/json/JSONArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cn.hutool.core.bean.BeanPath;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutableObj;
import cn.hutool.core.lang.mutable.MutablePair;
Expand Down Expand Up @@ -457,10 +458,8 @@ public void add(int index, Object element) {
InternalJSONUtil.testValidity(element);
this.rawList.add(index, JSONUtil.wrap(element, this.config));
} else {
// issue#3286, 增加安全检查,最多增加2倍
if(index > (this.size() + 1) * 2) {
throw new JSONException("Index is too large:", index);
}
// issue#3286, 增加安全检查,最多增加10倍
Validator.checkIndexLimit(index, this.size());
while (index != this.size()) {
this.add(JSONNull.NULL);
}
Expand Down
3 changes: 2 additions & 1 deletion hutool-json/src/main/java/cn/hutool/json/JSONParser.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cn.hutool.json;

import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Filter;
import cn.hutool.core.lang.mutable.Mutable;
import cn.hutool.core.lang.mutable.MutablePair;
Expand Down Expand Up @@ -66,7 +67,7 @@ public void parseTo(JSONObject jsonObject, Filter<MutablePair<String, Object>> f
}
default:
tokener.back();
key = tokener.nextValue().toString();
key = tokener.nextStringValue();
}

// The key is followed by ':'.
Expand Down
39 changes: 38 additions & 1 deletion hutool-json/src/main/java/cn/hutool/json/JSONTokener.java
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,43 @@ public String nextTo(String delimiters) throws JSONException {
}
}

/**
* 获取下一个String格式的值,用户获取key
* @return String格式的值
* @since 5.8.22
*/
public String nextStringValue(){
char c = this.nextClean();

switch (c) {
case '"':
case '\'':
return this.nextString(c);
case '{':
case '[':
throw this.syntaxError("Sting value must be not begin with a '{' or '['");
}

/*
* Handle unquoted text. This could be the values true, false, or null, or it can be a number.
* An implementation (such as this one) is allowed to also accept non-standard forms. Accumulate
* characters until we reach the end of the text or a formatting character.
*/

final StringBuilder sb = new StringBuilder();
while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
sb.append(c);
c = this.next();
}
this.back();

final String string = sb.toString().trim();
if (string.isEmpty()) {
throw this.syntaxError("Missing value");
}
return string;
}

/**
* 获得下一个值,值类型可以是Boolean, Double, Integer, JSONArray, JSONObject, Long, or String, or the JSONObject.NULL
*
Expand Down Expand Up @@ -366,7 +403,7 @@ public Object nextValue() throws JSONException {
this.back();

string = sb.toString().trim();
if (0 == string.length()) {
if (string.isEmpty()) {
throw this.syntaxError("Missing value");
}
return InternalJSONUtil.stringToValue(string);
Expand Down
23 changes: 23 additions & 0 deletions hutool-json/src/test/java/cn/hutool/json/Issue3289Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2023 looly([email protected])
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

package cn.hutool.json;

import org.junit.Test;

public class Issue3289Test {
@Test(expected = JSONException.class)
public void parseTest() {
final String s = "{\"a\":1,[6E962756779]}";
JSONUtil.parse(s);
}
}

0 comments on commit 5c4486b

Please sign in to comment.