Fixing 64-bit payload length parsing issue

This commit is contained in:
Joakim Erdfelt 2012-06-26 09:17:04 -07:00
parent d2056f3eb2
commit c439bf3882
3 changed files with 27 additions and 35 deletions

View File

@ -185,9 +185,20 @@ public class BaseFrame
setPayloadLength(this.payload.remaining());
}
public void setPayloadLength(int payloadLength)
public void setPayloadLength(int length)
{
this.payloadLength = payloadLength;
this.payloadLength = length;
}
public void setPayloadLength(long length)
{
// Since we use ByteBuffer so often, having lengths over Integer.MAX_VALUE is really impossible.
if (length > Integer.MAX_VALUE)
{
// OMG! Sanity Check! DO NOT WANT! Won't anyone think of the memory!
throw new IllegalArgumentException("[int-sane!] cannot handle payload lengths larger than " + Integer.MAX_VALUE);
}
this.payloadLength = (int)length;
}
public void setRsv1(boolean rsv1)

View File

@ -46,7 +46,7 @@ public abstract class FrameParser<T extends BaseFrame>
private static final Logger LOG = Log.getLogger(FrameParser.class);
private WebSocketPolicy policy;
private State state = State.PAYLOAD_LEN;
private int length = 0;
private long length = 0;
private int cursor = 0;
public FrameParser(WebSocketPolicy policy)
@ -149,37 +149,18 @@ public abstract class FrameParser<T extends BaseFrame>
if (length == 127)
{
// length 8 bytes (extended payload length)
if (buffer.remaining() >= 4)
{
buffer.getInt(); //toss the first one, first 4 bytes
length = buffer.getInt(); // last 4 bytes for actual length
}
else
{
length = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 4;
break; // continue onto next state
}
length = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 8;
break; // continue onto next state
}
else if (length == 126)
{
// length 2 bytes (extended payload length)
if (buffer.remaining() >= 2)
{
length = buffer.getShort();
if (length == -1)
{
length = 65535;
}
}
else
{
length = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 2;
break; // continue onto next state
}
length = 0;
state = State.PAYLOAD_LEN_BYTES;
cursor = 2;
break; // continue onto next state
}
getFrame().setPayloadLength(length);

View File

@ -112,7 +112,7 @@ public class RFC6455ExamplesParserTest
// 256 bytes binary message in a single unmasked frame
buf.put(new byte[]
{ (byte)0x82, 0x7E });
buf.putShort((short)0x01_00);
buf.putShort((short)0x01_00); // 16 bit size
for (int i = 0; i < dataSize; i++)
{
buf.put((byte)0x44);
@ -134,7 +134,7 @@ public class RFC6455ExamplesParserTest
ByteBufferAssert.assertSize("BinaryFrame.payload",dataSize,bin.getPayload());
ByteBuffer data = bin.getPayload();
for (int i = dataSize; i > 0; i--)
for (long i = dataSize; i > 0; i--)
{
Assert.assertThat("BinaryFrame.data[" + i + "]",data.get(),is((byte)0x44));
}
@ -145,12 +145,12 @@ public class RFC6455ExamplesParserTest
{
int dataSize = 1024 * 64;
ByteBuffer buf = ByteBuffer.allocate(dataSize + 10);
ByteBuffer buf = ByteBuffer.allocate((dataSize + 10));
// Raw bytes as found in RFC 6455, Section 5.7 - Examples
// 64 Kbytes binary message in a single unmasked frame
buf.put(new byte[]
{ (byte)0x82, 0x7F });
buf.putInt(dataSize);
buf.putLong(dataSize); // 64bit size
for (int i = 0; i < dataSize; i++)
{
buf.put((byte)0x77);
@ -172,7 +172,7 @@ public class RFC6455ExamplesParserTest
ByteBufferAssert.assertSize("BinaryFrame.payload",dataSize,bin.getPayload());
ByteBuffer data = bin.getPayload();
for (int i = dataSize; i > 0; i--)
for (long i = dataSize; i > 0; i--)
{
Assert.assertThat("BinaryFrame.data[" + i + "]",data.get(),is((byte)0x77));
}