From f4355e81082efa874bfd9cd2a66ff05ac163be78 Mon Sep 17 00:00:00 2001 From: Wei-Chiu Chuang Date: Mon, 24 Jul 2023 15:08:23 -0700 Subject: [PATCH] HADOOP-12677. DecompressorStream throws IndexOutOfBoundsException when calling skip(long). Change-Id: I73183ce9c4ff55d71a0d46be4d5b11c48dbdef24 --- .../io/compress/DecompressorStream.java | 5 +++-- .../compress/TestBlockDecompressorStream.java | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) 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();