From 58067431de20423f90fdbdaa95b4e94dce75ae3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Helleu?= Date: Mon, 23 Jun 2025 23:07:05 +0200 Subject: [PATCH] relay/api: process HTTP request received as soon as a NULL char is received MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes the API probe made by schemathesis, so it detects immediately that such NULL byte is not allowed by WeeChat, instead of timing out after 10 seconds: ✅ API capabilities: Supports NULL byte in headers: ✘ --- CHANGELOG.md | 1 + src/plugins/relay/relay-client.c | 7 ++++--- src/plugins/relay/relay-http.c | 13 +++++++++---- src/plugins/relay/relay-http.h | 3 ++- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9538745df..86eb990bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - irc: display nick changes and quit messages when option irc.look.ignore_tag_messages is enabled ([#2241](https://github.com/weechat/weechat/issues/2241)) - perl: fix build when multiplicity is not available ([#2243](https://github.com/weechat/weechat/issues/2243)) - relay/api: reject any invalid or unknown password hash algorithm in handshake resource +- relay/api: process HTTP request received as soon as a NULL char is received - relay/weechat: fix empty buffers in client when WeeChat is running on Solaris/illumos - build: fix build on Solaris/illumos (issue #2251) diff --git a/src/plugins/relay/relay-client.c b/src/plugins/relay/relay-client.c index 2a8c4914b..54873900b 100644 --- a/src/plugins/relay/relay-client.c +++ b/src/plugins/relay/relay-client.c @@ -504,7 +504,8 @@ relay_client_recv_text_buffer (struct t_relay_client *client, if ((client->websocket == RELAY_CLIENT_WEBSOCKET_INITIALIZING) || (client->recv_data_type == RELAY_CLIENT_DATA_HTTP)) { - relay_http_recv (client, buffer + index); + relay_http_recv (client, buffer + index, length_buffer - index); + break; } else { @@ -582,7 +583,7 @@ relay_client_read_websocket_frames (struct t_relay_client *client, if ((client->websocket == RELAY_CLIENT_WEBSOCKET_INITIALIZING) || (client->recv_data_type == RELAY_CLIENT_DATA_HTTP)) { - relay_http_recv (client, frames[i].payload); + relay_http_recv (client, frames[i].payload, frames[i].payload_size); } else if ((client->recv_data_type == RELAY_CLIENT_DATA_TEXT_LINE) || (client->recv_data_type == RELAY_CLIENT_DATA_TEXT_MULTILINE)) @@ -694,7 +695,7 @@ relay_client_recv_buffer (struct t_relay_client *client, if ((client->websocket == RELAY_CLIENT_WEBSOCKET_INITIALIZING) || (client->recv_data_type == RELAY_CLIENT_DATA_HTTP)) { - relay_http_recv (client, buffer); + relay_http_recv (client, buffer, buffer_size); } else if ((client->recv_data_type == RELAY_CLIENT_DATA_TEXT_LINE) || (client->recv_data_type == RELAY_CLIENT_DATA_TEXT_MULTILINE)) diff --git a/src/plugins/relay/relay-http.c b/src/plugins/relay/relay-http.c index b899c1827..bc2d68a8b 100644 --- a/src/plugins/relay/relay-http.c +++ b/src/plugins/relay/relay-http.c @@ -935,11 +935,13 @@ relay_http_process_request (struct t_relay_client *client) */ void -relay_http_recv (struct t_relay_client *client, const char *data) +relay_http_recv (struct t_relay_client *client, const char *data, int size) { - char *new_partial, *pos; + char *new_partial, *pos, **null_char; int length, ws_deflate_allowed; + null_char = memchr (data, 0, size); + if (client->partial_message) { new_partial = realloc (client->partial_message, @@ -1003,8 +1005,11 @@ relay_http_recv (struct t_relay_client *client, const char *data) relay_http_add_to_body (client->http_req, &(client->partial_message)); } - /* process the request if it's ready to be processed (all parsed) */ - if (client->http_req->status == RELAY_HTTP_END) + /* + * process the request if it's ready to be processed (all parsed) + * or if we received a NULL char in the HTTP message (forbidden) + * */ + if ((client->http_req->status == RELAY_HTTP_END) || null_char) { relay_http_process_request (client); relay_http_request_reinit (client->http_req); diff --git a/src/plugins/relay/relay-http.h b/src/plugins/relay/relay-http.h index 14d9e943f..17b70ef20 100644 --- a/src/plugins/relay/relay-http.h +++ b/src/plugins/relay/relay-http.h @@ -100,7 +100,8 @@ extern long relay_http_get_param_long (struct t_relay_http_request *request, extern int relay_http_parse_method_path (struct t_relay_http_request *request, const char *method_path); extern int relay_http_check_auth (struct t_relay_client *client); -extern void relay_http_recv (struct t_relay_client *client, const char *data); +extern void relay_http_recv (struct t_relay_client *client, + const char *data, int size); extern int relay_http_send (struct t_relay_client *client, int return_code, const char *message, const char *headers,