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

Consider using IdentityHashSet for cycle detection #650

Closed
cushon opened this issue Nov 26, 2021 · 2 comments · Fixed by #651
Closed

Consider using IdentityHashSet for cycle detection #650

cushon opened this issue Nov 26, 2021 · 2 comments · Fixed by #651

Comments

@cushon
Copy link
Contributor

cushon commented Nov 26, 2021

The cycle detection introduced in #632 / #645 uses a HashSet, and detects if the object being serialized contains another object that is equal using Object.equals. This reports errors for objects where there isn't actually a cycle, but a contained object tests equal with an enclosing one, like in the following example.

Using IdentityHashMap instead of HashSet would detect actual cycles, but avoid reporting the following error.

import org.json.JSONObject;

class Json {

  public static void main(String[] args) {
    new JSONObject(new Foo(1, new Foo(1, new Foo(1, null))));
  }

  public static class Foo {

    final int x;
    final Foo f;

    Foo(int x, Foo f) {
      this.x = x;
      this.f = f;
    }

    public Foo getFoo() {
      return f;
    }

    @Override
    public boolean equals(Object other) {
      return other instanceof Foo && ((Foo) other).x == x;
    }

    @Override
    public int hashCode() {
      return x;
    }
  }
}
Exception in thread "main" org.json.JSONException: JavaBean object contains recursively defined member variable of key "foo"
	at org.json.JSONObject.recursivelyDefinedObjectException(JSONObject.java:2722)
	at org.json.JSONObject.populateMap(JSONObject.java:1558)
	at org.json.JSONObject.<init>(JSONObject.java:371)
	at org.json.JSONObject.wrap(JSONObject.java:2496)
	at org.json.JSONObject.populateMap(JSONObject.java:1563)
	at org.json.JSONObject.populateMap(JSONObject.java:1529)
	at org.json.JSONObject.<init>(JSONObject.java:366)
	at Json.main(Json.java:6)
cushon added a commit to cushon/JSON-java that referenced this issue Nov 27, 2021
@stleary
Copy link
Owner

stleary commented Dec 1, 2021

@cushon Thanks for catching and fixing this.

@stleary stleary closed this as completed Dec 1, 2021
@stleary stleary reopened this Dec 1, 2021
@stleary
Copy link
Owner

stleary commented Dec 1, 2021

To be fixed in #651

@stleary stleary closed this as completed Dec 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants