Fix buffer leak in test which was introduced while implement ZLIB_OR_NONE support. Related to [#2269]
This commit is contained in:
parent
2b47058644
commit
835c446f5f
@ -385,7 +385,7 @@ public class JdkZlibDecoder extends ZlibDecoder {
|
|||||||
* You can lookup the details in the ZLIB RFC:
|
* You can lookup the details in the ZLIB RFC:
|
||||||
* <a href="http://tools.ietf.org/html/rfc1950#section-2.2">RFC 1950</a>.
|
* <a href="http://tools.ietf.org/html/rfc1950#section-2.2">RFC 1950</a>.
|
||||||
*/
|
*/
|
||||||
private boolean looksLikeZlib(short cmf_flg) {
|
private static boolean looksLikeZlib(short cmf_flg) {
|
||||||
return (cmf_flg & 0x7800) == 0x7800 &&
|
return (cmf_flg & 0x7800) == 0x7800 &&
|
||||||
cmf_flg % 31 == 0;
|
cmf_flg % 31 == 0;
|
||||||
}
|
}
|
||||||
|
@ -48,91 +48,109 @@ public abstract class ZlibTest {
|
|||||||
ByteBuf deflatedData = Unpooled.wrappedBuffer(gzip("message"));
|
ByteBuf deflatedData = Unpooled.wrappedBuffer(gzip("message"));
|
||||||
|
|
||||||
EmbeddedChannel chDecoderGZip = new EmbeddedChannel(createDecoder(ZlibWrapper.GZIP));
|
EmbeddedChannel chDecoderGZip = new EmbeddedChannel(createDecoder(ZlibWrapper.GZIP));
|
||||||
chDecoderGZip.writeInbound(deflatedData.copy());
|
try {
|
||||||
assertTrue(chDecoderGZip.finish());
|
chDecoderGZip.writeInbound(deflatedData.copy());
|
||||||
ByteBuf buf = (ByteBuf) chDecoderGZip.readInbound();
|
assertTrue(chDecoderGZip.finish());
|
||||||
assertEquals(buf, data);
|
ByteBuf buf = (ByteBuf) chDecoderGZip.readInbound();
|
||||||
assertNull(chDecoderGZip.readInbound());
|
assertEquals(buf, data);
|
||||||
data.release();
|
assertNull(chDecoderGZip.readInbound());
|
||||||
deflatedData.release();
|
data.release();
|
||||||
buf.release();
|
deflatedData.release();
|
||||||
|
buf.release();
|
||||||
|
} finally {
|
||||||
|
// close channel to prevent any leak even on exception
|
||||||
|
chDecoderGZip.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, ByteBuf data) throws Exception {
|
private void testCompress0(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper, ByteBuf data) throws Exception {
|
||||||
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
|
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
|
||||||
|
|
||||||
chEncoder.writeOutbound(data.copy());
|
|
||||||
chEncoder.flush();
|
|
||||||
|
|
||||||
EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
|
EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
|
||||||
for (;;) {
|
|
||||||
ByteBuf deflatedData = (ByteBuf) chEncoder.readOutbound();
|
|
||||||
if (deflatedData == null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
chDecoderZlib.writeInbound(deflatedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] decompressed = new byte[data.readableBytes()];
|
try {
|
||||||
int offset = 0;
|
chEncoder.writeOutbound(data.copy());
|
||||||
for (;;) {
|
chEncoder.flush();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertEquals(data, Unpooled.wrappedBuffer(decompressed));
|
|
||||||
assertNull(chDecoderZlib.readInbound());
|
|
||||||
|
|
||||||
// Closing an encoder channel will generate a footer.
|
for (;;) {
|
||||||
assertTrue(chEncoder.finish());
|
ByteBuf deflatedData = (ByteBuf) chEncoder.readOutbound();
|
||||||
for (;;) {
|
if (deflatedData == null) {
|
||||||
Object msg = chEncoder.readOutbound();
|
break;
|
||||||
if (msg == null) {
|
}
|
||||||
break;
|
chDecoderZlib.writeInbound(deflatedData);
|
||||||
}
|
}
|
||||||
ReferenceCountUtil.release(msg);
|
|
||||||
}
|
|
||||||
// But, the footer will be decoded into nothing. It's only for validation.
|
|
||||||
assertFalse(chDecoderZlib.finish());
|
|
||||||
|
|
||||||
data.release();
|
byte[] decompressed = new byte[data.readableBytes()];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(data, Unpooled.wrappedBuffer(decompressed));
|
||||||
|
assertNull(chDecoderZlib.readInbound());
|
||||||
|
|
||||||
|
// Closing an encoder channel will generate a footer.
|
||||||
|
assertTrue(chEncoder.finish());
|
||||||
|
for (;;) {
|
||||||
|
Object msg = chEncoder.readOutbound();
|
||||||
|
if (msg == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ReferenceCountUtil.release(msg);
|
||||||
|
}
|
||||||
|
// But, the footer will be decoded into nothing. It's only for validation.
|
||||||
|
assertFalse(chDecoderZlib.finish());
|
||||||
|
|
||||||
|
data.release();
|
||||||
|
} finally {
|
||||||
|
// close channels in all cases to guard against leak when exception was thrown
|
||||||
|
chEncoder.close();
|
||||||
|
chDecoderZlib.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testCompressNone(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
|
private void testCompressNone(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
|
||||||
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
|
EmbeddedChannel chEncoder = new EmbeddedChannel(createEncoder(encoderWrapper));
|
||||||
|
|
||||||
// Closing an encoder channel without writing anything should generate both header and footer.
|
|
||||||
assertTrue(chEncoder.finish());
|
|
||||||
|
|
||||||
EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
|
EmbeddedChannel chDecoderZlib = new EmbeddedChannel(createDecoder(decoderWrapper));
|
||||||
for (;;) {
|
try {
|
||||||
ByteBuf deflatedData = (ByteBuf) chEncoder.readOutbound();
|
// Closing an encoder channel without writing anything should generate both header and footer.
|
||||||
if (deflatedData == null) {
|
assertTrue(chEncoder.finish());
|
||||||
break;
|
|
||||||
}
|
|
||||||
chDecoderZlib.writeInbound(deflatedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decoder should not generate anything at all.
|
for (;;) {
|
||||||
for (;;) {
|
ByteBuf deflatedData = (ByteBuf) chEncoder.readOutbound();
|
||||||
ByteBuf buf = (ByteBuf) chDecoderZlib.readInbound();
|
if (deflatedData == null) {
|
||||||
if (buf == null) {
|
break;
|
||||||
break;
|
}
|
||||||
|
chDecoderZlib.writeInbound(deflatedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.release();
|
// Decoder should not generate anything at all.
|
||||||
fail("should decode nothing");
|
boolean decoded = false;
|
||||||
}
|
for (;;) {
|
||||||
|
ByteBuf buf = (ByteBuf) chDecoderZlib.readInbound();
|
||||||
|
if (buf == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
assertFalse(chDecoderZlib.finish());
|
buf.release();
|
||||||
|
decoded = true;
|
||||||
|
}
|
||||||
|
assertFalse("should decode nothing", decoded);
|
||||||
|
|
||||||
|
assertFalse(chDecoderZlib.finish());
|
||||||
|
} finally {
|
||||||
|
// close channels in all cases to guard against leak when exception was thrown
|
||||||
|
chEncoder.close();
|
||||||
|
chDecoderZlib.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testCompressSmall(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
|
private void testCompressSmall(ZlibWrapper encoderWrapper, ZlibWrapper decoderWrapper) throws Exception {
|
||||||
|
Loading…
Reference in New Issue
Block a user