diff --git a/src/main/java/org/json/JSONObject.java b/src/main/java/org/json/JSONObject.java index c1e3b70..77d509b 100644 --- a/src/main/java/org/json/JSONObject.java +++ b/src/main/java/org/json/JSONObject.java @@ -366,6 +366,11 @@ public class JSONObject { this.populateMap(bean); } + private JSONObject(Object bean, Set objectsRecord) { + this(); + this.populateMap(bean, objectsRecord); + } + /** * Construct a JSONObject from an Object, using reflection to find the * public members. The resulting JSONObject's keys will be the strings from @@ -1511,11 +1516,6 @@ public class JSONObject { return NULL.equals(object) ? defaultValue : object.toString(); } - // Set to store the current seen objects in the recursive reaversal - // If the next value to be added to this set is a duplicate, a cycle - // is found - private final Set objectsRecord = new HashSet(); - /** * Populates the internal map of the JSONObject with the bean properties. The * bean can not be recursive. @@ -1526,6 +1526,10 @@ public class JSONObject { * the bean */ private void populateMap(Object bean) { + populateMap(bean, new HashSet()); + } + + private void populateMap(Object bean, Set objectsRecord) { Class klass = bean.getClass(); // If klass is a System class then set includeSuperClass to false. @@ -1555,7 +1559,7 @@ public class JSONObject { objectsRecord.add(result); - this.map.put(key, wrap(result)); + this.map.put(key, wrap(result, objectsRecord)); objectsRecord.remove(result); @@ -2449,6 +2453,10 @@ public class JSONObject { * @return The wrapped value */ public static Object wrap(Object object) { + return wrap(object, null); + } + + private static Object wrap(Object object, Set objectsRecord) { try { if (NULL.equals(object)) { return NULL; @@ -2483,7 +2491,15 @@ public class JSONObject { || object.getClass().getClassLoader() == null) { return object.toString(); } - return new JSONObject(object); + if (objectsRecord != null) { + return new JSONObject(object, objectsRecord); + } + else { + return new JSONObject(object); + } + } + catch (JSONException exception) { + throw exception; } catch (Exception exception) { return null; } diff --git a/src/test/java/org/json/junit/JSONObjectTest.java b/src/test/java/org/json/junit/JSONObjectTest.java index 94c3e4b..e19a157 100644 --- a/src/test/java/org/json/junit/JSONObjectTest.java +++ b/src/test/java/org/json/junit/JSONObjectTest.java @@ -73,6 +73,7 @@ import org.json.junit.data.MyJsonString; 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.Singleton; import org.json.junit.data.SingletonEnum; import org.json.junit.data.WeirdList; @@ -3218,6 +3219,14 @@ public class JSONObjectTest { jsonObject.put(null, new Object()); fail("Expected an exception"); } + @Test(expected=JSONException.class) + public void testSimpleRecursiveObject() { + RecursiveBean ObjA = new RecursiveBean("ObjA"); + RecursiveBean ObjB = new RecursiveBean("ObjB", ObjA); + ObjA.setRef(ObjB); + JSONObject jsonObject = new JSONObject(ObjA); + fail("Expected an exception"); + } @Test public void testIssue548ObjectWithEmptyJsonArray() { diff --git a/src/test/java/org/json/junit/data/RecursiveBean.java b/src/test/java/org/json/junit/data/RecursiveBean.java index 00caf13..18ec8bd 100644 --- a/src/test/java/org/json/junit/data/RecursiveBean.java +++ b/src/test/java/org/json/junit/data/RecursiveBean.java @@ -10,6 +10,7 @@ public class RecursiveBean { private Object reference; public String getName() { return name; } public Object getRef() {return reference;} + public void setRef(Object refObj) {reference = refObj;} public RecursiveBean(String name) { this.name = name;