Program: 80588
Project: 80588
Buggy source:
/** 
 * Decode the in buffer according to the Section 5.2. RFC 6455. If there are multiple websocket dataframes in the buffer, this will parse all and return one complete decoded buffer. <pre> 0                   1                   2                   3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len |    Extended payload length    | |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           | |N|V|V|V|       |S|             |   (if payload len==126/127)   | | |1|2|3|       |K|             |                               | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + |     Extended payload length continued, if payload len == 127  | + - - - - - - - - - - - - - - - +-------------------------------+ |                               |Masking-key, if MASK set to 1  | +-------------------------------+-------------------------------+ | Masking-key (continued)       |          Payload Data         | +-------------------------------- - - - - - - - - - - - - - - - + :                     Payload Data continued ...                : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |                     Payload Data continued ...                | +---------------------------------------------------------------+ </pre>
 * @param in
 * @param session
 */
public static void decodeIncommingData(IoBuffer in,IoSession session){
  log.trace("String_Node_Str",in);
  DecoderState decoderState=(DecoderState)session.getAttribute(DECODER_STATE_KEY);
  if (decoderState.fin == Byte.MIN_VALUE) {
    byte frameInfo=in.get();
    decoderState.fin=(byte)((frameInfo >>> 7) & 1);
    log.trace("String_Node_Str",decoderState.fin);
    decoderState.opCode=(byte)(frameInfo & 0x0f);
    log.trace("String_Node_Str",decoderState.opCode);
  }
  if (decoderState.mask == Byte.MIN_VALUE) {
    byte frameInfo2=in.get();
    decoderState.mask=(byte)((frameInfo2 >>> 7) & 1);
    log.trace("String_Node_Str",decoderState.mask);
    decoderState.frameLen=(frameInfo2 & (byte)0x7F);
    log.trace("String_Node_Str",decoderState.frameLen);
    if (decoderState.frameLen == 126) {
      decoderState.frameLen=in.getShort();
      log.trace("String_Node_Str",decoderState.frameLen);
    }
 else     if (decoderState.frameLen == 127) {
      long extendedLen=in.getLong();
      if (extendedLen >= Integer.MAX_VALUE) {
        log.error("String_Node_Str",extendedLen);
      }
 else {
        decoderState.frameLen=(int)extendedLen;
      }
      log.trace("String_Node_Str",decoderState.frameLen);
    }
  }
  if (decoderState.frameLen + (decoderState.mask == 1 ? 4 : 0) > in.remaining()) {
    log.info("String_Node_Str");
  }
 else {
    if (decoderState.mask == 1) {
      byte maskKey[]=new byte[4];
      for (int i=0; i < 4; i++) {
        maskKey[i]=in.get();
      }
      decoderState.payload=new byte[decoderState.frameLen];
      for (int i=0; i < decoderState.frameLen; i++) {
        byte maskedByte=in.get();
        decoderState.payload[i]=(byte)(maskedByte ^ maskKey[i % 4]);
      }
    }
 else {
      decoderState.payload=new byte[decoderState.frameLen];
      in.get(decoderState.payload);
    }
    if (decoderState.fin == 0) {
      IoBuffer fragments=(IoBuffer)session.getAttribute(DECODED_MESSAGE_FRAGMENTS_KEY);
      if (fragments == null) {
        fragments=IoBuffer.allocate(decoderState.frameLen);
        fragments.setAutoExpand(true);
        session.setAttribute(DECODED_MESSAGE_FRAGMENTS_KEY,fragments);
        MessageType messageType=MessageType.CLOSE;
switch (decoderState.opCode) {
case 0:
          messageType=MessageType.CONTINUATION;
        break;
case 1:
      messageType=MessageType.TEXT;
    break;
case 2:
  messageType=MessageType.BINARY;
break;
case 9:
messageType=MessageType.PING;
break;
case 0xa:
messageType=MessageType.PONG;
break;
}
session.setAttribute(DECODED_MESSAGE_TYPE_KEY,messageType);
}
fragments.put(decoderState.payload);
session.removeAttribute(DECODER_STATE_KEY);
}
 else {
WSMessage message=new WSMessage();
MessageType messageType=(MessageType)session.getAttribute(DECODED_MESSAGE_TYPE_KEY);
if (messageType == null) {
switch (decoderState.opCode) {
case 0:
messageType=MessageType.CONTINUATION;
break;
case 1:
messageType=MessageType.TEXT;
break;
case 2:
messageType=MessageType.BINARY;
break;
case 9:
messageType=MessageType.PING;
break;
case 0xa:
messageType=MessageType.PONG;
break;
case 8:
messageType=MessageType.CLOSE;
break;
default :
log.info("String_Node_Str",decoderState.opCode);
}
}
message.setMessageType(messageType);
IoBuffer fragments=(IoBuffer)session.removeAttribute(DECODED_MESSAGE_FRAGMENTS_KEY);
if (fragments != null) {
fragments.put(decoderState.payload);
fragments.flip();
message.setPayload(fragments);
}
 else {
message.addPayload(decoderState.payload);
}
session.setAttribute(DECODED_MESSAGE_KEY,message);
session.removeAttribute(DECODER_STATE_KEY);
session.removeAttribute(DECODED_MESSAGE_TYPE_KEY);
}
}
}

Fixed version (ground truth):
/** 
 * Decode the in buffer according to the Section 5.2. RFC 6455. If there are multiple websocket dataframes in the buffer, this will parse all and return one complete decoded buffer. <pre> 0                   1                   2                   3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-------+-+-------------+-------------------------------+ |F|R|R|R| opcode|M| Payload len |    Extended payload length    | |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           | |N|V|V|V|       |S|             |   (if payload len==126/127)   | | |1|2|3|       |K|             |                               | +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + |     Extended payload length continued, if payload len == 127  | + - - - - - - - - - - - - - - - +-------------------------------+ |                               |Masking-key, if MASK set to 1  | +-------------------------------+-------------------------------+ | Masking-key (continued)       |          Payload Data         | +-------------------------------- - - - - - - - - - - - - - - - + :                     Payload Data continued ...                : + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |                     Payload Data continued ...                | +---------------------------------------------------------------+ </pre>
 * @param in
 * @param session
 */
public static void decodeIncommingData(IoBuffer in,IoSession session){
  log.trace("String_Node_Str",in);
  DecoderState decoderState=(DecoderState)session.getAttribute(DECODER_STATE_KEY);
  if (decoderState.fin == Byte.MIN_VALUE) {
    byte frameInfo=in.get();
    decoderState.fin=(byte)((frameInfo >>> 7) & 1);
    log.trace("String_Node_Str",decoderState.fin);
    decoderState.opCode=(byte)(frameInfo & 0x0f);
    log.trace("String_Node_Str",decoderState.opCode);
  }
  if (decoderState.mask == Byte.MIN_VALUE) {
    byte frameInfo2=in.get();
    decoderState.mask=(byte)((frameInfo2 >>> 7) & 1);
    log.trace("String_Node_Str",decoderState.mask);
    decoderState.frameLen=(frameInfo2 & (byte)0x7F);
    log.trace("String_Node_Str",decoderState.frameLen);
    if (decoderState.frameLen == 126) {
      decoderState.frameLen=in.getUnsignedShort();
      log.trace("String_Node_Str",decoderState.frameLen);
    }
 else     if (decoderState.frameLen == 127) {
      long extendedLen=in.getLong();
      if (extendedLen >= Integer.MAX_VALUE) {
        log.error("String_Node_Str",extendedLen);
      }
 else {
        decoderState.frameLen=(int)extendedLen;
      }
      log.trace("String_Node_Str",decoderState.frameLen);
    }
  }
  if (decoderState.frameLen + (decoderState.mask == 1 ? 4 : 0) > in.remaining()) {
    log.info("String_Node_Str");
  }
 else {
    if (decoderState.mask == 1) {
      byte maskKey[]=new byte[4];
      for (int i=0; i < 4; i++) {
        maskKey[i]=in.get();
      }
      decoderState.payload=new byte[decoderState.frameLen];
      for (int i=0; i < decoderState.frameLen; i++) {
        byte maskedByte=in.get();
        decoderState.payload[i]=(byte)(maskedByte ^ maskKey[i % 4]);
      }
    }
 else {
      decoderState.payload=new byte[decoderState.frameLen];
      in.get(decoderState.payload);
    }
    if (decoderState.fin == 0) {
      IoBuffer fragments=(IoBuffer)session.getAttribute(DECODED_MESSAGE_FRAGMENTS_KEY);
      if (fragments == null) {
        fragments=IoBuffer.allocate(decoderState.frameLen);
        fragments.setAutoExpand(true);
        session.setAttribute(DECODED_MESSAGE_FRAGMENTS_KEY,fragments);
        MessageType messageType=MessageType.CLOSE;
switch (decoderState.opCode) {
case 0:
          messageType=MessageType.CONTINUATION;
        break;
case 1:
      messageType=MessageType.TEXT;
    break;
case 2:
  messageType=MessageType.BINARY;
break;
case 9:
messageType=MessageType.PING;
break;
case 0xa:
messageType=MessageType.PONG;
break;
}
session.setAttribute(DECODED_MESSAGE_TYPE_KEY,messageType);
}
fragments.put(decoderState.payload);
session.removeAttribute(DECODER_STATE_KEY);
}
 else {
WSMessage message=new WSMessage();
MessageType messageType=(MessageType)session.getAttribute(DECODED_MESSAGE_TYPE_KEY);
if (messageType == null) {
switch (decoderState.opCode) {
case 0:
messageType=MessageType.CONTINUATION;
break;
case 1:
messageType=MessageType.TEXT;
break;
case 2:
messageType=MessageType.BINARY;
break;
case 9:
messageType=MessageType.PING;
break;
case 0xa:
messageType=MessageType.PONG;
break;
case 8:
messageType=MessageType.CLOSE;
break;
default :
log.info("String_Node_Str",decoderState.opCode);
}
}
message.setMessageType(messageType);
IoBuffer fragments=(IoBuffer)session.removeAttribute(DECODED_MESSAGE_FRAGMENTS_KEY);
if (fragments != null) {
fragments.put(decoderState.payload);
fragments.flip();
message.setPayload(fragments);
}
 else {
message.addPayload(decoderState.payload);
}
session.setAttribute(DECODED_MESSAGE_KEY,message);
session.removeAttribute(DECODER_STATE_KEY);
session.removeAttribute(DECODED_MESSAGE_TYPE_KEY);
}
}
}