From cbe23837b5d2c83e91457a3ec30ffb9be3e3a890 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Fri, 5 Oct 2018 10:14:22 -0700 Subject: [PATCH 1/3] Test to show BinaryCodec.readBytesOrFewer will fail if the input stream is a ByteArrayInputStream, the buffer has no more bytes, and the # of bytes to read is zero. --- .../htsjdk/samtools/util/BinaryCodecTest.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/test/java/htsjdk/samtools/util/BinaryCodecTest.java b/src/test/java/htsjdk/samtools/util/BinaryCodecTest.java index a47bb22e43..1774289d06 100644 --- a/src/test/java/htsjdk/samtools/util/BinaryCodecTest.java +++ b/src/test/java/htsjdk/samtools/util/BinaryCodecTest.java @@ -27,12 +27,7 @@ import org.testng.Assert; import org.testng.annotations.Test; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; /* @@ -284,5 +279,11 @@ public void timeTest() throws IOException{ readCodec.close(); } - + @Test + public void testReadBytesOrFewerNoneAvailable() { + final byte[] value = new byte[0]; + final ByteArrayInputStream instream = new ByteArrayInputStream(value); + final BinaryCodec readCodec = new BinaryCodec(instream); + Assert.assertEquals(readCodec.readBytesOrFewer(value, 0, 0), 0); + } } From 6d40e0a8b458edcd2dc7a2fa58d6f4dbc61f7310 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Fri, 5 Oct 2018 10:15:12 -0700 Subject: [PATCH 2/3] Bug fix: BinaryCodec should not fail when both reading and no bytes are requested. --- src/main/java/htsjdk/samtools/util/BinaryCodec.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/htsjdk/samtools/util/BinaryCodec.java b/src/main/java/htsjdk/samtools/util/BinaryCodec.java index 08fe60a123..14d2e2a8b5 100644 --- a/src/main/java/htsjdk/samtools/util/BinaryCodec.java +++ b/src/main/java/htsjdk/samtools/util/BinaryCodec.java @@ -415,7 +415,8 @@ public int readBytesOrFewer(final byte[] buffer, final int offset, final int len throw new IllegalStateException("Calling read method on BinaryCodec open for write."); } try { - return inputStream.read(buffer, offset, length); + if (length == 0) return 0; + else return inputStream.read(buffer, offset, length); } catch (IOException e) { throw new RuntimeIOException(constructErrorMessage("Read error"), e); } From e3625e748f49fdb6cb8a8f2e34d4e11c34c4faf9 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Fri, 5 Oct 2018 10:40:30 -0700 Subject: [PATCH 3/3] fixups and developer note --- src/main/java/htsjdk/samtools/util/BinaryCodec.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/htsjdk/samtools/util/BinaryCodec.java b/src/main/java/htsjdk/samtools/util/BinaryCodec.java index 14d2e2a8b5..51e23fed09 100644 --- a/src/main/java/htsjdk/samtools/util/BinaryCodec.java +++ b/src/main/java/htsjdk/samtools/util/BinaryCodec.java @@ -415,8 +415,10 @@ public int readBytesOrFewer(final byte[] buffer, final int offset, final int len throw new IllegalStateException("Calling read method on BinaryCodec open for write."); } try { - if (length == 0) return 0; - else return inputStream.read(buffer, offset, length); + // Some implementations of InputStream do not behave well when the buffer is empty and length is zero, for + // example ByteArrayInputStream, so we must check for length equal to zero. + // See: https://bugs.java.com/view_bug.do?bug_id=6766844 + return (length == 0) ? 0 : inputStream.read(buffer, offset, length); } catch (IOException e) { throw new RuntimeIOException(constructErrorMessage("Read error"), e); }