diff --git a/CHANGELOG.md b/CHANGELOG.md index c0cfb0679..87086db3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ ### Bug修复 * 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题 +* 【json 】 修复SQLEXception导致的栈溢出(issue#1401@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java index b5641b305..393cc0c61 100644 --- a/hutool-json/src/main/java/cn/hutool/json/JSONArray.java +++ b/hutool-json/src/main/java/cn/hutool/json/JSONArray.java @@ -26,11 +26,11 @@ import static cn.hutool.json.JSONConverter.jsonConvert; * JSON数组
* JSON数组是表示中括号括住的数据表现形式
* 对应的JSON字符串格格式例如: - * + * *
  * ["a", "b", "c", 12]
  * 
- * + * * @author looly */ public class JSONArray implements JSON, JSONGetter, List, RandomAccess { @@ -56,7 +56,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 构造
* 默认使用{@link ArrayList} 实现 - * + * * @param initialCapacity 初始大小 * @since 3.2.2 */ @@ -67,7 +67,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 构造
* 默认使用{@link ArrayList} 实现 - * + * * @param config JSON配置项 * @since 4.6.5 */ @@ -78,7 +78,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 构造
* 默认使用{@link ArrayList} 实现 - * + * * @param initialCapacity 初始大小 * @param config JSON配置项 * @since 4.1.19 @@ -91,7 +91,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 构造
* 将参数数组中的元素转换为JSON对应的对象加入到JSONArray中 - * + * * @param list 初始化的JSON数组 */ public JSONArray(Iterable list) { @@ -104,7 +104,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 构造
* 将参数数组中的元素转换为JSON对应的对象加入到JSONArray中 - * + * * @param list 初始化的JSON数组 */ public JSONArray(Collection list) { @@ -137,7 +137,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando /** * 从对象构造,忽略{@code null}的值
* 支持以下类型的参数: - * + * *
 	 * 1. 数组
 	 * 2. {@link Iterable}对象
@@ -154,7 +154,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 	/**
 	 * 从对象构造
* 支持以下类型的参数: - * + * *
 	 * 1. 数组
 	 * 2. {@link Iterable}对象
@@ -172,7 +172,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 	/**
 	 * 从对象构造
* 支持以下类型的参数: - * + * *
 	 * 1. 数组
 	 * 2. {@link Iterable}对象
@@ -197,7 +197,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 设置转为字符串时的日期格式,默认为时间戳(null值)
-	 * 
+	 *
 	 * @param format 格式,null表示使用时间戳
 	 * @return this
 	 * @since 4.1.19
@@ -343,7 +343,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 当此JSON列表的每个元素都是一个JSONObject时,可以调用此方法返回一个Iterable,便于使用foreach语法遍历
-	 * 
+	 *
 	 * @return Iterable
 	 * @since 4.0.12
 	 */
@@ -493,7 +493,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 转为Bean数组
-	 * 
+	 *
 	 * @param arrayClass 数组元素类型
 	 * @return 实体类对象
 	 */
@@ -503,7 +503,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 转为{@link ArrayList}
-	 * 
+	 *
 	 * @param  元素类型
 	 * @param elementType 元素类型
 	 * @return {@link ArrayList}
@@ -536,7 +536,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 将JSON内容写入Writer
-	 * 
+	 *
 	 * @param writer writer
 	 * @param indentFactor 缩进因子,定义每一级别增加的缩进量
 	 * @param indent 本级别缩进量
@@ -575,7 +575,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 初始化
-	 * 
+	 *
 	 * @param source 数组或集合或JSON数组字符串
 	 * @throws JSONException 非数组或集合
 	 */
@@ -605,15 +605,21 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 			} else {
 				throw new JSONException("JSONArray initial value should be a string or collection or array.");
 			}
+
+			Object next;
 			while (iter.hasNext()) {
-				this.add(iter.next());
+				next = iter.next();
+				// 检查循环引用
+				if(next != source){
+					this.add(next);
+				}
 			}
 		}
 	}
 
 	/**
 	 * 初始化
-	 * 
+	 *
 	 * @param source JSON字符串
 	 */
 	private void init(CharSequence source) {
@@ -624,7 +630,7 @@ public class JSONArray implements JSON, JSONGetter, List, Rando
 
 	/**
 	 * 初始化
-	 * 
+	 *
 	 * @param x {@link JSONTokener}
 	 */
 	private void init(JSONTokener x) {
diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java
index 18a8d98a8..b25f910ac 100644
--- a/hutool-json/src/main/java/cn/hutool/json/JSONObject.java
+++ b/hutool-json/src/main/java/cn/hutool/json/JSONObject.java
@@ -24,7 +24,6 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
 import java.util.Enumeration;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.ResourceBundle;
@@ -653,7 +652,7 @@ public class JSONObject implements JSON, JSONGetter, Map
 			return;
 		}
 
-		if(ArrayUtil.isArray(source) || source instanceof Iterable || source instanceof Iterator){
+		if(ArrayUtil.isArray(source)){
 			// 不支持集合类型转换为JSONObject
 			throw new JSONException("Unsupported type [{}] to JSONObject!", source.getClass());
 		}
diff --git a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java
index 238fe2321..6cccd9bf1 100644
--- a/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java
+++ b/hutool-json/src/main/java/cn/hutool/json/JSONUtil.java
@@ -21,6 +21,7 @@ import java.io.StringWriter;
 import java.io.Writer;
 import java.lang.reflect.Type;
 import java.nio.charset.Charset;
+import java.sql.SQLException;
 import java.time.temporal.TemporalAccessor;
 import java.util.Calendar;
 import java.util.Date;
@@ -735,6 +736,11 @@ public final class JSONUtil {
 		}
 
 		try {
+			// fix issue#1401@Github
+			if(object instanceof SQLException){
+				return object.toString();
+			}
+
 			// JSONArray
 			if (object instanceof Iterable || ArrayUtil.isArray(object)) {
 				return new JSONArray(object, jsonConfig);
diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
index 5348ab732..60a49d8aa 100644
--- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
+++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
@@ -11,6 +11,7 @@ import cn.hutool.json.test.bean.UserC;
 import org.junit.Assert;
 import org.junit.Test;
 
+import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
@@ -179,4 +180,12 @@ public class JSONUtilTest {
 				"    \"test\": \"\\\\地库地库\",\n" +
 				"}");
 	}
+
+	@Test
+	public void sqlExceptionTest(){
+		//https://github.com/looly/hutool/issues/1401
+		// SQLException实现了Iterable接口,默认是遍历之,会栈溢出,修正后只返回string
+		final JSONObject set = JSONUtil.createObj().set("test", new SQLException("test"));
+		Assert.assertEquals("{\"test\":\"java.sql.SQLException: test\"}", set.toString());
+	}
 }