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

Gson.fromJson methods now respect the lenient flag #795

Closed
wants to merge 1 commit into from

Conversation

sgbrown
Copy link
Contributor

@sgbrown sgbrown commented Feb 23, 2016

Gson.fromJson(JsonReader, Type) would previously override the lenient flag in the JsonReader to always be true while being used from here. This would cause all instances of Gson to act as though the lenient flag is set to true regardless of the actual state in the Gson object. I have corrected this to respect the lenient flag.

also updated JsonReader.nextDouble() method to deserialize infinite values, following the comments
in GsonBuilder.serializeSpecialFloatingPointValues() method which claims:
"Gson always accepts these special values during deserialization"

These fixes should also address issue #372

also updated JsonReader.nextDouble() method to deserialize infinite values, following the comments
in GsonBuilder.serializeSpecialFloatingPointValues() method which claims:
"Gson always accepts these special values during deserialization"

These fixes should also address issue google#372
@swankjesse
Copy link
Collaborator

Unfortunately, as the tests suggest, this is massively incompatible. If you'd like this behavior in your own code, avoid toJson/fromJson and use a TypeAdapter instead.

@swankjesse swankjesse closed this Feb 23, 2016
@sgbrown
Copy link
Contributor Author

sgbrown commented Feb 23, 2016

I think Gson.lenient flag probably does more harm than good in the current state. The comments on the GsonBuilder.setLenient() method say

By default, Gson is strict and only accepts JSON as specified by RFC 4627.

The comments on Gson.setLenient() also references the JsonReader.setLenient(boolean) method which has a great explanation of what should and shouldn't be considered when using the lenient flag.

The unfortunate fact here is that due to the Gson.fromJson(JsonReader, Type) method always setting the lenient flag to true when parsing, almost none of what is commented in GsonBuilder about the default behavior of Gson is true. The only affect that setting the lenient flag on Gson will do is to allow comments to be at the end of your json buffer when calling Gson.fromJson(Reader, Type) since the assertFullConsumption(Object, JsonReader) method will be called from here and only checks for data at the end of the buffer having not been consumed (e.g. comments at the end).

Consider, for example, the test in com.google.gson.functional.LeniencyTest

    @Override
   protected void setUp() throws Exception {
     super.setUp();
     gson = new GsonBuilder().setLenient().create();
   }

   public void testLenientFromJson() {
     List<String> json = gson.fromJson(""
         + "[ # One!\n"
         + "  'Hi' #Element!\n"
         + "] # Array!", new TypeToken<List<String>>() {}.getType());
     assertEquals(singletonList("Hi"), json);
   }

If you were to remove the comment at the end of the String ("# Array!"), then it would not make any difference at all whether or not the lenient flag had been set. The following would also pass:

     List<String> json = new GsonBuilder().create().fromJson(""
         + "[ # One!\n"
         + "  'Hi' #Element!\n"
         + "]", new TypeToken<List<String>>() {}.getType());
     assertEquals(singletonList("Hi"), json);

It seems counterintuitive that with the lenient flag unset, comments in the middle of the JSON data would be ignored but comments at the end would cause a failure when the Gson parser is supposed to be "strict".

If it is considered undesirable to change the default behavior (to the behavior that is documented) by actually respecting a default lenient flag being set to false (i.e. default to strict), then perhaps the correct answer is to respect the lenient flag, default Gson to have the lenient flag set to true, and update the javadocs to reflect that Gson by default is lenient.

Do you have any thoughts on this alternate approach?

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.

2 participants