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

avoid using recursion in for JSONML and JSONTokener #726

Closed
wants to merge 7 commits into from

Conversation

cleydyr
Copy link
Contributor

@cleydyr cleydyr commented Feb 12, 2023

Fixes #722

@stleary
Copy link
Owner

stleary commented Feb 12, 2023

Nice work!
A description of what was changed and why it was changed would be helpful.
The changes to JSONML should probably not be included in this pull request, since that file is being updated in #723 and will be accepted before this PR.
Good to see the unit tests did not find any regressions.
What is needed to ensure that there have been no functional changes - i.e. that the new code produces exactly the same results as the old? I don't think the current unit tests are sufficient to confirm this.

@cleydyr
Copy link
Contributor Author

cleydyr commented Feb 13, 2023

No problem. I can drop the first commit, which is related to JSONML.

The commits prefixed by refactoring can be proven to make no functional changes.

The last commit is trickier, as I tried to simulate what the call stack does: push local variables (at least the relevant ones) and the instruction into the stack, but it would be hard to prove that the two algorithms yield the same results.

So, I see two alternatives: 1) generate a considerable amount of data in the JSON format that corresponds to the grammar that this parser obeys (the grammar should be defined formally, as in https://www.json.org/json-en.html) and add tests to reduce the likelihood of missing a case (never eliminating it, of course) or 2) assume the tests we have currently are "good enough" and, should anybody find a regression, fix the parser accordingly.

What do you think?

@stleary
Copy link
Owner

stleary commented Feb 14, 2023

A lot of code was updated. The unit tests are good for catching regressions but for this PR I don't think that is enough. Probably needs a careful review and some additional unit testing. Otherwise, I think someone could fairly ask why not create a ParserConfiguration class similar to XML and JSONML and avoid all the refactoring.

JSONTokener tokener = new JSONTokener(resourceAsStream);
JSONArray json_input = new JSONArray(tokener);
assertNotNull(json_input);
fail("Excepected Exception.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why test was removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because with my changes a stack overflow is not expected to happen as the algorithm to parse strings to JSON is not recursive anymore. So the test would fail 100% of the time, instead of intermittently as it does currently.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be changes in test

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For both of these, these tests looks like they were testing to make sure that a stack overflow occurred. So these tests "pass" if the bug isn't fixed, but will fail if the bug is fixed. So... not the best test to leave in.

That said, a better test might be to ensure that the use case that previously threw an exception no longer throws an exception? So instead of removing the tests entirely, update them to test that use case, but ensure that no exception is not thrown instead of ensuring that an exception is thrown?

(I'm not a maintainer on this project, just my two cents as someone who was watching this CVE.)

JSONTokener tokener = new JSONTokener(resourceAsStream);
JSONObject json_input = new JSONObject(tokener);
assertNotNull(json_input);
fail("Excepected Exception.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test should not be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not good remove tests after code changes

@javadev
Copy link
Contributor

javadev commented Feb 20, 2023

I see so many changes and few unit tests

@javadev
Copy link
Contributor

javadev commented Feb 20, 2023

This branch has conflicts that must be resolved

Copy link
Contributor

@javadev javadev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many code changes and few unit tests

@javadev
Copy link
Contributor

javadev commented Apr 27, 2023

This branch has conflicts that must be resolved

@cleydyr cleydyr closed this Apr 27, 2023
@cleydyr
Copy link
Contributor Author

cleydyr commented Apr 27, 2023

I'll send this again when I rebase and have some test coverage.

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 this pull request may close these issues.

JSONObject/Array should be protected from stack overflow exceptions caused by recursion
5 participants