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

Changes to ensure if no object is opened user won't be able to write property name #2475

Merged
merged 4 commits into from
Aug 22, 2023

Conversation

shivam-sehgal
Copy link
Contributor

@shivam-sehgal shivam-sehgal commented Aug 21, 2023

Purpose

Currently, even if the no object is opened or begin object is not called or all open objects are ended using jsonwriter.endObject()
Still user is able to add json object property name, which shouldn't be happening
Closes #2407

Description

Currently when the Jsonwriter name method is called no check is there to identify if it's an empty document or all open objects are closed and stack size reaches 1 and the top element is NON_EMPTY_DOC
basically the two case

  • The user calls jsonwrite.name() for the first time in an empty document or when the beginobject method has not been called.
  • The user calls jsonwrite.name() when all opened objects are closed.
    In both of these invalid cases, the stack size should be 1 as per the current implementation

    In the first case, stack will be having one status only which will be EMPTY_DOCUMENT
    
In the second case, all other statuses will be popped from the stack and only one status NONEMPTY_DOCUMENT will be present in the stack
    So added a check in the name method for these 2 special cases
    Also added and changed the unit test as per the requirement

Checklist

  • New code follows the Google Java Style Guide
  • If necessary, new public API validates arguments, for example rejects null
  • New public API has Javadoc
    • Javadoc uses @since $next-version$
      ($next-version$ is a special placeholder which is automatically replaced during release)
  • If necessary, new unit tests have been added
    • Assertions in unit tests use Truth, see existing tests
    • No JUnit 3 features are used (such as extending class TestCase)
    • If this pull request fixes a bug, a new test was added for a situation which failed previously and is now fixed
  • mvn clean verify javadoc:jar passes without errors

Copy link
Member

@eamonnmcmanus eamonnmcmanus left a comment

Choose a reason for hiding this comment

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

Thanks, this looks great! I have some minor comments. I'm also going to try running this against all of Google's internal tests, though I don't expect that will find any problems.

@@ -498,6 +498,10 @@ public JsonWriter name(String name) throws IOException {
if (stackSize == 0) {
throw new IllegalStateException("JsonWriter is closed.");
}
// As currently in any valid case name function cannot be called if stack top has these 2 statuses
if (stackSize == 1 && ( peek() == EMPTY_DOCUMENT || peek() == NONEMPTY_DOCUMENT )) {
Copy link
Member

Choose a reason for hiding this comment

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

Style nit: there shouldn't be a space after ( or before ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

my bad, corrected that, thanks for pointing out

jsonWriter.endArray(); // End the array
jsonWriter.endObject(); // End the outer object
assertThrows(IllegalStateException.class, () -> jsonWriter.name("this_throw_exception_as_all_objects_are_closed"));
assertThrows(IllegalStateException.class, () -> jsonWriter.value("this_throw_exception_as_only_one_top_level_entry"));
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little uneasy at the assumption that the previous statement hasn't changed the state of jsonWriter. I think it might be better to move the preceding setup into a private method (that maybe returns a JsonWriter) and then use that method in two different test methods, one for .name and one for .value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agree with you regarding status change and the possible impact of it, created a private method to return jsonwritter as you recommended, and running both tests with 2 separate objects

} catch (IllegalStateException expected) {
assertThat(expected).hasMessageThat().isEqualTo("Nesting problem.");
assertThrows(IllegalStateException.class, () -> jsonWriter.name("hello"));
//removed nested exception test on jsonwriter.writevalue as it seems currently valid case per code
Copy link
Member

Choose a reason for hiding this comment

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

I think you are right about removing that test, but now that you have recorded that, can you remove this comment? It will be confusing for future readers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, reading this comment will be odd for users as code is already gone, thanks for pointing it out, removed this comment

@@ -498,6 +498,10 @@ public JsonWriter name(String name) throws IOException {
if (stackSize == 0) {
throw new IllegalStateException("JsonWriter is closed.");
}
// As currently in any valid case name function cannot be called if stack top has these 2 statuses
Copy link
Member

Choose a reason for hiding this comment

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

I found this comment a bit confusing. I think it isn't really necessary anyway? It doesn't really tell the reader anything that they can't already see from the following statement.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it! removed this unecessary comment

@shivam-sehgal
Copy link
Contributor Author

Thank you for reviewing the code! I'll look forward to the test results.

Copy link
Member

@eamonnmcmanus eamonnmcmanus left a comment

Choose a reason for hiding this comment

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

Thanks for doing this! I ran it against all of Google's internal tests and did not see any problems.

@eamonnmcmanus eamonnmcmanus merged commit 392cc65 into google:main Aug 22, 2023
9 checks passed
@shivam-sehgal
Copy link
Contributor Author

Thanks for doing this! I ran it against all of Google's internal tests and did not see any problems.

Thanks for the approval :)

@Marcono1234
Copy link
Collaborator

Thanks @shivam-sehgal for your work on this!

Unfortunately I think my original issue made it look like this only affected the top level (which is addressed by your pull request), but it actually also affects trying to use JsonWriter.name inside a JSON array.

I have created #2476 to (hopefully) fully resolve this. It reverts some of your test changes because handling of multiple top-level values was already covered by multiple separate test methods, and while it is generally good that your method getJsonWriterWithObjects covered multiple value types; I think here more concise test data specific to this issue might be better. The data created by getJsonWriterWithObjects might rather be useful for integration tests / functional tests (I think) but there already a bunch of this in this repository. Sorry for that; I hope it is ok for you (and for @eamonnmcmanus).

tibor-universe pushed a commit to getuniverse/gson that referenced this pull request Sep 14, 2024
…property name (google#2475)

* Changes to ensure if no object is opened user won't be able to add prop in the object

* review points

* spelling correction
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.

3 participants