3434
3535public final class BufferedTokenizerWithSizeLimitTest {
3636
37+ public static final int GB = 1024 * 1024 * 1024 ;
38+
3739 private BufferedTokenizer sut ;
3840
3941 @ Before
4042 public void setUp () {
41- sut = new BufferedTokenizer ("\n " , 10 );
43+ initSUTWithSizeLimit (10 );
44+ }
45+
46+ private void initSUTWithSizeLimit (int sizeLimit ) {
47+ sut = new BufferedTokenizer ("\n " , sizeLimit );
4248 }
4349
4450 @ Test
@@ -129,4 +135,29 @@ public void givenFragmentThatHasTheSecondTokenOverrunsSizeLimitThenAnErrorIsThro
129135 // third token resumes
130136 assertEquals ("ccc" , tokensIterator .next ());
131137 }
138+
139+ @ Test
140+ public void givenTooLongInputExtractDoesntOverflow () {
141+ assertEquals ("Xmx must equals to what's defined in the Gradle's javaTests task" ,
142+ 12L * GB , Runtime .getRuntime ().maxMemory ());
143+
144+ // re-init the tokenizer with big sizeLimit
145+ initSUTWithSizeLimit ((int ) ((2L * GB ) - 3 ));
146+ // Integer.MAX_VALUE is 2 * GB
147+ String bigFirstPiece = generateString ("a" , Integer .MAX_VALUE - 1024 );
148+ sut .extract (bigFirstPiece );
149+
150+ // add another small fragment to trigger int overflow
151+ // sizeLimit is (2^32-1)-3 first segment length is (2^32-1) - 1024 second is 1024 +2
152+ // so the combined length of first and second is > sizeLimit and should throw an expection
153+ // but because of overflow it's negative and happens to be < sizeLimit
154+ Exception thrownException = assertThrows (IllegalStateException .class , () -> {
155+ sut .extract (generateString ("a" , 1024 + 2 )).iterator ().next ();
156+ });
157+ assertThat (thrownException .getMessage (), containsString ("input buffer full" ));
158+ }
159+
160+ private String generateString (String fill , int size ) {
161+ return fill .repeat (size );
162+ }
132163}
0 commit comments