diff --git a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java index f845e74495..3e922be90b 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/Bzip2Decoder.java @@ -276,17 +276,26 @@ public class Bzip2Decoder extends ByteToMessageDecoder { if (!decoded) { return; } - int blockLength = blockDecompressor.blockLength(); - ByteBuf uncompressed = ctx.alloc().buffer(blockLength); - int uncByte; - while ((uncByte = blockDecompressor.read()) >= 0) { - uncompressed.writeByte(uncByte); + + final int blockLength = blockDecompressor.blockLength(); + final ByteBuf uncompressed = ctx.alloc().buffer(blockLength); + boolean success = false; + try { + int uncByte; + while ((uncByte = blockDecompressor.read()) >= 0) { + uncompressed.writeByte(uncByte); + } + + int currentBlockCRC = blockDecompressor.checkCRC(); + streamCRC = (streamCRC << 1 | streamCRC >>> 31) ^ currentBlockCRC; + + out.add(uncompressed); + success = true; + } finally { + if (!success) { + uncompressed.release(); + } } - - int currentBlockCRC = blockDecompressor.checkCRC(); - streamCRC = (streamCRC << 1 | streamCRC >>> 31) ^ currentBlockCRC; - - out.add(uncompressed); currentState = State.INIT_BLOCK; break; case EOF: diff --git a/codec/src/test/java/io/netty/handler/codec/compression/Bzip2DecoderTest.java b/codec/src/test/java/io/netty/handler/codec/compression/Bzip2DecoderTest.java index 0ad19b95ee..58812f077a 100644 --- a/codec/src/test/java/io/netty/handler/codec/compression/Bzip2DecoderTest.java +++ b/codec/src/test/java/io/netty/handler/codec/compression/Bzip2DecoderTest.java @@ -119,7 +119,18 @@ public class Bzip2DecoderTest { 0x4E, 0x14, 0x24, 0x1D, (byte) 0xDD, (byte) 0xF2, (byte) 0xB0, 0x00 }; ByteBuf in = Unpooled.wrappedBuffer(data); - channel.writeInbound(in); + try { + channel.writeInbound(in); + } finally { + for (;;) { + ByteBuf inflated = channel.readInbound(); + if (inflated == null) { + break; + } + inflated.release(); + } + channel.finish(); + } } @Test