use of io.netty.handler.codec.CorruptedFrameException in project netty by netty.
the class DefaultDnsRecordDecoder method decodeName.
/**
* Retrieves a domain name given a buffer containing a DNS packet. If the
* name contains a pointer, the position of the buffer will be set to
* directly after the pointer's index after the name has been read.
*
* @param in the byte buffer containing the DNS packet
* @return the domain name for an entry
*/
public static String decodeName(ByteBuf in) {
int position = -1;
int checked = 0;
final int end = in.writerIndex();
final int readable = in.readableBytes();
// - https://www.ietf.org/rfc/rfc1035.txt , Section 3.1
if (readable == 0) {
return ROOT;
}
final StringBuilder name = new StringBuilder(readable << 1);
while (in.isReadable()) {
final int len = in.readUnsignedByte();
final boolean pointer = (len & 0xc0) == 0xc0;
if (pointer) {
if (position == -1) {
position = in.readerIndex() + 1;
}
if (!in.isReadable()) {
throw new CorruptedFrameException("truncated pointer in a name");
}
final int next = (len & 0x3f) << 8 | in.readUnsignedByte();
if (next >= end) {
throw new CorruptedFrameException("name has an out-of-range pointer");
}
in.readerIndex(next);
// check for loops
checked += 2;
if (checked >= end) {
throw new CorruptedFrameException("name contains a loop.");
}
} else if (len != 0) {
if (!in.isReadable(len)) {
throw new CorruptedFrameException("truncated label in a name");
}
name.append(in.toString(in.readerIndex(), len, CharsetUtil.UTF_8)).append('.');
in.skipBytes(len);
} else {
// len == 0
break;
}
}
if (position != -1) {
in.readerIndex(position);
}
if (name.length() == 0) {
return ROOT;
}
if (name.charAt(name.length() - 1) != '.') {
name.append('.');
}
return name.toString();
}
use of io.netty.handler.codec.CorruptedFrameException in project drill by apache.
the class RpcDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
if (!ctx.channel().isOpen()) {
return;
}
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("Inbound rpc message received.");
}
// now, we know the entire message is in the buffer and the buffer is constrained to this message. Additionally,
// this process should avoid reading beyond the end of this buffer so we inform the ByteBufInputStream to throw an
// exception if be go beyond readable bytes (as opposed to blocking).
final ByteBufInputStream is = new ByteBufInputStream(buffer, buffer.readableBytes());
// read the rpc header, saved in delimited format.
checkTag(is, RpcEncoder.HEADER_TAG);
final RpcHeader header = RpcHeader.parseDelimitedFrom(is);
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug(" post header read index {}", buffer.readerIndex());
}
// read the protobuf body into a buffer.
checkTag(is, RpcEncoder.PROTOBUF_BODY_TAG);
final int pBodyLength = readRawVarint32(is);
final ByteBuf pBody = buffer.slice(buffer.readerIndex(), pBodyLength);
buffer.skipBytes(pBodyLength);
pBody.retain(1);
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("Read protobuf body of length {} into buffer {}.", pBodyLength, pBody);
}
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("post protobufbody read index {}", buffer.readerIndex());
}
ByteBuf dBody = null;
int dBodyLength = 0;
// read the data body.
if (buffer.readableBytes() > 0) {
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("Reading raw body, buffer has {} bytes available, is available {}.", buffer.readableBytes(), is.available());
}
checkTag(is, RpcEncoder.RAW_BODY_TAG);
dBodyLength = readRawVarint32(is);
if (buffer.readableBytes() != dBodyLength) {
throw new CorruptedFrameException(String.format("Expected to receive a raw body of %d bytes but received a buffer with %d bytes.", dBodyLength, buffer.readableBytes()));
}
dBody = buffer.slice();
dBody.retain(1);
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("Read raw body of {}", dBody);
}
} else {
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug("No need to read raw body, no readable bytes left.");
}
}
// return the rpc message.
InboundRpcMessage m = new InboundRpcMessage(header.getMode(), header.getRpcType(), header.getCoordinationId(), pBody, dBody);
// move the reader index forward so the next rpc call won't try to work with it.
buffer.skipBytes(dBodyLength);
messageCounter.incrementAndGet();
if (RpcConstants.SOME_DEBUGGING) {
logger.debug("Inbound Rpc Message Decoded {}.", m);
}
out.add(m);
}
use of io.netty.handler.codec.CorruptedFrameException in project netty by netty.
the class JsonObjectDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (state == ST_CORRUPTED) {
in.skipBytes(in.readableBytes());
return;
}
// index of next byte to process.
int idx = this.idx;
int wrtIdx = in.writerIndex();
if (wrtIdx > maxObjectLength) {
// buffer size exceeded maxObjectLength; discarding the complete buffer.
in.skipBytes(in.readableBytes());
reset();
throw new TooLongFrameException("object length exceeds " + maxObjectLength + ": " + wrtIdx + " bytes discarded");
}
for (; /* use current idx */
idx < wrtIdx; idx++) {
byte c = in.getByte(idx);
if (state == ST_DECODING_NORMAL) {
decodeByte(c, in, idx);
// that the JSON object/array is complete.
if (openBraces == 0) {
ByteBuf json = extractObject(ctx, in, in.readerIndex(), idx + 1 - in.readerIndex());
if (json != null) {
out.add(json);
}
// The JSON object/array was extracted => discard the bytes from
// the input buffer.
in.readerIndex(idx + 1);
// Reset the object state to get ready for the next JSON object/text
// coming along the byte stream.
reset();
}
} else if (state == ST_DECODING_ARRAY_STREAM) {
decodeByte(c, in, idx);
if (!insideString && (openBraces == 1 && c == ',' || openBraces == 0 && c == ']')) {
// because the byte at position idx is not a whitespace.
for (int i = in.readerIndex(); Character.isWhitespace(in.getByte(i)); i++) {
in.skipBytes(1);
}
// skip trailing spaces.
int idxNoSpaces = idx - 1;
while (idxNoSpaces >= in.readerIndex() && Character.isWhitespace(in.getByte(idxNoSpaces))) {
idxNoSpaces--;
}
ByteBuf json = extractObject(ctx, in, in.readerIndex(), idxNoSpaces + 1 - in.readerIndex());
if (json != null) {
out.add(json);
}
in.readerIndex(idx + 1);
if (c == ']') {
reset();
}
}
// JSON object/array detected. Accumulate bytes until all braces/brackets are closed.
} else if (c == '{' || c == '[') {
initDecoding(c);
if (state == ST_DECODING_ARRAY_STREAM) {
// Discard the array bracket
in.skipBytes(1);
}
// Discard leading spaces in front of a JSON object/array.
} else if (Character.isWhitespace(c)) {
in.skipBytes(1);
} else {
state = ST_CORRUPTED;
throw new CorruptedFrameException("invalid JSON received at byte position " + idx + ": " + ByteBufUtil.hexDump(in));
}
}
if (in.readableBytes() == 0) {
this.idx = 0;
} else {
this.idx = idx;
}
}
use of io.netty.handler.codec.CorruptedFrameException in project netty by netty.
the class BigIntegerDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
// Wait until the length prefix is available.
if (in.readableBytes() < 5) {
return;
}
in.markReaderIndex();
// Check the magic number.
int magicNumber = in.readUnsignedByte();
if (magicNumber != 'F') {
in.resetReaderIndex();
throw new CorruptedFrameException("Invalid magic number: " + magicNumber);
}
// Wait until the whole data is available.
int dataLength = in.readInt();
if (in.readableBytes() < dataLength) {
in.resetReaderIndex();
return;
}
// Convert the received data into a new BigInteger.
byte[] decoded = new byte[dataLength];
in.readBytes(decoded);
out.add(new BigInteger(decoded));
}
use of io.netty.handler.codec.CorruptedFrameException in project drill by apache.
the class ProtobufLengthDecoder method decode.
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!ctx.channel().isOpen()) {
if (in.readableBytes() > 0) {
logger.info("Channel is closed, discarding remaining {} byte(s) in buffer.", in.readableBytes());
}
in.skipBytes(in.readableBytes());
return;
}
in.markReaderIndex();
final byte[] buf = new byte[5];
for (int i = 0; i < buf.length; i++) {
if (!in.isReadable()) {
in.resetReaderIndex();
return;
}
buf[i] = in.readByte();
if (buf[i] >= 0) {
int length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32();
if (length < 0) {
throw new CorruptedFrameException("negative length: " + length);
}
if (length == 0) {
throw new CorruptedFrameException("Received a message of length 0.");
}
if (in.readableBytes() < length) {
in.resetReaderIndex();
return;
} else {
// need to make buffer copy, otherwise netty will try to refill this buffer if we move the readerIndex forward...
// TODO: Can we avoid this copy?
ByteBuf outBuf;
try {
outBuf = allocator.buffer(length);
} catch (OutOfMemoryException e) {
logger.warn("Failure allocating buffer on incoming stream due to memory limits. Current Allocation: {}.", allocator.getAllocatedMemory());
in.resetReaderIndex();
outOfMemoryHandler.handle();
return;
}
outBuf.writeBytes(in, in.readerIndex(), length);
in.skipBytes(length);
if (RpcConstants.EXTRA_DEBUGGING) {
logger.debug(String.format("ReaderIndex is %d after length header of %d bytes and frame body of length %d bytes.", in.readerIndex(), i + 1, length));
}
out.add(outBuf);
return;
}
}
}
// Couldn't find the byte whose MSB is off.
throw new CorruptedFrameException("length wider than 32-bit");
}
Aggregations