From f5eea4698d0bf3f0ce23ea07cad5c8474ce64fb7 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Mon, 13 Jun 2016 09:04:41 +0200 Subject: [PATCH] Fix possible NPE in HttpCunkedInput if wrapped ChunkedInput.readChunk(...) return null. Motivation: Its completly fine for ChunkedInput.readChunk(...) to return null to indicate there is currently not any data to read. We need to handle this in HttpChunkedInput to not produce a NPE when constructing the HttpContent. Modifications: If readChunk(...) return null just return null as well. Result: No more NPE. --- .../handler/codec/http/HttpChunkedInput.java | 3 ++ .../codec/http/HttpChunkedInputTest.java | 41 ++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpChunkedInput.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpChunkedInput.java index 23926525fb..7ac61119dc 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpChunkedInput.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpChunkedInput.java @@ -100,6 +100,9 @@ public class HttpChunkedInput implements ChunkedInput { } } else { ByteBuf buf = input.readChunk(allocator); + if (buf == null) { + return null; + } return new DefaultHttpContent(buf); } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpChunkedInputTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpChunkedInputTest.java index fbf607536a..002c8d0826 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpChunkedInputTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpChunkedInputTest.java @@ -16,6 +16,8 @@ package io.netty.handler.codec.http; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.stream.ChunkedFile; import io.netty.handler.stream.ChunkedInput; @@ -82,6 +84,42 @@ public class HttpChunkedInputTest { check(new HttpChunkedInput(new ChunkedNioFile(TMP))); } + @Test + public void testWrappedReturnNull() throws Exception { + HttpChunkedInput input = new HttpChunkedInput(new ChunkedInput() { + @Override + public boolean isEndOfInput() throws Exception { + return false; + } + + @Override + public void close() throws Exception { + // NOOP + } + + @Override + public ByteBuf readChunk(ChannelHandlerContext ctx) throws Exception { + return null; + } + + @Override + public ByteBuf readChunk(ByteBufAllocator allocator) throws Exception { + return null; + } + + @Override + public long length() { + return 0; + } + + @Override + public long progress() { + return 0; + } + }); + assertNull(input.readChunk(ByteBufAllocator.DEFAULT)); + } + private static void check(ChunkedInput... inputs) { EmbeddedChannel ch = new EmbeddedChannel(new ChunkedWriteHandler()); @@ -118,6 +156,7 @@ public class HttpChunkedInputTest { } assertEquals(BYTES.length * inputs.length, read); - assertSame("Last chunk must be DefaultLastHttpContent", LastHttpContent.EMPTY_LAST_CONTENT, lastHttpContent); + assertSame("Last chunk must be LastHttpContent.EMPTY_LAST_CONTENT", + LastHttpContent.EMPTY_LAST_CONTENT, lastHttpContent); } }