From 49c70e5b394d303b47bd894d430f78f08aefc268 Mon Sep 17 00:00:00 2001 From: Louis Bergelson Date: Wed, 26 Sep 2018 10:39:35 -0400 Subject: [PATCH] fixing bug in SeekableHttpStream.read (#1182) * fixing bug in SeekableHttpStream.read * a bug in SeekableHttpStream could cause clients to go into an infinite loop because read would return 0 when trying to read one byte past the end of the file * fixes #1181 --- .../seekablestream/SeekableHTTPStream.java | 5 ++++- .../seekablestream/SeekableBufferedStreamTest.java | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/htsjdk/samtools/seekablestream/SeekableHTTPStream.java b/src/main/java/htsjdk/samtools/seekablestream/SeekableHTTPStream.java index 640a14d989..a846fe4512 100644 --- a/src/main/java/htsjdk/samtools/seekablestream/SeekableHTTPStream.java +++ b/src/main/java/htsjdk/samtools/seekablestream/SeekableHTTPStream.java @@ -100,9 +100,12 @@ public int read(byte[] buffer, int offset, int len) throws IOException { if (offset < 0 || len < 0 || (offset + len) > buffer.length) { throw new IndexOutOfBoundsException("Offset="+offset+",len="+len+",buflen="+buffer.length); } - if (len == 0 || position == contentLength) { + if (len == 0 ) { return 0; } + if (position == contentLength) { + return -1; + } HttpURLConnection connection = null; InputStream is = null; diff --git a/src/test/java/htsjdk/samtools/seekablestream/SeekableBufferedStreamTest.java b/src/test/java/htsjdk/samtools/seekablestream/SeekableBufferedStreamTest.java index f6e0b69899..4e498828db 100644 --- a/src/test/java/htsjdk/samtools/seekablestream/SeekableBufferedStreamTest.java +++ b/src/test/java/htsjdk/samtools/seekablestream/SeekableBufferedStreamTest.java @@ -69,6 +69,20 @@ public void testRandomRead() throws IOException { assertEquals(buffer1, buffer2); } + @Test + public void testReadExactlyOneByteAtEndOfFile() throws IOException { + try (final SeekableStream stream = new SeekableHTTPStream(new URL(BAM_URL_STRING))){ + byte[] buff = new byte[1]; + long length = stream.length(); + stream.seek(length - 1); + Assert.assertFalse(stream.eof()); + Assert.assertEquals(stream.read(buff), 1); + Assert.assertTrue(stream.eof()); + Assert.assertEquals(stream.read(buff), -1); + } + } + + /** * Test an attempt to read past the end of the file. The test file is 594,149 bytes in length. The test * attempts to read a 1000 byte block starting at position 594000. A correct result would return 149 bytes.