From 812955e39d5324780c3867e582f33c531466b7f3 Mon Sep 17 00:00:00 2001 From: Liam Miller-Cushon Date: Fri, 26 Nov 2021 20:07:21 -0500 Subject: [PATCH] Use IdentityHashSet for cycle detection Fixes https://github.com/stleary/JSON-java/issues/650 --- src/main/java/org/json/JSONObject.java | 5 +-- .../java/org/json/junit/JSONObjectTest.java | 16 +++++++++ .../json/junit/data/RecursiveBeanEquals.java | 33 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/json/junit/data/RecursiveBeanEquals.java diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index 77d509b..99a0750 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -37,9 +37,10 @@ import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; @@ -1526,7 +1527,7 @@ public class JSONObject { * the bean */ private void populateMap(Object bean) { - populateMap(bean, new HashSet()); + populateMap(bean, Collections.newSetFromMap(new IdentityHashMap())); } private void populateMap(Object bean, Set objectsRecord) { diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 381c942..7f4fb72 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -74,6 +74,7 @@ import org.json.junit.data.MyNumber; import org.json.junit.data.MyNumberContainer; import org.json.junit.data.MyPublicClass; import org.json.junit.data.RecursiveBean; +import org.json.junit.data.RecursiveBeanEquals; import org.json.junit.data.Singleton; import org.json.junit.data.SingletonEnum; import org.json.junit.data.WeirdList; @@ -3311,6 +3312,21 @@ public class JSONObjectTest { new JSONObject(ObjD); new JSONObject(ObjE); } + @Test(expected=JSONException.class) + public void testRecursiveEquals() { + RecursiveBeanEquals a = new RecursiveBeanEquals("same"); + a.setRef(a); + new JSONObject(a); + } + @Test + public void testNotRecursiveEquals() { + RecursiveBeanEquals a = new RecursiveBeanEquals("same"); + RecursiveBeanEquals b = new RecursiveBeanEquals("same"); + RecursiveBeanEquals c = new RecursiveBeanEquals("same"); + a.setRef(b); + b.setRef(c); + new JSONObject(a); + } @Test diff --git a/src/test/java/org/json/junit/data/RecursiveBeanEquals.java b/src/test/java/org/json/junit/data/RecursiveBeanEquals.java new file mode 100644 index 0000000..1016648 --- /dev/null +++ b/src/test/java/org/json/junit/data/RecursiveBeanEquals.java @@ -0,0 +1,33 @@ +package org.json.junit.data; + +/** test class for verifying if recursively defined bean can be correctly identified */ +public class RecursiveBeanEquals { + private final String name; + private Object reference; + + public RecursiveBeanEquals(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public Object getRef() { + return reference; + } + + public void setRef(Object refObj) { + reference = refObj; + } + + @Override + public boolean equals(Object other) { + return other instanceof RecursiveBeanEquals && name.equals(((RecursiveBeanEquals) other).name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } +}