[#1874] WebSocket08FrameDecoder may leak memory if channel is closed before the full frame was received

This commit is contained in:
Norman Maurer 2013-09-30 20:43:30 +02:00
parent 20d5361403
commit 328f67fdfe

View File

@ -288,9 +288,11 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
// Take the data that we have in this packet // Take the data that we have in this packet
if (framePayload == null) { if (framePayload == null) {
framePayload = payloadBuffer; framePayload = payloadBuffer;
payloadBuffer = null;
} else if (payloadBuffer != null) { } else if (payloadBuffer != null) {
framePayload.writeBytes(payloadBuffer); framePayload.writeBytes(payloadBuffer);
payloadBuffer.release(); payloadBuffer.release();
payloadBuffer = null;
} }
// Unmask data if needed // Unmask data if needed
@ -302,16 +304,19 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
// fragmented // fragmented
if (frameOpcode == OPCODE_PING) { if (frameOpcode == OPCODE_PING) {
out.add(new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new PingWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null;
return; return;
} }
if (frameOpcode == OPCODE_PONG) { if (frameOpcode == OPCODE_PONG) {
out.add(new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new PongWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null;
return; return;
} }
if (frameOpcode == OPCODE_CLOSE) { if (frameOpcode == OPCODE_CLOSE) {
checkCloseFrameBody(ctx, framePayload); checkCloseFrameBody(ctx, framePayload);
receivedClosingHandshake = true; receivedClosingHandshake = true;
out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new CloseWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null;
return; return;
} }
@ -359,12 +364,15 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
// Return the frame // Return the frame
if (frameOpcode == OPCODE_TEXT) { if (frameOpcode == OPCODE_TEXT) {
out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new TextWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null;
return; return;
} else if (frameOpcode == OPCODE_BINARY) { } else if (frameOpcode == OPCODE_BINARY) {
out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, framePayload)); out.add(new BinaryWebSocketFrame(frameFinalFlag, frameRsv, framePayload));
framePayload = null;
return; return;
} else if (frameOpcode == OPCODE_CONT) { } else if (frameOpcode == OPCODE_CONT) {
out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, framePayload, aggregatedText)); out.add(new ContinuationWebSocketFrame(frameFinalFlag, frameRsv, framePayload, aggregatedText));
framePayload = null;
return; return;
} else { } else {
throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: " throw new UnsupportedOperationException("Cannot decode web socket frame with opcode: "
@ -463,4 +471,18 @@ public class WebSocket08FrameDecoder extends ReplayingDecoder<WebSocket08FrameDe
// Restore reader index // Restore reader index
buffer.readerIndex(idx); buffer.readerIndex(idx);
} }
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
// release all not complete frames data to prevent leaks.
// https://github.com/netty/netty/issues/1874
if (framePayload != null) {
framePayload.release();
}
if (payloadBuffer != null) {
payloadBuffer.release();
}
}
} }