From e06cb82c4c1c27273e4811107e5b9ac6a66ef1fb Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Mon, 5 Jun 2017 15:41:34 -0700 Subject: [PATCH] JdkZlibDecoder and JZlibDecoder consistency Motivation: JdkZlibDecoder will allocate a new buffer when the previous buffer is filled with inflated data, but JZlibDecoder will attempt to use the same buffer by resizing. This leads to inconsistent results when these two decoders that are intended to be functionality equivalent. Modifications: - JdkZlibDecoder should attempt to resize and reuse the existing buffer instead of creating multiple buffers Result: Fixes https://github.com/netty/netty/issues/6804 --- .../codec/compression/JZlibDecoder.java | 9 ++++----- .../codec/compression/JdkZlibDecoder.java | 19 +++++-------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java index ad2ae29904..5d23bb8bd6 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/JZlibDecoder.java @@ -107,16 +107,15 @@ public class JZlibDecoder extends ZlibDecoder { z.next_in = array; z.next_in_index = 0; } - int oldNextInIndex = z.next_in_index; + final int oldNextInIndex = z.next_in_index; // Configure output. - int maxOutputLength = inputLength << 1; - ByteBuf decompressed = ctx.alloc().heapBuffer(maxOutputLength); + ByteBuf decompressed = ctx.alloc().heapBuffer(inputLength << 1); try { loop: for (;;) { - z.avail_out = maxOutputLength; - decompressed.ensureWritable(maxOutputLength); + decompressed.ensureWritable(z.avail_in << 1); + z.avail_out = decompressed.writableBytes(); z.next_out = decompressed.array(); z.next_out_index = decompressed.arrayOffset() + decompressed.writerIndex(); int oldNextOutIndex = z.next_out_index; diff --git a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java index 3594685a24..d9b4b914f1 100644 --- a/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java +++ b/codec/src/main/java/io/netty/handler/codec/compression/JdkZlibDecoder.java @@ -167,25 +167,14 @@ public class JdkZlibDecoder extends ZlibDecoder { inflater.setInput(array); } - int maxOutputLength = inflater.getRemaining() << 1; - ByteBuf decompressed = ctx.alloc().heapBuffer(maxOutputLength); + ByteBuf decompressed = ctx.alloc().heapBuffer(inflater.getRemaining() << 1); try { boolean readFooter = false; - byte[] outArray = decompressed.array(); while (!inflater.needsInput()) { + byte[] outArray = decompressed.array(); int writerIndex = decompressed.writerIndex(); int outIndex = decompressed.arrayOffset() + writerIndex; - int length = decompressed.writableBytes(); - - if (length == 0) { - // completely filled the buffer allocate a new one and start to fill it - out.add(decompressed); - decompressed = ctx.alloc().heapBuffer(maxOutputLength); - outArray = decompressed.array(); - continue; - } - - int outputLength = inflater.inflate(outArray, outIndex, length); + int outputLength = inflater.inflate(outArray, outIndex, decompressed.writableBytes()); if (outputLength > 0) { decompressed.writerIndex(writerIndex + outputLength); if (crc != null) { @@ -208,6 +197,8 @@ public class JdkZlibDecoder extends ZlibDecoder { readFooter = true; } break; + } else { + decompressed.ensureWritable(inflater.getRemaining() << 1); } }