diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/DecompressorStream.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/DecompressorStream.java index 745105ce873af..900b6f17549a0 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/DecompressorStream.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/compress/DecompressorStream.java @@ -199,9 +199,10 @@ public long skip(long n) throws IOException { checkStream(); // Read 'n' bytes - int skipped = 0; + long skipped = 0; while (skipped < n) { - int len = Math.min(((int)n - skipped), skipBytes.length); + // len is between 0 and skipBytes.length, so downcast is safe + int len = (int)Math.min((n - skipped), skipBytes.length); len = read(skipBytes, 0, len); if (len == -1) { eof = true; diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/compress/TestBlockDecompressorStream.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/compress/TestBlockDecompressorStream.java index cdab772e2fcd7..3a4b7ec591800 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/compress/TestBlockDecompressorStream.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/io/compress/TestBlockDecompressorStream.java @@ -23,6 +23,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.EOFException; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -48,6 +49,26 @@ public void testRead2() throws IOException { testRead(4); } + @Test + public void testDecompressorStreamSkipOutOfBound() throws IOException { + ByteArrayInputStream bytesIn; + DecompressorStream decompStream; + int bufLen = 4; + bytesOut = new ByteArrayOutputStream(); + bytesOut.write(ByteBuffer.allocate(bufLen).putInt(1024).array(), 0, bufLen); + buf = bytesOut.toByteArray(); + bytesIn = new ByteArrayInputStream(buf); + + decompStream = new DecompressorStream(bytesIn, new FakeDecompressor()); + try { + // check that skipping a length longer than Integer.MAX_VALUE does not + // throw IndexOutOfBoundsException + decompStream.skip((long)Integer.MAX_VALUE + 1); + } catch (EOFException e) { + // expected exception, because the input is not that long + } + } + private void testRead(int bufLen) throws IOException { // compress empty stream bytesOut = new ByteArrayOutputStream();