@@ -39,6 +39,7 @@ of this software and associated documentation files (the "Software"), to deal
3939import java .util .Collection ;
4040import java .util .Enumeration ;
4141import java .util .HashMap ;
42+ import java .util .HashSet ;
4243import java .util .Iterator ;
4344import java .util .Locale ;
4445import java .util .Map ;
@@ -1510,6 +1511,11 @@ public String optString(String key, String defaultValue) {
15101511 return NULL .equals (object ) ? defaultValue : object .toString ();
15111512 }
15121513
1514+ // Set to store the current seen objects in the recursive reaversal
1515+ // If the next value to be added to this set is a duplicate, a cycle
1516+ // is found
1517+ private final Set <Object > objectsRecord = new HashSet <Object >();
1518+
15131519 /**
15141520 * Populates the internal map of the JSONObject with the bean properties. The
15151521 * bean can not be recursive.
@@ -1541,8 +1547,18 @@ && isValidMethodName(method.getName())) {
15411547 final Object result = method .invoke (bean );
15421548 if (result != null ) {
15431549 // check cyclic dependency and throw error if needed
1550+ // the wrap and populateMap combination method is
1551+ // itself DFS recursive
1552+ if (objectsRecord .contains (result )) {
1553+ throw recursivelyDefinedObjectException (key );
1554+ }
1555+
1556+ objectsRecord .add (result );
15441557
15451558 this .map .put (key , wrap (result ));
1559+
1560+ objectsRecord .remove (result );
1561+
15461562 // we don't use the result anywhere outside of wrap
15471563 // if it's a resource we should be sure to close it
15481564 // after calling toString
@@ -2678,4 +2694,15 @@ private static JSONException wrongValueFormatException(
26782694 "JSONObject[" + quote (key ) + "] is not a " + valueType + " (" + value + ")."
26792695 , cause );
26802696 }
2697+
2698+ /**
2699+ * Create a new JSONException in a common format for recursive object definition.
2700+ * @param key name of the key
2701+ * @return JSONException that can be thrown.
2702+ */
2703+ private static JSONException recursivelyDefinedObjectException (String key ) {
2704+ return new JSONException (
2705+ "JavaBean object contains recursively defined member variable of key " + quote (key )
2706+ );
2707+ }
26812708}
0 commit comments