relay: fix decoding of websocket frames when there are multiple frames in a single message received (only the first one was decoded)
This commit is contained in:
parent
7bf712d4c9
commit
a6c188ce4f
@ -1,7 +1,7 @@
|
||||
WeeChat ChangeLog
|
||||
=================
|
||||
Sébastien Helleu <flashcode@flashtux.org>
|
||||
v0.4.2-rc2, 2013-09-30
|
||||
v0.4.2-rc2, 2013-10-05
|
||||
|
||||
|
||||
This document lists all changes for each version.
|
||||
@ -119,6 +119,8 @@ Version 0.4.2 (under dev!)
|
||||
buffer per nick
|
||||
* logger: add option "flush" for command /logger
|
||||
* lua: fix interpreter used in API functions (bug #39470)
|
||||
* relay: fix decoding of websocket frames when there are multiple frames in a
|
||||
single message received (only the first one was decoded)
|
||||
* relay: add command "ping" in weechat protocol (task #12689)
|
||||
* relay: fix binding to an IP address (bug #39119)
|
||||
* rmodifier: add option "missing" for command /rmodifier
|
||||
|
@ -262,61 +262,63 @@ relay_websocket_send_http (struct t_relay_client *client,
|
||||
|
||||
int
|
||||
relay_websocket_decode_frame (const unsigned char *buffer,
|
||||
unsigned long long length,
|
||||
unsigned long long buffer_length,
|
||||
unsigned char *decoded,
|
||||
unsigned long long *decoded_length)
|
||||
{
|
||||
unsigned long long i, index, length_frame_size, length_frame;
|
||||
unsigned long long i, index_buffer, length_frame_size, length_frame;
|
||||
|
||||
*decoded_length = 0;
|
||||
index_buffer = 0;
|
||||
|
||||
if (length < 2)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* check if frame is masked: client MUST send a masked frame; if frame is
|
||||
* not masked, we MUST reject it and close the connection (see RFC 6455)
|
||||
*/
|
||||
if (!(buffer[1] & 128))
|
||||
return 0;
|
||||
|
||||
/* decode frame */
|
||||
index = 2;
|
||||
length_frame_size = 1;
|
||||
length_frame = buffer[1] & 127;
|
||||
if ((length_frame == 126) || (length_frame == 127))
|
||||
/* loop to decode all frames in message */
|
||||
while (index_buffer + 2 <= buffer_length)
|
||||
{
|
||||
length_frame_size = (length_frame == 126) ? 2 : 8;
|
||||
if (length < 1 + length_frame_size)
|
||||
/*
|
||||
* check if frame is masked: client MUST send a masked frame; if frame is
|
||||
* not masked, we MUST reject it and close the connection (see RFC 6455)
|
||||
*/
|
||||
if (!(buffer[index_buffer + 1] & 128))
|
||||
return 0;
|
||||
length_frame = 0;
|
||||
for (i = 0; i < length_frame_size; i++)
|
||||
|
||||
/* decode frame */
|
||||
length_frame_size = 1;
|
||||
length_frame = buffer[index_buffer + 1] & 127;
|
||||
index_buffer += 2;
|
||||
if ((length_frame == 126) || (length_frame == 127))
|
||||
{
|
||||
length_frame += (unsigned long long)buffer[index + i] << ((length_frame_size - i - 1) * 8);
|
||||
length_frame_size = (length_frame == 126) ? 2 : 8;
|
||||
if (buffer_length < 1 + length_frame_size)
|
||||
return 0;
|
||||
length_frame = 0;
|
||||
for (i = 0; i < length_frame_size; i++)
|
||||
{
|
||||
length_frame += (unsigned long long)buffer[index_buffer + i] << ((length_frame_size - i - 1) * 8);
|
||||
}
|
||||
index_buffer += length_frame_size;
|
||||
}
|
||||
index += length_frame_size;
|
||||
|
||||
if (buffer_length < 1 + length_frame_size + 4 + length_frame)
|
||||
return 0;
|
||||
|
||||
/* read masks (4 bytes) */
|
||||
int masks[4];
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
masks[i] = (int)((unsigned char)buffer[index_buffer + i]);
|
||||
}
|
||||
index_buffer += 4;
|
||||
|
||||
/* decode data using masks */
|
||||
for (i = 0; i < length_frame; i++)
|
||||
{
|
||||
decoded[*decoded_length + i] = (int)((unsigned char)buffer[index_buffer + i]) ^ masks[i % 4];
|
||||
}
|
||||
decoded[*decoded_length + length_frame] = '\0';
|
||||
*decoded_length += length_frame;
|
||||
index_buffer += length_frame;
|
||||
}
|
||||
|
||||
if (length < 1 + length_frame_size + 4 + length_frame)
|
||||
return 0;
|
||||
|
||||
/* read masks (4 bytes) */
|
||||
int masks[4];
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
masks[i] = (int)((unsigned char)buffer[index + i]);
|
||||
}
|
||||
index += 4;
|
||||
|
||||
/* decode data using masks */
|
||||
for (i = 0; i < length_frame; i++)
|
||||
{
|
||||
decoded[i] = (int)((unsigned char)buffer[index + i]) ^ masks[i % 4];
|
||||
}
|
||||
decoded[length_frame] = '\0';
|
||||
|
||||
*decoded_length = length_frame;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user