Merge pull request #651 from cushon/i650

Use IdentityHashSet for cycle detection
This commit is contained in:
Sean Leary 2021-12-03 19:35:26 -06:00 committed by GitHub
commit 04e8ea84dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.IdentityHashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -1526,7 +1527,7 @@ public class JSONObject {
* the bean * the bean
*/ */
private void populateMap(Object 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) { 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.MyNumberContainer;
import org.json.junit.data.MyPublicClass; import org.json.junit.data.MyPublicClass;
import org.json.junit.data.RecursiveBean; import org.json.junit.data.RecursiveBean;
import org.json.junit.data.RecursiveBeanEquals;
import org.json.junit.data.Singleton; import org.json.junit.data.Singleton;
import org.json.junit.data.SingletonEnum; import org.json.junit.data.SingletonEnum;
import org.json.junit.data.WeirdList; import org.json.junit.data.WeirdList;
@ -3311,6 +3312,21 @@ public class JSONObjectTest {
new JSONObject(ObjD); new JSONObject(ObjD);
new JSONObject(ObjE); 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 @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();
}
}