Fixed infinite loop in ProtobufVarint32FrameDecoder when too large varint length is received
This commit is contained in:
parent
ab0facdee5
commit
674af6ae12
|
@ -18,6 +18,7 @@ package org.jboss.netty.handler.codec.protobuf;
|
||||||
import org.jboss.netty.buffer.ChannelBuffer;
|
import org.jboss.netty.buffer.ChannelBuffer;
|
||||||
import org.jboss.netty.channel.Channel;
|
import org.jboss.netty.channel.Channel;
|
||||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||||
|
import org.jboss.netty.handler.codec.frame.CorruptedFrameException;
|
||||||
import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
import org.jboss.netty.handler.codec.frame.FrameDecoder;
|
||||||
|
|
||||||
import com.google.protobuf.CodedInputStream;
|
import com.google.protobuf.CodedInputStream;
|
||||||
|
@ -45,7 +46,8 @@ import com.google.protobuf.CodedInputStream;
|
||||||
*/
|
*/
|
||||||
public class ProtobufVarint32FrameDecoder extends FrameDecoder {
|
public class ProtobufVarint32FrameDecoder extends FrameDecoder {
|
||||||
|
|
||||||
// TODO maxFrameLength + safe skip (just like LengthFieldBasedFrameDecoder)
|
// TODO maxFrameLength + safe skip + fail-fast option
|
||||||
|
// (just like LengthFieldBasedFrameDecoder)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
@ -57,24 +59,30 @@ public class ProtobufVarint32FrameDecoder extends FrameDecoder {
|
||||||
@Override
|
@Override
|
||||||
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
|
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
|
||||||
buffer.markReaderIndex();
|
buffer.markReaderIndex();
|
||||||
byte[] buf = new byte[5];
|
final byte[] buf = new byte[5];
|
||||||
for (int i = 0; i < 5; i ++) {
|
for (int i = 0; i < buf.length; i ++) {
|
||||||
if (!buffer.readable()) {
|
if (!buffer.readable()) {
|
||||||
break;
|
buffer.resetReaderIndex();
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[i] = buffer.readByte();
|
buf[i] = buffer.readByte();
|
||||||
if (buf[i] >= 0) {
|
if (buf[i] >= 0) {
|
||||||
int messageSize = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32();
|
int length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32();
|
||||||
if (buffer.readableBytes() < messageSize) {
|
if (length < 0) {
|
||||||
break;
|
throw new CorruptedFrameException("negative length: " + length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.readBytes(messageSize);
|
if (buffer.readableBytes() < length) {
|
||||||
|
buffer.resetReaderIndex();
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return buffer.readBytes(length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.resetReaderIndex();
|
// Couldn't find the byte whose MSB is off.
|
||||||
return null;
|
throw new CorruptedFrameException("length larger than 32-bit");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user