diff --git a/src/main/java/org/xerial/snappy/SnappyInputStream.java b/src/main/java/org/xerial/snappy/SnappyInputStream.java index 24f59767..9835cf90 100755 --- a/src/main/java/org/xerial/snappy/SnappyInputStream.java +++ b/src/main/java/org/xerial/snappy/SnappyInputStream.java @@ -417,9 +417,20 @@ protected boolean hasNextChunk() } } + // chunkSize is negative + if (chunkSize < 0) { + throw new SnappyError(SnappyErrorCode.INVALID_CHUNK_SIZE, "chunkSize is too big or negative : " + chunkSize); + } + // extend the compressed data buffer size if (compressed == null || chunkSize > compressed.length) { - compressed = new byte[chunkSize]; + // chunkSize exceeds limit + try { + compressed = new byte[chunkSize]; + } + catch (java.lang.OutOfMemoryError e) { + throw new SnappyError(SnappyErrorCode.INVALID_CHUNK_SIZE, e.getMessage()); + } } readBytes = 0; while (readBytes < chunkSize) { diff --git a/src/test/java/org/xerial/snappy/SnappyTest.java b/src/test/java/org/xerial/snappy/SnappyTest.java index 8a68b537..55726e79 100755 --- a/src/test/java/org/xerial/snappy/SnappyTest.java +++ b/src/test/java/org/xerial/snappy/SnappyTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.*; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.ByteBuffer; @@ -330,6 +331,53 @@ public void isValidCompressedData() } } + /* + + Tests happy cases for SnappyInputStream.read method + - {0} + */ + @Test + public void isValidChunkLengthForSnappyInputStreamIn() + throws Exception { + byte[] data = {0}; + SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data)); + byte[] out = new byte[50]; + in.read(out); + } + + /* + Tests sad cases for SnappyInputStream.read method + - Expects a java.lang.NegativeArraySizeException catched into a SnappyError + - {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff} + */ + @Test(expected = SnappyError.class) + public void isInvalidChunkLengthForSnappyInputStreamInNegative() + throws Exception { + byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff}; + SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data)); + byte[] out = new byte[50]; + in.read(out); + } + + /* + Tests sad cases for SnappyInputStream.read method + - Expects a java.lang.OutOfMemoryError + - {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff} + */ + @Test(expected = SnappyError.class) + public void isInvalidChunkLengthForSnappyInputStreamOutOfMemory() + throws Exception { + byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff}; + SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data)); + byte[] out = new byte[50]; + try { + in.read(out); + } catch (Exception ignored) { + // Exception here will be catched + // But OutOfMemoryError will not be caught, and will still be thrown + } + } + /* Tests happy cases for BitShuffle.shuffle method - double: 0, 10 @@ -337,7 +385,7 @@ public void isValidCompressedData() - int: 0, 10 - long: 0, 10 - short: 0, 10 - */ + */ @Test public void isValidArrayInputLengthForBitShuffleShuffle() throws Exception @@ -386,5 +434,6 @@ public void isTooLargeLongArrayInputLengthForBitShuffleShuffle() throws Exceptio @Test(expected = SnappyError.class) public void isTooLargeShortArrayInputLengthForBitShuffleShuffle() throws Exception { BitShuffle.shuffle(new short[Integer.MAX_VALUE / 2 + 1]); + } }