stleary / JSON-java

A reference implementation of a JSON package in Java.
http://stleary.github.io/JSON-java/index.html
Other
4.53k stars 2.56k forks source link

JSONObject stack overflow #837

Open Renis-1 opened 10 months ago

Renis-1 commented 10 months ago

If a list has itself as an element JSONObject(list) causes stack overflow error as seen in following code:

List<List<?>> list = new LinkedList<>();
list.add(list);
JSONObject j = new JSONObject(list);
stleary commented 10 months ago

@Renis-1 Thanks for bringing this up. Will see if a fix can be added after #823 is committed.

michalbbednarczyk commented 9 months ago

stack overflow error is also caused by:

Deque<Deque<?>> deque = new ArrayDeque<>();
deque.add(deque);
JSONObject jo = new JSONObject(deque);
BlockingDeque<BlockingDeque<?>> deque = new LinkedBlockingDeque<>();
deque.add(deque);
JSONObject jo = new JSONObject(deque);
Properties properties = new Properties();
properties.put("key", properties);
JSONObject jo = new JSONObject(properties);
EnumMap<TestEnum, EnumMap<TestEnum, ?>> map = new EnumMap<>(TestEnum.class);
map.put(TestEnum.CONSTANT1, map);
JSONObject jo = new JSONObject(map);
Hashtable<String, Hashtable<String, ?>> table = new Hashtable<>();
table.put("key", table);
JSONObject jo = new JSONObject(table);
Map<String, Map<String, ?>> map = new IdentityHashMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
Map<String, Map<String, ?>> map = new TreeMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
Map<String, Map<String, ?>> map = new WeakHashMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
Map<String, Map<String, ?>> map = new LinkedHashMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
SortedMap<String, SortedMap<String, ?>> map = new TreeMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
NavigableMap<String, NavigableMap<String, ?>> map = new TreeMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
Map<String, Map<String, ?>> map = new ConcurrentHashMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
Queue<Stack<?>> queue = new LinkedList<>();
Stack<Stack<?>> stack = new Stack<>();
stack.add(stack);
queue.add(stack);
JSONObject jo = new JSONObject(queue);
Deque<Deque<?>> deque = new LinkedBlockingDeque<>();
deque.add(deque);
JSONObject jo = new JSONObject(deque);
Queue<Runnable> queue = new SynchronousQueue<>();
Runnable element = () -> {};
queue.add(element);
JSONObject jo = new JSONObject(queue);
Deque<Deque<?>> deque = new ConcurrentLinkedDeque<>();
deque.add(deque);
JSONObject jo = new JSONObject(deque);
ConcurrentSkipListMap<String, ConcurrentSkipListMap<String, ?>> map = new ConcurrentSkipListMap<>();
map.put("key", map);
JSONObject jo = new JSONObject(map);
johnjaylward commented 9 months ago

Yeah... don't do that. The JavaDoc specifically states that that will happen and not to use cyclical references.

stleary commented 9 months ago

@micbedn Thanks for posting. Are you sure you are testing with the latest code, though? I am only seeing JSONExceptions:

    @Test
    public void foo() {
        Deque<Deque<?>> deque = new ArrayDeque<>();
        deque.add(deque);
        JSONObject jo = new JSONObject(deque);
    }

Output:

JSONArray has reached recursion depth limit of 512 org.json.JSONException: JSONArray has reached recursion depth limit of 512