Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java heap space: OOM #58

Closed
Alanscut opened this issue Nov 6, 2019 · 2 comments
Closed

java heap space: OOM #58

Alanscut opened this issue Nov 6, 2019 · 2 comments
Assignees
Labels
bug released Issue has been released
Milestone

Comments

@Alanscut
Copy link
Contributor

Alanscut commented Nov 6, 2019

hi Andres, some particular scenario will trigger the OOM Exception in JSONObject.fromObject():

String str = "{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}:1}";
JSONObject object = JSONObject.fromObject(str);
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.base/java.util.Arrays.copyOf(Arrays.java:3746)
	at java.base/java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:172)
	at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:748)
	at java.base/java.lang.StringBuffer.append(StringBuffer.java:424)
	at org.kordamp.json.JSONObject.toString(JSONObject.java:2079)
        ...

The problem lies in the buffer allocation memory:
JSONUitls.java

   public static String quote(String string) {
       ...
       StringBuffer sb = new StringBuffer(len * 2);
       ...

Since double quotes need to be escaped, the number of slash symbol will grow exponentially with the number of nested layers.

@PeterXMoore
Copy link

PeterXMoore commented Sep 27, 2022

I'd like to lobby for making this a high priority fix.

The problem is that although only strings are legal keys in JSON, fromJSONTokener ends up accepting objects and arrays as keys as well. The memory issue comes up from the recursive quoting of all the object keys. The string representation grows exponentially: doubling in size for every level of nesting.

I have a simple fix: change the portion of fromJSONTokener that parses the key to only allow strings:

                      c = tokener.nextClean();
                      switch (c) {
                          case 0:
                              throw tokener.syntaxError("A JSONObject text must end with '}'");
                          // start of fix
                          case '{':
                              throw tokener.syntaxError("Object found where key expected");
                          case '[': 
                              throw tokener.syntaxError("Array found where key expected");
                          // end of fix         
                          case '}':
                              fireObjectEndEvent(jsonConfig);
                              return jsonObject;
                          default:

I've made this change locally, and the fixed version passes org.kordamp.json's full test suite. And our next release, with 20 or so projects using org.kordamp.json, makes use of the fixed version and no issues were found in our normal release testing.

(By the way: org.json had the same issue, but fixed it in org.json-20220320 with commit 7a124d8 on Jan 31)

If it would help, I could generate a pull request. Though be warned: it would my first git pull request.

@aalmiray aalmiray self-assigned this Sep 30, 2022
@aalmiray aalmiray added the bug label Sep 30, 2022
@aalmiray aalmiray added this to the 3.0.3 milestone Sep 30, 2022
@github-actions github-actions bot added the released Issue has been released label Sep 27, 2024
Copy link
Contributor

🎉 This issue has been resolved in v3.1.0 (Release Notes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug released Issue has been released
Projects
None yet
Development

No branches or pull requests

3 participants