diff --git a/src/main/java/org/takes/rq/ChunkedInputStream.java b/src/main/java/org/takes/rq/ChunkedInputStream.java index b77ee1b99..0dee6bcbf 100644 --- a/src/main/java/org/takes/rq/ChunkedInputStream.java +++ b/src/main/java/org/takes/rq/ChunkedInputStream.java @@ -37,9 +37,8 @@ /** * Input stream from chunked coded http request body. - * - * @since 0.31.2 * @link Chunked Transfer Coding + * @since 0.31.2 */ final class ChunkedInputStream extends InputStream { @@ -70,6 +69,7 @@ final class ChunkedInputStream extends InputStream { /** * Ctor. + * * @param stream The raw input stream */ ChunkedInputStream(final InputStream stream) { @@ -109,7 +109,13 @@ public int read(final byte[] buf, final int off, final int len) if (shift == len) { result = len; } else { - result = shift + this.read(buf, off + shift, len - shift); + result = shift + Math.max( + this.read( + buf, + off + shift, + len - shift + ), 0 + ); } } return result; diff --git a/src/test/java/org/takes/rq/ChunkedInputStreamTest.java b/src/test/java/org/takes/rq/ChunkedInputStreamTest.java index e16b345b5..2d958cdcd 100644 --- a/src/test/java/org/takes/rq/ChunkedInputStreamTest.java +++ b/src/test/java/org/takes/rq/ChunkedInputStreamTest.java @@ -134,4 +134,33 @@ void ignoresParameterAfterSemiColon() throws IOException { MatcherAssert.assertThat(stream.available(), Matchers.equalTo(0)); stream.close(); } + + @Test + void readsWithLenGreaterThanTotalSize() throws IOException { + final String data = "Hello, World!"; + final String length = Integer.toHexString(data.length()); + final InputStream stream = new ChunkedInputStream( + IOUtils.toInputStream( + new Joined( + ChunkedInputStreamTest.CRLF, + length, + data, + ChunkedInputStreamTest.END_OF_CHUNK, + "" + ).toString(), + StandardCharsets.UTF_8 + ) + ); + final byte[] buf = new byte[data.length() + 10]; + MatcherAssert.assertThat( + stream.read(buf), + Matchers.equalTo(data.length()) + ); + MatcherAssert.assertThat( + buf, + Matchers.equalTo((data + new String(new byte[10])).getBytes()) + ); + MatcherAssert.assertThat(stream.available(), Matchers.equalTo(0)); + stream.close(); + } }