Allow the user to call slice().retain() or duplicate.retain() in his/her ByteToMessageDecoder.decode(...) method.

Motivation:
At the moment a user can not safetly call slice().retain() or duplicate.retain()in the ByteToMessageDecoder.decode(...) implementation without the risk to see coruption because we may call discardSomeReadBytes() to make room on the buffer once the handling is done.

Modifications:
Check for the refCnt() before call discardSomeReadBytes() and also check before call decode(...) to create a copy if needed.

Result:
The user can safetly call slice().retain() or duplicate.retain() in his/her ByteToMessageDecoder.decode(...) method.
This commit is contained in:
Norman Maurer 2014-04-06 20:49:03 +02:00
parent 4307729ff7
commit 25e0d9de7e

View File

@ -133,7 +133,15 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter {
if (first) {
cumulation = data;
} else {
if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()) {
if (cumulation.writerIndex() > cumulation.maxCapacity() - data.readableBytes()
|| cumulation.refCnt() > 1) {
// Expand cumulation (by replace it) when either there is not more room in the buffer
// or if the refCnt is greater then 1 which may happen when the user use slice().retain() or
// duplicate().retain().
//
// See:
// - https://github.com/netty/netty/issues/2327
// - https://github.com/netty/netty/issues/1764
expandCumulation(ctx, data.readableBytes());
}
cumulation.writeBytes(data);
@ -171,9 +179,14 @@ public abstract class ByteToMessageDecoder extends ChannelHandlerAdapter {
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
if (cumulation != null && !first) {
if (cumulation != null && !first && cumulation.refCnt() == 1) {
// discard some bytes if possible to make more room in the
// buffer
// buffer but only if the refCnt == 1 as otherwise the user may have
// used slice().retain() or duplicate().retain().
//
// See:
// - https://github.com/netty/netty/issues/2327
// - https://github.com/netty/netty/issues/1764
cumulation.discardSomeReadBytes();
}
if (decodeWasNull) {