From f7811b0ae206eed9d7c5697466d7da202f0212cc Mon Sep 17 00:00:00 2001 From: Sebastien Helleu Date: Tue, 12 Feb 2013 14:14:40 +0100 Subject: [PATCH] relay: fix crash when decoding a websocket frame --- src/plugins/relay/relay-client.c | 13 +++++++++---- src/plugins/relay/relay-websocket.c | 7 ++++++- src/plugins/relay/relay-websocket.h | 5 +++-- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c index d91b2e4ef..9ca857878 100644 --- a/src/plugins/relay/relay-client.c +++ b/src/plugins/relay/relay-client.c @@ -391,9 +391,10 @@ int relay_client_recv_cb (void *arg_client, int fd) { struct t_relay_client *client; - static char buffer[4096], decoded[4096]; + static char buffer[4096], decoded[4096 + 1]; const char *ptr_buffer; - int num_read; + int num_read, rc; + unsigned long long decoded_length; /* make C compiler happy */ (void) fd; @@ -443,8 +444,11 @@ relay_client_recv_cb (void *arg_client, int fd) if (client->websocket == 2) { /* websocket used, decode message */ - if (!relay_websocket_decode_frame ((unsigned char *)buffer, num_read, - (unsigned char *)decoded)) + rc = relay_websocket_decode_frame ((unsigned char *)buffer, + (unsigned long long)num_read, + (unsigned char *)decoded, + &decoded_length); + if (!rc || (decoded_length == 0)) { /* error when decoding frame: close connection */ weechat_printf_tags (NULL, "relay_client", @@ -458,6 +462,7 @@ relay_client_recv_cb (void *arg_client, int fd) return WEECHAT_RC_OK; } ptr_buffer = decoded; + num_read = (int)decoded_length; } if ((client->websocket == 1) diff --git a/src/plugins/relay/relay-websocket.c b/src/plugins/relay/relay-websocket.c index f0632db8c..44b74445f 100644 --- a/src/plugins/relay/relay-websocket.c +++ b/src/plugins/relay/relay-websocket.c @@ -263,10 +263,13 @@ relay_websocket_send_http (struct t_relay_client *client, int relay_websocket_decode_frame (const unsigned char *buffer, unsigned long long length, - unsigned char *decoded) + unsigned char *decoded, + unsigned long long *decoded_length) { unsigned long long i, index, length_frame_size, length_frame; + *decoded_length = 0; + if (length < 2) return 0; @@ -312,6 +315,8 @@ relay_websocket_decode_frame (const unsigned char *buffer, } decoded[length_frame] = '\0'; + *decoded_length = length_frame; + return 1; } diff --git a/src/plugins/relay/relay-websocket.h b/src/plugins/relay/relay-websocket.h index 8f813200d..ba361d0aa 100644 --- a/src/plugins/relay/relay-websocket.h +++ b/src/plugins/relay/relay-websocket.h @@ -28,8 +28,9 @@ extern char *relay_websocket_build_handshake (struct t_relay_client *client); extern void relay_websocket_send_http (struct t_relay_client *client, const char *http); extern int relay_websocket_decode_frame (const unsigned char *buffer, - int length, - unsigned char *decoded); + unsigned long long length, + unsigned char *decoded, + unsigned long long *decoded_length); extern char *relay_websocket_encode_frame (struct t_relay_client *client, const char *buffer, unsigned long long length,