Revision: 5785 Author: [email protected] Date: Thu Jul 23 14:47:07 2009 Log: Fixes a buffer overflow in AsyncFragmentLoader.
Review by: bobv http://code.google.com/p/google-web-toolkit/source/detail?r=5785 Modified: /trunk/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java /trunk/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java ======================================= --- /trunk/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java Thu Jul 16 16:35:08 2009 +++ /trunk/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java Thu Jul 23 14:47:07 2009 @@ -108,8 +108,9 @@ /** * A trivial queue of int's that should compile much better than a - * LinkedList<Integer>. It assumes that there will be a maximum number - * of items passed through the queue for its entire life. + * LinkedList<Integer>. It assumes that it has a bound on the number of + * items added to the queue. Removing items does not free up more space, but + * calling <code>clear()</code> does. */ private static class BoundedIntQueue { private final int[] array; @@ -119,22 +120,31 @@ public BoundedIntQueue(int maxPuts) { array = new int[maxPuts]; } - + public void add(int x) { assert (write < array.length); array[write++] = x; } - + + /** + * Removes all elements, and also makes all space in the queue available + * again. + */ + public void clear() { + read = 0; + write = 0; + } + public int peek() { assert read < write; return array[read]; } - + public int remove() { assert read < write; return array[read++]; } - + public int size() { return write - read; } @@ -177,6 +187,12 @@ handlersToRun.add(waitingForInitialFragmentsErrorHandlers.remove()); waitingForInitialFragments.remove(); } + + /* + * Call clear() here so that waitingForInitialFragments makes all of its + * space available for later requests. + */ + waitingForInitialFragments.clear(); // add handlers for pending initial fragment downloads handlersToRun.addAll(initialFragmentErrorHandlers.values()); ======================================= --- /trunk/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java Sun Jul 19 09:52:17 2009 +++ /trunk/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java Thu Jul 23 14:47:07 2009 @@ -237,6 +237,30 @@ loader.fragmentHasLoaded(5); reqs.assertFragmentsRequested(); } + + /** + * This test catches a case in an earlier version of AsyncFragmentLoader where + * AsyncFragmentLoader.waitingForInitialFragments could exhaust its available + * space. + */ + public void testOverflowInWaitingForInitialFragments() { + MockLoadStrategy reqs = new MockLoadStrategy(); + int numEntries = 6; + AsyncFragmentLoader loader = new AsyncFragmentLoader(numEntries, new int[] { + 1, 2, 3}, reqs, NULL_LOGGER); + + /* + * Repeatedly queue up extra downloads waiting on an initial and then fail. + */ + for (int i = 0; i < 10; i++) { + MockErrorHandler error = new MockErrorHandler(); + loader.inject(4, error); + reqs.assertFragmentsRequested(1); + + loadFailed(reqs, 1); + assertTrue(error.getWasCalled()); + } + } /** * A thorough exercise of loading with an initial load sequence specified. --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
