[#1893] Fix bug in JdkZlibDecoder which did not let it handle large data

This commit is contained in:
Norman Maurer 2013-10-07 07:31:21 +02:00
parent c0936fc8e7
commit 00f99dbff6
2 changed files with 59 additions and 16 deletions

View File

@ -147,13 +147,20 @@ public class JdkZlibDecoder extends ZlibDecoder {
ByteBuf decompressed = ctx.alloc().heapBuffer(maxOutputLength);
try {
boolean readFooter = false;
byte[] outArray = decompressed.array();
while (!inflater.needsInput()) {
byte[] outArray = decompressed.array();
int outIndex = decompressed.arrayOffset() + decompressed.writerIndex();
int length = outArray.length - outIndex;
int outputLength = inflater.inflate(outArray, outIndex, length);
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);
if (outputLength > 0) {
decompressed.writerIndex(decompressed.writerIndex() + outputLength);
if (crc != null) {

View File

@ -25,12 +25,21 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
public abstract class ZlibTest {
private static final byte[] BYTES_SMALL = new byte[128];
private static final byte[] BYTES_LARGE = new byte[1024 * 1024];
static {
for (int i = 0; i < BYTES_SMALL.length; i++) {
BYTES_SMALL[i] = (byte) i;
}
for (int i = 0; i < BYTES_LARGE.length; i++) {
BYTES_LARGE[i] = (byte) i;
}
}
protected abstract ZlibEncoder createEncoder(ZlibWrapper wrapper);
protected abstract ZlibDecoder createDecoder(ZlibWrapper wrapper);
@ -50,8 +59,8 @@ public abstract class ZlibTest {
buf.release();
}
protected void testCompress(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
ByteBuf data = Unpooled.copiedBuffer("test", CharsetUtil.UTF_8);
private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, byte[] bytes) throws Exception {
ByteBuf data = Unpooled.wrappedBuffer(bytes);
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
chEncoder.writeOutbound(data.copy());
@ -68,42 +77,69 @@ public abstract class ZlibTest {
assertTrue(chDecoderZlib.finish());
ByteBuf buf = (ByteBuf) chDecoderZlib.readInbound();
assertEquals(data, buf);
byte[] decompressed = new byte[bytes.length];
int offset = 0;
for (;;) {
ByteBuf buf = (ByteBuf) chDecoderZlib.readInbound();
if (buf == null) {
break;
}
int length = buf.readableBytes();
buf.readBytes(decompressed, offset, length);
offset += length;
buf.release();
if (offset == decompressed.length) {
break;
}
}
assertArrayEquals(bytes, decompressed);
assertNull(chDecoderZlib.readInbound());
data.release();
buf.release();
}
private void testCompressSmall(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
testCompress0(encoderWrapper, decoderWrapper, BYTES_SMALL);
}
private void testCompressLarge(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
testCompress0(encoderWrapper, decoderWrapper, BYTES_LARGE);
}
@Test
public void testZLIB() throws Exception {
testCompress(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB);
testCompressSmall(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB);
testCompressLarge(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB);
}
@Test
public void testNONE() throws Exception {
testCompress(ZlibWrapper.NONE, ZlibWrapper.NONE);
testCompressSmall(ZlibWrapper.NONE, ZlibWrapper.NONE);
testCompressLarge(ZlibWrapper.NONE, ZlibWrapper.NONE);
}
@Test
public void testGZIP() throws Exception {
testCompress(ZlibWrapper.GZIP, ZlibWrapper.GZIP);
testCompressSmall(ZlibWrapper.GZIP, ZlibWrapper.GZIP);
testCompressLarge(ZlibWrapper.GZIP, ZlibWrapper.GZIP);
}
@Test
public void testZLIB_OR_NONE() throws Exception {
testCompress(ZlibWrapper.NONE, ZlibWrapper.ZLIB_OR_NONE);
testCompressSmall(ZlibWrapper.NONE, ZlibWrapper.ZLIB_OR_NONE);
testCompressLarge(ZlibWrapper.NONE, ZlibWrapper.ZLIB_OR_NONE);
}
@Test
public void testZLIB_OR_NONE2() throws Exception {
testCompress(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB_OR_NONE);
testCompressSmall(ZlibWrapper.ZLIB, ZlibWrapper.ZLIB_OR_NONE);
testCompressLarge(ZlibWrapper.GZIP, ZlibWrapper.ZLIB_OR_NONE);
}
@Test
public void testZLIB_OR_NONE3() throws Exception {
testCompress(ZlibWrapper.GZIP, ZlibWrapper.ZLIB_OR_NONE);
testCompressSmall(ZlibWrapper.GZIP, ZlibWrapper.ZLIB_OR_NONE);
testCompressLarge(ZlibWrapper.GZIP, ZlibWrapper.ZLIB_OR_NONE);
}
private static byte[] gzip(String message) throws IOException {