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

ArrayIndexOutOfBoundsException when parsing large Map #49

Closed
mjavault opened this issue Oct 13, 2016 · 4 comments
Closed

ArrayIndexOutOfBoundsException when parsing large Map #49

mjavault opened this issue Oct 13, 2016 · 4 comments
Milestone

Comments

@mjavault
Copy link

mjavault commented Oct 13, 2016

Howdy,
I'm getting the following error when parsing a Map that contains a large number of items (2387 in this case) using Jackson Jr version 2.8.3:

java.lang.ArrayIndexOutOfBoundsException: 3645

The source JSON was generated using the JSON.std.asString() function with no problem, but the result can't be parse back by the JSON.std.anyFrom() function.
Attached a file that reproduces the problem.
large_map.txt

File does not contain duplicate keys, and the parsing works when I reduce the number of items in the Map down to 1822. You can also use the following code to reproduce:

    public static void main(String[] args) {
        int i = 0;
        try {
            for (i = 1; i < 3000; i++) {
                testLargeJson(i);
            }
        } catch (Exception ex) {
            System.out.println(i);
            ex.printStackTrace();
        }
    }

    private static void testLargeJson(int size) throws Exception {
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < size; i++) {
            map.put("" + i, new HashMap<String, Object>());
        }
        String output = JSON.std.asString(map);
        Map json = (Map) JSON.std.anyFrom(output);
    }

This crashes for i = 1823 but not before.

@mjavault
Copy link
Author

Tracked down the problem to this function in DeferredMap:

    private final int _newSize(int size)
    {
        if (size < 200) {
            return size+size;
        }
        if (size < 2000) {
            return size + (size>>1);
        }
        return size + (size>>2);
    }

This can return an odd value, with will then crash when inserting items in put() because put inserts two elements at a time.
I'll open a PR.

@cowtowncoder cowtowncoder modified the milestones: .7.9, 2.7.9 Oct 14, 2016
@cowtowncoder
Copy link
Member

Yes. Thank you for reporting this, will fix ASAP.

@cowtowncoder
Copy link
Member

Fix will be in 2.8.4 (and 2.7.9 whenever that gets released).

@mjavault
Copy link
Author

Thanks!

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

No branches or pull requests

2 participants