[#3967] Guard against NPE in PendingWriteQueue

Motivation:

If the Channel is already closed when the PendingWriteQueue is created it will generate a NPE when add or remove is called later.

Modifications:

Add null checks to guard against NPE.

Result:

No more NPE possible.
This commit is contained in:
Norman Maurer 2015-07-09 22:48:10 +02:00
parent ef195348b5
commit 1be2173596
2 changed files with 27 additions and 2 deletions

View File

@ -87,7 +87,12 @@ public final class PendingWriteQueue {
tail = write; tail = write;
} }
size ++; size ++;
buffer.incrementPendingOutboundBytes(write.size); // We need to guard against null as channel.unsafe().outboundBuffer() may returned null
// if the channel was already closed when constructing the PendingWriteQueue.
// See https://github.com/netty/netty/issues/3967
if (buffer != null) {
buffer.incrementPendingOutboundBytes(write.size);
}
} }
/** /**
@ -245,7 +250,12 @@ public final class PendingWriteQueue {
} }
write.recycle(); write.recycle();
buffer.decrementPendingOutboundBytes(writeSize); // We need to guard against null as channel.unsafe().outboundBuffer() may returned null
// if the channel was already closed when constructing the PendingWriteQueue.
// See https://github.com/netty/netty/issues/3967
if (buffer != null) {
buffer.decrementPendingOutboundBytes(writeSize);
}
} }
private static void safeFail(ChannelPromise promise, Throwable cause) { private static void safeFail(ChannelPromise promise, Throwable cause) {

View File

@ -245,6 +245,21 @@ public class PendingWriteQueueTest {
assertNull(channel.readInbound()); assertNull(channel.readInbound());
} }
// See https://github.com/netty/netty/issues/3967
@Test
public void testCloseChannelOnCreation() {
EmbeddedChannel channel = new EmbeddedChannel();
channel.close().syncUninterruptibly();
final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext());
IllegalStateException ex = new IllegalStateException();
ChannelPromise promise = channel.newPromise();
queue.add(1L, promise);
queue.removeAndFailAll(ex);
assertSame(ex, promise.cause());
}
private static class TestHandler extends ChannelDuplexHandler { private static class TestHandler extends ChannelDuplexHandler {
protected PendingWriteQueue queue; protected PendingWriteQueue queue;
private int expectedSize; private int expectedSize;