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

JsonReader skipValue() can cause an infinite loop #605

Closed
GoogleCodeExporter opened this issue Mar 19, 2015 · 1 comment · Fixed by #2062
Closed

JsonReader skipValue() can cause an infinite loop #605

GoogleCodeExporter opened this issue Mar 19, 2015 · 1 comment · Fixed by #2062
Labels

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
2. run reader.beginObject() to start reading the stream

3. run reader.skipValue() repeatedly until you try and skip over the "}" to end 
the json stream.  the last skip will cause an infinite loop.


What is the expected output? What do you see instead?
I would expect an exception to be thrown indicating EOF was hit, or that you 
cannot skip over an object/array closing.  Even silently ignoring would be 
better then an infinite loop.



What version of the product are you using? On what operating system?
2.3 w/ Java 1.7.0_67



Please provide any additional information below.

JsonReader line 1249 decrements the count to -1 because PEEKED_END_OBJECT is 
encountered on the last skip, but since the next item is EOF, it forever 
infinite loops waiting for the counter to get incremented back to 0, which 
never occurs.

I put in a quick hack for my problem by adding an extra if condition

} else if (p == PEEKED_EOF) {
    count = 0;
}

Probably a better fix would be to check for count>0 instead of !=0 (assuming 
that doesn't cause a problem somewhere else, but I am not familiar enough with 
the code base to try this).

This code snippet can reproduce the problem:

   public void testEarlyEOF() throws Exception {
        String json = "{ \"errors\":[ { \"field\":null,\"code\":\"loanId-not-found\" } ] }";

        final InputStream is = new ByteArrayInputStream(json.getBytes());

        Thread t = new Thread() {
            @Override
            public void run() {
                JsonReader reader = new JsonReader(new InputStreamReader(is));

                try {
                    reader.beginObject();     // start of overall json object
                    reader.skipValue();       // skip "errors" label
                    reader.skipValue();       // skip array value for "errors"
                    reader.skipValue();       // try and skip the closing "}"
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

        t.setDaemon(true);
        t.start();

        t.join(10000);
        boolean alive = t.isAlive();
        if (alive) t.interrupt();
        assertFalse("should have finished by now, we must be hung", alive);
    }



Original issue reported on code.google.com by rocco.ga...@gmail.com on 3 Nov 2014 at 2:15

@Cerebrum2
Copy link

The same problem is still in version 2.8.0.
It is obvious if you look at the code of JsonReader.skipValue()

To reproduce. Make sure you are at the state END_OBJECT or END_ARRAY
call skipValue()
==> endless loop

The reason is that count is initialized with 0.
When END_OBJECT or END_ARRAY is reached it performs count-- and count becomes negative.

So the loop will never terminate:
while (count != 0);

garydgregory added a commit to garydgregory/gson that referenced this issue Jan 18, 2020
fix skipValue() for END_ARRAY and END_OBJECT, fixes google#605
@Marcono1234 Marcono1234 added the bug label Aug 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants