Use IdentityHashSet for cycle detection

Fixes https://github.com/stleary/JSON-java/issues/650
This commit is contained in:
Liam Miller-Cushon 2021-11-26 20:07:21 -05:00
parent bc623e36d6
commit 812955e39d
3 changed files with 52 additions and 2 deletions

View File

@ -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<Object>());
populateMap(bean, Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>()));
}
private void populateMap(Object bean, Set<Object> objectsRecord) {

View File

@ -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

View File

@ -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();
}
}