From acaf52862812b4cc656bbafe9083f2733345a41b Mon Sep 17 00:00:00 2001 From: Matthew Horan Date: Sun, 28 Jun 2026 14:46:18 -0400 Subject: [PATCH] relay/api: only decompress compressed messages With permessage-deflate, RSV1 of the first fragment indicates whether or not the message is compressed [1]. If RSV1 is not set then the message should not be decompressed. [1] https://datatracker.ietf.org/doc/html/rfc7692#section-6 --- CHANGELOG.md | 1 + src/plugins/relay/relay-websocket.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 243f9cece..33419ced7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - core: fix buffer overflow in connection to SOCKS5 proxy ([#2325](https://github.com/weechat/weechat/issues/2325)) - relay/api: fix memory leak in resources "handshake", "input" and "completion" +- relay: fix read of uncompressed websocket frame ([#2331](https://github.com/weechat/weechat/issues/2331)) - xfer: fix out-of-bounds write in xfer file transfer resume ([#2326](https://github.com/weechat/weechat/issues/2326)) ## Version 4.9.2 (2026-06-07) diff --git a/src/plugins/relay/relay-websocket.c b/src/plugins/relay/relay-websocket.c index 3295c3a28..e6054cc4a 100644 --- a/src/plugins/relay/relay-websocket.c +++ b/src/plugins/relay/relay-websocket.c @@ -653,7 +653,7 @@ relay_websocket_decode_frame (const unsigned char *buffer, size_t size_decompressed; char *payload_decompressed; struct t_relay_websocket_frame *frames2, *ptr_frame; - int size, masked_frame, mask[4]; + int size, compressed, masked_frame, mask[4]; if (!buffer || !frames || !num_frames) return 0; @@ -674,6 +674,9 @@ relay_websocket_decode_frame (const unsigned char *buffer, opcode = buffer[index_buffer] & 15; + /* RSV1 indicates whether this message is compressed */ + compressed = (buffer[index_buffer] & 64) ? 1 : 0; + /* check if frame is masked */ masked_frame = (buffer[index_buffer + 1] & 128) ? 1 : 0; @@ -780,9 +783,9 @@ relay_websocket_decode_frame (const unsigned char *buffer, /* * decompress data if frame is not empty and if "permessage-deflate" - * is enabled + * is enabled and the message is compressed */ - if ((length_frame > 0) && ws_deflate && ws_deflate->enabled) + if ((length_frame > 0) && ws_deflate && ws_deflate->enabled && compressed) { if (!ws_deflate->strm_inflate) {