|
18 | 18 | package org.apache.commons.codec.digest; |
19 | 19 |
|
20 | 20 | import org.junit.Assert; |
| 21 | +import org.junit.Assume; |
21 | 22 |
|
22 | 23 | import java.nio.ByteBuffer; |
23 | 24 | import java.util.Arrays; |
@@ -890,4 +891,37 @@ private static int[] createRandomBlocks(final int maxLength) { |
890 | 891 | } |
891 | 892 | return Arrays.copyOf(blocks, count); |
892 | 893 | } |
| 894 | + |
| 895 | + /** |
| 896 | + * This test hits an edge case where a very large number of bytes is added to the incremental |
| 897 | + * hash. The data is constructed so that an integer counter of unprocessed bytes will |
| 898 | + * overflow. If this is not handled correctly then the code throws an exception when it |
| 899 | + * copies more data into the unprocessed bytes array. |
| 900 | + */ |
| 901 | + @Test |
| 902 | + public void testIncrementalHashWithUnprocessedBytesAndHugeLengthArray() { |
| 903 | + // Assert the test precondition that a large array added to unprocessed bytes |
| 904 | + // will overflow an integer counter. We use the smallest hugeLength possible |
| 905 | + // as some VMs cannot allocate maximum length arrays. |
| 906 | + final int unprocessedSize = 3; |
| 907 | + final int hugeLength = Integer.MAX_VALUE - 2; |
| 908 | + Assert.assertTrue("This should overflow to negative", unprocessedSize + hugeLength < 4); |
| 909 | + |
| 910 | + // Check the test can be run |
| 911 | + byte[] bytes = null; |
| 912 | + try { |
| 913 | + bytes = new byte[hugeLength]; |
| 914 | + } catch (OutOfMemoryError ignore) { |
| 915 | + // Some VMs cannot allocate an array this large. |
| 916 | + // Some test environments may not have enough available memory for this. |
| 917 | + } |
| 918 | + Assume.assumeTrue("Cannot allocate array of length " + hugeLength, bytes != null); |
| 919 | + |
| 920 | + final IncrementalHash32x86 inc = new IncrementalHash32x86(); |
| 921 | + inc.start(0); |
| 922 | + // Add bytes that should be unprocessed |
| 923 | + inc.add(bytes, 0, unprocessedSize); |
| 924 | + // Add a huge number of bytes to overflow an integer counter of unprocessed bytes. |
| 925 | + inc.add(bytes, 0, hugeLength); |
| 926 | + } |
893 | 927 | } |
0 commit comments