1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-10 11:43:13 +02:00

Compare commits

...

24 Commits

Author SHA1 Message Date
Sébastien Helleu ec5bd64dbf Version 4.9.4-dev 2026-07-05 15:43:50 +02:00
Sébastien Helleu 24fbeaa9a8 Version 4.9.3 2026-07-05 15:40:23 +02:00
Sébastien Helleu 8119823a17 core: mute compiler warning on calls to dup() function 2026-07-05 14:26:15 +02:00
Sébastien Helleu fa29dd8e63 api: do not free dynamic string on error in function string_dyn_concat 2026-07-05 13:08:43 +02:00
Sébastien Helleu de3a771d53 core: fix possible buffer overflow in list of commands displayed by /help (issue #2330)
Fix: c.lang.security.insecure-use-strcat-fn.insecure-use-strcat-fn security vulnerability

Found by OrbisAI Security
2026-07-05 13:08:30 +02:00
orbisai0security 49a3fd7ae6 core: fix possible buffer overflow in command /color alias (issue #2330)
Fix: c.lang.security.insecure-use-strcat-fn.insecure-use-strcat-fn security vulnerability

Automated security fix generated by OrbisAI Security
2026-07-05 13:08:13 +02:00
Sébastien Helleu 3bd95f0d12 core: update ChangeLog (GHSA-wmpc-m6g9-fwj8) 2026-07-05 12:58:30 +02:00
Sébastien Helleu 57795ddb98 core: set max curl version to 8.22.0 for TLSAUTH symbols 2026-07-05 12:55:32 +02:00
Sébastien Helleu 0645731b9b ci: bump poexam to version 0.0.12 2026-07-03 08:31:46 +02:00
Sébastien Helleu 9d43e2eed7 core: fix punctuation in German translation 2026-07-03 08:30:58 +02:00
Matthew Horan acaf528628 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
2026-07-03 07:51:14 +02:00
Sébastien Helleu cfa59405cf core: set pointers to NULL after free of data when a buffer is closed (issue #2332) 2026-06-30 10:18:05 +02:00
Matthew Horan 9388c01074 doc/api: note that colors param is supported nicks endpoint 2026-06-30 10:17:20 +02:00
Sébastien Helleu 0cd736af22 relay/api: fix memory leak in resources "handshake", "input" and "completion" 2026-06-17 21:55:06 +02:00
aizu-m 703120bbfb xfer: fix out-of-bounds write in xfer_dcc_resume_hash (#2326) 2026-06-17 21:31:53 +02:00
aizu-m 12c4170fbf core: fix buffer overflow in function network_pass_socks5proxy (#2325)
bound the configured proxy username and password before they are copied into the fixed stack buffer in network_pass_socks5proxy, otherwise a login longer than the buffer (a long password or token) overruns it while building the SOCKS5 auth request.
2026-06-12 13:03:20 +02:00
Sébastien Helleu e9138c5d55 core: add CVE IDs in ChangeLog 2026-06-09 22:12:25 +02:00
Sébastien Helleu eb8c8641ea Version 4.9.3-dev 2026-06-07 09:28:03 +02:00
Sébastien Helleu bd6455d07f Version 4.9.2 2026-06-07 09:25:09 +02:00
Sébastien Helleu 8d3180fa78 tests: increase buffer size for injection of fake IRC message 2026-06-07 08:48:47 +02:00
aizu-m 519ab4e7bb relay: fix out-of-bounds read in relay_http_print_log_request (#2324) 2026-06-06 11:20:05 +02:00
Sébastien Helleu 3c36fd7412 relay: limit size of partial message received while reading an HTTP request to prevent memory exhaustion
A relay client could send data with no end-of-line (an unterminated method
or header line) and dribble its payload, making WeeChat accumulate it in the
partial message buffer that grew without limit, until all memory was
exhausted. This path is reachable before authentication during websocket
initialization with the "weechat" and "irc" protocols.

The accumulated partial message is now bounded by
RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH: once the limit is reached, the extra
data is ignored.
2026-06-06 09:38:55 +02:00
Sébastien Helleu b62c97dbe3 core: add links to issues in ChangeLog (#2321, #2322) 2026-06-06 07:25:19 +02:00
aizu-m f91f92b48f xfer: fix out-of-bounds read in xfer_chat_recv_cb on empty line (#2323) 2026-06-06 07:21:55 +02:00
27 changed files with 252 additions and 52 deletions
+1 -1
View File
@@ -131,7 +131,7 @@ jobs:
sudo apt-get update -qq
sudo apt-get --yes --no-install-recommends install ${{ env.CHECK_DEPS_UBUNTU }}
pipx install msgcheck ruff
cargo install --version 0.0.10 poexam
cargo install --version 0.0.12 poexam
- name: Check gettext files (msgcheck)
run: msgcheck po/*.po
+2
View File
@@ -7,9 +7,11 @@ select = [
"checks",
]
ignore = [
"acronyms",
"brackets",
"double-quotes",
"double-words",
"functions",
"header",
"html-tags",
"paths",
+21 -6
View File
@@ -6,15 +6,30 @@ SPDX-License-Identifier: GPL-3.0-or-later
# WeeChat ChangeLog
## Version 4.9.2 (under dev)
## Version 4.9.3 (2026-07-05)
### Fixed
- core: fix buffer overflow in connection to SOCKS5 proxy ([#2325](https://github.com/weechat/weechat/issues/2325))
- core: fix possible buffer overflow in command /color alias ([#2330](https://github.com/weechat/weechat/issues/2330))
- core: fix possible buffer overflow in list of commands displayed by /help ([#2330](https://github.com/weechat/weechat/issues/2330))
- api: do not free dynamic string on error in function string_dyn_concat
- relay/api: fix memory leak in resources "handshake", "input" and "completion" ([GHSA-wmpc-m6g9-fwj8](https://github.com/weechat/weechat/security/advisories/GHSA-wmpc-m6g9-fwj8))
- 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)
### Fixed
- api: fix infinite loop in function string_replace when the search string is empty
- irc: limit size of data received from the server to prevent memory exhaustion
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message
- irc: fix out-of-bounds read on incoming DCC command with a quoted filename ending the message ([#2322](https://github.com/weechat/weechat/issues/2322))
- relay: limit size of received websocket frame and HTTP body to prevent memory exhaustion
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory
- relay: limit size of partial message received while reading an HTTP request to prevent memory exhaustion
- relay: fix out-of-bounds read in dump of data ([#2324](https://github.com/weechat/weechat/issues/2324))
- xfer: replace directory separator in remote nick by underscore in download filename to prevent writing the file outside the download directory ([#2321](https://github.com/weechat/weechat/issues/2321))
- xfer: fix out-of-bounds read when receiving empty line in DCC chat ([#2323](https://github.com/weechat/weechat/issues/2323))
## Version 4.9.1 (2026-05-31)
@@ -22,9 +37,9 @@ SPDX-License-Identifier: GPL-3.0-or-later
- core: fix option weechat.look.color_real_white not applied when color is "white" on 16+ colors terminals ([#1742](https://github.com/weechat/weechat/issues/1742))
- irc: fix tag in message with list of names when joining a channel
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3))
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc))
- relay: limit size of decompressed websocket frame with permessage-deflate to prevent memory exhaustion ([GHSA-v2v4-45wm-5cr3](https://github.com/weechat/weechat/security/advisories/GHSA-v2v4-45wm-5cr3), [CVE-2026-53524](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53524))
- relay: fix timing attack on password authentication ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
- api, relay: fix timing attack on TOTP validation ([GHSA-vhv8-g2r9-cwcc](https://github.com/weechat/weechat/security/advisories/GHSA-vhv8-g2r9-cwcc), [CVE-2026-53525](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-53525))
## Version 4.9.0 (2026-03-29)
+2
View File
@@ -3474,6 +3474,8 @@ Concatenate a string to a dynamic string.
The pointer _*string_ can change if the string is reallocated (if there is
not enough space to concatenate the string).
In case of error, the dynamic string is left unchanged.
Prototype:
[source,c]
+7
View File
@@ -1028,6 +1028,13 @@ Path parameters:
confused with the buffer number, which is different)
* `buffer_name` (string, **required**): buffer name
Query parameters:
* `colors` (string, optional, default: `ansi`): how to return strings with color codes:
** `ansi`: return ANSI color codes
** `weechat`: return WeeChat internal color codes
** `strip`: strip colors
Request example: get nicks of a buffer:
[source,shell]
+2
View File
@@ -3532,6 +3532,8 @@ Concaténer une chaîne dans une chaîne dynamique.
Le pointeur _*string_ peut changer si la chaîne est réallouée (s'il n'y a pas
assez de place pour concaténer la chaîne).
En cas d'erreur, la chaîne dynamique reste inchangée.
Prototype :
[source,c]
+8
View File
@@ -1040,6 +1040,14 @@ Paramètres de chemin :
confondre avec le numéro du tampon, qui est différent)
* `buffer_name` (chaîne, **obligatoire**) : nom du tampon
Paramètres de requête :
* `colors` (chaîne, facultatif, par défaut : `ansi`) : comment les chaînes avec
des couleurs sont retournées :
** `ansi` : retourner les codes couleur ANSI
** `weechat` : retourner les codes couleur internes WeeChat
** `strip` : supprimer les couleurs
Exemple de requête : obtenir les pseudos d'un tampon :
[source,shell]
+3
View File
@@ -3635,6 +3635,9 @@ Concatenate a string to a dynamic string.
The pointer _*string_ can change if the string is reallocated (if there is
not enough space to concatenate the string).
// TRANSLATION MISSING
In case of error, the dynamic string is left unchanged.
Prototipo:
[source,c]
+3
View File
@@ -3586,6 +3586,9 @@ _WeeChat バージョン 1.8 以上で利用可, updated in 3.0_
文字列が再確保された場合 (文字列を連結するのに十分なサイズが確保されていなかった場合)
にはポインタ _*string_ が変わる可能性があります。
// TRANSLATION MISSING
In case of error, the dynamic string is left unchanged.
プロトタイプ:
[source,c]
+3
View File
@@ -3356,6 +3356,9 @@ _WeeChat ≥ 1.8, ажурирано у верзији 3.0._
Показивач на стринг _*string_ може да се промени ако се стринг реалоцира (у случају да нема довољно простора за надовезивање стринга).
// TRANSLATION MISSING
In case of error, the dynamic string is left unchanged.
Прототип:
[source,c]
+8 -1
View File
@@ -1024,12 +1024,19 @@ GET /api/buffers/{id_бафера}/nicks
GET /api/buffers/{име_бафера}/nicks
----
Параметри упита:
Параметри путање:
* `id_бафера` (цео број, **обавезно**): јединствени идентификатор бафера (не треба
да се помеша са бројем бафера, то је нешто друго)
* `име_бафера` (стринг, **обавезно**): име бафера
Параметри упита:
* `colors` (стринг, није обавезно, подразумевано: `ansi`): како се враћају стрингови са кодовима боје:
** `ansi`: враћају се ANSI кодови боје
** `weechat`: враћају се WeeChat интерни кодови боје
** `strip`: уклањају се боје
Пример захтева: врати надимке бафера:
[source,shell]
+2 -2
View File
@@ -29,7 +29,7 @@ msgstr ""
"Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-03-21 17:24+0100\n"
"PO-Revision-Date: 2026-03-21 17:24+0100\n"
"PO-Revision-Date: 2026-07-03 08:28+0200\n"
"Last-Translator: Nils Görs <weechatter@arcor.de>\n"
"Language-Team: German <kde-i18n-de@kde.org>\n"
"Language: de_DE\n"
@@ -17330,7 +17330,7 @@ msgstr ""
"Um Tastenkurzbefehle im Skript-Buffer direkt nutzen zu können (zum Beispiel: "
"alt+i = installieren, alt+r = entfernen, ...), muss diese Einstellung "
"aktiviert werden. Andernfalls können Aktionen nur über die Eingabezeile "
"durchgeführt werden: i,r..."
"durchgeführt werden: i,r, ..."
msgid "color for status \"autoloaded\" (\"a\")"
msgstr "Farbe in der der Status \"autoloaded\" (\"a\") dargestellt werden soll"
+19 -22
View File
@@ -1720,17 +1720,12 @@ COMMAND_CALLBACK(color)
else
str_alias = argv[i];
}
str_color[0] = '\0';
if (str_alias)
{
strcat (str_color, ";");
strcat (str_color, str_alias);
}
if (str_rgb)
{
strcat (str_color, ";");
strcat (str_color, str_rgb);
}
snprintf (str_color, sizeof (str_color),
"%s%s%s%s",
(str_alias) ? ";" : "",
(str_alias) ? str_alias : "",
(str_rgb) ? ";" : "",
(str_rgb) ? str_rgb : "");
/* add color alias */
snprintf (str_command, sizeof (str_command),
@@ -2980,7 +2975,7 @@ command_help_list_plugin_commands (struct t_weechat_plugin *plugin,
struct t_gui_buffer *ptr_buffer;
int command_found, length, max_length, list_size;
int cols, lines, col, line, index;
char str_format[64], str_command[256], str_line[2048];
char str_format[64], str_command[256], **str_line;
if (verbose)
{
@@ -3083,27 +3078,29 @@ command_help_list_plugin_commands (struct t_weechat_plugin *plugin,
}
/* display lines with commands, in columns */
for (line = 0; line < lines; line++)
str_line = string_dyn_alloc (256);
if (str_line)
{
str_line[0] = '\0';
for (col = 0; col < cols; col++)
for (line = 0; line < lines; line++)
{
index = (col * lines) + line;
if (index < list_size)
string_dyn_copy (str_line, NULL);
for (col = 0; col < cols; col++)
{
item = weelist_get (list, index);
if (item)
index = (col * lines) + line;
if (index < list_size)
{
if (strlen (str_line) + strlen (weelist_string (item)) + 1 < (int)sizeof (str_line))
item = weelist_get (list, index);
if (item)
{
snprintf (str_command, sizeof (str_command),
str_format, weelist_string (item));
strcat (str_line, str_command);
string_dyn_concat (str_line, str_command, -1);
}
}
}
gui_chat_printf (NULL, "%s", *str_line);
}
gui_chat_printf (NULL, "%s", str_line);
string_dyn_free (str_line, 1);
}
}
+19 -1
View File
@@ -581,7 +581,13 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
int port)
{
struct t_network_socks5 socks5;
unsigned char buffer[288];
/*
* buffer must be large enough for the username/password authentication
* request, which is the longest message sent/received here; according to
* RFC 1929 it is: version (1) + username length (1) + username (max 255)
* + password length (1) + password (max 255)
*/
unsigned char buffer[2 + 255 + 1 + 255];
int username_len, password_len, addr_len, addr_buffer_len;
unsigned char *addr_buffer;
char *username, *password;
@@ -630,6 +636,18 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
username_len = strlen (username);
password_len = strlen (password);
/*
* username and password length are each stored on a single byte
* (RFC 1929), so they cannot exceed 255 bytes: reject longer values,
* otherwise the memcpy calls below would overflow the buffer
*/
if ((username_len > 255) || (password_len > 255))
{
free (username);
free (password);
return 0;
}
/* make username/password buffer */
buffer[0] = 1;
buffer[1] = (unsigned char) username_len;
+2 -4
View File
@@ -4768,6 +4768,8 @@ string_dyn_copy (char **string, const char *new_string)
* if the string had to be extended, or the same pointer if there was enough
* size to concatenate the new string.
*
* In case of error, the dynamic string is left unchanged.
*
* Return:
* 1: OK
* 0: error
@@ -4803,11 +4805,7 @@ string_dyn_concat (char **string, const char *add, int bytes)
new_size_alloc = new_size;
string_realloc = realloc (ptr_string_dyn->string, new_size_alloc);
if (!string_realloc)
{
free (ptr_string_dyn->string);
free (ptr_string_dyn);
return 0;
}
ptr_string_dyn->string = string_realloc;
ptr_string_dyn->size_alloc = new_size_alloc;
}
+6
View File
@@ -143,8 +143,10 @@ struct t_url_constant url_auth[] =
struct t_url_constant url_authtype[] =
{
#if LIBCURL_VERSION_NUM < 0x081600 /* < 8.22.0 */
URL_DEF_CONST(_TLSAUTH, NONE),
URL_DEF_CONST(_TLSAUTH, SRP),
#endif
{ NULL, 0 },
};
@@ -409,9 +411,11 @@ struct t_url_option url_options[] =
URL_DEF_OPTION(PASSWORD, STRING, NULL),
URL_DEF_OPTION(PROXYUSERNAME, STRING, NULL),
URL_DEF_OPTION(PROXYPASSWORD, STRING, NULL),
#if LIBCURL_VERSION_NUM < 0x081600 /* < 8.22.0 */
URL_DEF_OPTION(TLSAUTH_TYPE, MASK, url_authtype),
URL_DEF_OPTION(TLSAUTH_USERNAME, STRING, NULL),
URL_DEF_OPTION(TLSAUTH_PASSWORD, STRING, NULL),
#endif
URL_DEF_OPTION(SASL_AUTHZID, STRING, NULL),
URL_DEF_OPTION(SASL_IR, LONG, NULL),
@@ -626,9 +630,11 @@ struct t_url_option url_options[] =
URL_DEF_OPTION(PROXY_SSL_OPTIONS, LONG, url_ssl_options),
URL_DEF_OPTION(PROXY_SSL_VERIFYHOST, LONG, NULL),
URL_DEF_OPTION(PROXY_SSL_VERIFYPEER, LONG, NULL),
#if LIBCURL_VERSION_NUM < 0x081600 /* < 8.22.0 */
URL_DEF_OPTION(PROXY_TLSAUTH_PASSWORD, STRING, NULL),
URL_DEF_OPTION(PROXY_TLSAUTH_TYPE, STRING, NULL),
URL_DEF_OPTION(PROXY_TLSAUTH_USERNAME, STRING, NULL),
#endif
URL_DEF_OPTION(TLS13_CIPHERS, LIST, NULL),
URL_DEF_OPTION(PROXY_TLS13_CIPHERS, LIST, NULL),
#if LIBCURL_VERSION_NUM >= 0x074700 /* 7.71.0 */
+4 -3
View File
@@ -47,7 +47,7 @@ void
daemonize (void)
{
pid_t pid;
int fd, i;
int fd, i, rc;
printf ("%s ", _("Running WeeChat in background..."));
@@ -77,8 +77,9 @@ daemonize (void)
close (i);
}
fd = open ("/dev/null", O_RDWR);
(void) dup (fd);
(void) dup (fd);
rc = dup (fd);
rc = dup (fd);
(void) rc;
}
/*
+31
View File
@@ -3804,6 +3804,7 @@ gui_buffer_close (struct t_gui_buffer *buffer)
gui_hotlist_remove_buffer (buffer, 1);
free (buffer->hotlist_removed);
buffer->hotlist_removed = NULL;
if (gui_hotlist_initial_buffer == buffer)
gui_hotlist_initial_buffer = NULL;
@@ -3822,55 +3823,85 @@ gui_buffer_close (struct t_gui_buffer *buffer)
/* free all lines */
gui_line_free_all (buffer);
free (buffer->own_lines);
buffer->own_lines = NULL;
free (buffer->mixed_lines);
buffer->mixed_lines = NULL;
/* free some data */
gui_buffer_undo_free_all (buffer);
gui_history_buffer_free (buffer);
gui_completion_free (buffer->completion);
buffer->completion = NULL;
gui_nicklist_remove_all (buffer);
gui_nicklist_remove_group (buffer, buffer->nicklist_root);
buffer->nicklist_root = NULL;
hashtable_free (buffer->hotlist_max_level_nicks);
buffer->hotlist_max_level_nicks = NULL;
gui_key_free_all (-1, &buffer->keys, &buffer->last_key,
&buffer->keys_count, 0);
gui_buffer_local_var_remove_all (buffer);
hashtable_free (buffer->local_variables);
buffer->local_variables = NULL;
free (buffer->plugin_name_for_upgrade);
buffer->plugin_name_for_upgrade = NULL;
free (buffer->name);
buffer->name = NULL;
free (buffer->full_name);
buffer->full_name = NULL;
free (buffer->old_full_name);
buffer->old_full_name = NULL;
free (buffer->short_name);
buffer->short_name = NULL;
free (buffer->title);
buffer->title = NULL;
free (buffer->modes);
buffer->modes = NULL;
free (buffer->input_prompt);
buffer->input_prompt = NULL;
free (buffer->input_buffer);
buffer->input_buffer = NULL;
free (buffer->input_undo_snap);
buffer->input_undo_snap = NULL;
free (buffer->text_search_input);
buffer->text_search_input = NULL;
if (buffer->text_search_regex_compiled)
{
regfree (buffer->text_search_regex_compiled);
free (buffer->text_search_regex_compiled);
buffer->text_search_regex_compiled = NULL;
}
free (buffer->highlight_words);
buffer->highlight_words = NULL;
free (buffer->highlight_disable_regex);
buffer->highlight_disable_regex = NULL;
if (buffer->highlight_disable_regex_compiled)
{
regfree (buffer->highlight_disable_regex_compiled);
free (buffer->highlight_disable_regex_compiled);
buffer->highlight_disable_regex_compiled = NULL;
}
free (buffer->highlight_regex);
buffer->highlight_regex = NULL;
if (buffer->highlight_regex_compiled)
{
regfree (buffer->highlight_regex_compiled);
free (buffer->highlight_regex_compiled);
buffer->highlight_regex_compiled = NULL;
}
free (buffer->highlight_tags_restrict);
buffer->highlight_tags_restrict = NULL;
string_free_split_tags (buffer->highlight_tags_restrict_array);
buffer->highlight_tags_restrict_array = NULL;
free (buffer->highlight_tags);
buffer->highlight_tags = NULL;
string_free_split_tags (buffer->highlight_tags_array);
buffer->highlight_tags_array = NULL;
free (buffer->input_callback_data);
buffer->input_callback_data = NULL;
free (buffer->close_callback_data);
buffer->close_callback_data = NULL;
free (buffer->nickcmp_callback_data);
buffer->nickcmp_callback_data = NULL;
/* remove buffer from buffers list */
if (buffer->prev_buffer)
+15 -2
View File
@@ -402,7 +402,10 @@ RELAY_API_PROTOCOL_CALLBACK(handshake)
if (json_body)
{
if (!cJSON_IsObject (json_body))
{
cJSON_Delete (json_body);
return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
}
json_algos = cJSON_GetObjectItem (json_body, "password_hash_algo");
if (json_algos)
{
@@ -781,8 +784,13 @@ RELAY_API_PROTOCOL_CALLBACK(input)
char str_delay[32];
json_body = cJSON_Parse (client->http_req->body);
if (!json_body || !cJSON_IsObject (json_body))
if (!json_body)
return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
if (!cJSON_IsObject (json_body))
{
cJSON_Delete (json_body);
return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
}
/* get buffer either by name or by id */
ptr_buffer = NULL;
@@ -908,8 +916,13 @@ RELAY_API_PROTOCOL_CALLBACK(completion)
struct t_gui_buffer *ptr_buffer;
json_body = cJSON_Parse (client->http_req->body);
if (!json_body || !cJSON_IsObject(json_body))
if (!json_body)
return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
if (!cJSON_IsObject(json_body))
{
cJSON_Delete (json_body);
return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
}
/* get buffer either by name or by id */
ptr_buffer = NULL;
+9 -1
View File
@@ -1006,6 +1006,14 @@ relay_http_recv (struct t_relay_client *client, const char *data, int size)
if (client->partial_message)
{
/*
* limit the size of the partial message: once the maximum is reached,
* ignore the extra data (protection against a client sending a huge
* amount of data without any end-of-line and dribbling it, which would
* consume all the memory)
*/
if (strlen (client->partial_message) >= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH)
return;
new_partial = realloc (client->partial_message,
strlen (client->partial_message) +
strlen (data) + 1);
@@ -1708,7 +1716,7 @@ relay_http_print_log_request (struct t_relay_http_request *request)
weechat_log_printf (" path_items. . . . . . . : %p", request->path_items);
if (request->path_items)
{
for (i = 0; request->path_items[0]; i++)
for (i = 0; request->path_items[i]; i++)
{
weechat_log_printf (" '%s'", request->path_items[i]);
}
+9
View File
@@ -64,6 +64,15 @@ enum t_relay_client_http_status
*/
#define RELAY_HTTP_BODY_MAX_LENGTH (8 * 1024 * 1024)
/*
* maximum length of the partial message accumulated while reading an HTTP
* request: once this limit is reached, the extra data is ignored; this
* protects against a client sending a huge amount of data without any
* end-of-line (an unterminated method or header line), which would consume
* all the memory
*/
#define RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH (8 * 1024 * 1024)
struct t_relay_http_request
{
enum t_relay_client_http_status status; /* HTTP status */
+6 -3
View File
@@ -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)
{
+1 -1
View File
@@ -162,7 +162,7 @@ xfer_chat_recv_cb (const void *pointer, void *data, int fd)
{
ctcp_action = 0;
length = strlen (ptr_buf);
if (ptr_buf[length - 1] == '\r')
if ((length > 0) && (ptr_buf[length - 1] == '\r'))
{
ptr_buf[length - 1] = '\0';
length--;
+2 -2
View File
@@ -242,8 +242,8 @@ int
xfer_dcc_resume_hash (struct t_xfer *xfer)
{
char *buf;
unsigned long long total_read;
ssize_t length_buf, to_read, num_read;
unsigned long long total_read, length_buf, to_read;
ssize_t num_read;
int ret, fd;
total_read = 0;
+1 -1
View File
@@ -305,7 +305,7 @@ TEST_GROUP(IrcProtocolWithServer)
void server_recv (const char *command)
{
char str_command[4096];
char str_command[8192];
record_start ();
arraylist_clear (sent_messages);
@@ -41,6 +41,7 @@ extern "C"
#include "src/plugins/relay/relay-client.h"
#include "src/plugins/relay/relay-config.h"
#include "src/plugins/relay/relay-http.h"
#include "src/plugins/relay/relay-server.h"
#include "src/plugins/relay/relay-websocket.h"
#include "src/plugins/weechat-plugin.h"
@@ -1021,6 +1022,69 @@ TEST(RelayHttp, Recv)
/* TODO: write tests */
}
/*
* Test functions:
* relay_http_recv (partial message accumulated is bounded)
*
* Check that data received without any end-of-line does not grow the partial
* message buffer without limit.
*/
TEST(RelayHttp, RecvLimit)
{
struct t_relay_server *server;
struct t_relay_client *client;
char *chunk;
int chunk_size, i;
size_t length1, length2;
/* disable auto-open of relay buffer (it would pollute other tests) */
config_file_option_set (relay_config_look_auto_open_buffer, "off", 1);
server = relay_server_new ("weechat", RELAY_PROTOCOL_WEECHAT, NULL,
9000,
NULL, /* path */
1, /* ipv4 */
0, /* ipv6 */
0, /* tls */
0); /* unix_socket */
CHECK(server);
client = relay_client_new (-1, "test", server);
CHECK(client);
chunk_size = 1024 * 1024;
chunk = (char *)malloc (chunk_size + 1);
CHECK(chunk);
memset (chunk, 'a', chunk_size);
chunk[chunk_size] = '\0';
/* feed more than the maximum, with no end-of-line (16 MB) */
for (i = 0; i < 16; i++)
{
relay_http_recv (client, chunk, chunk_size);
}
CHECK(client->partial_message);
length1 = strlen (client->partial_message);
/* the partial message must be bounded (not ~16 MB) */
CHECK(length1 <= RELAY_HTTP_PARTIAL_MESSAGE_MAX_LENGTH + (size_t)chunk_size);
/* feeding more data must not grow it any further */
for (i = 0; i < 16; i++)
{
relay_http_recv (client, chunk, chunk_size);
}
length2 = strlen (client->partial_message);
LONGS_EQUAL(length1, length2);
free (chunk);
relay_client_free (client);
relay_server_free (server);
/* restore auto-open of relay buffer */
config_file_option_reset (relay_config_look_auto_open_buffer, 1);
}
/*
* Test functions:
* relay_http_compress
+2 -2
View File
@@ -41,8 +41,8 @@
# devel-number the devel version as hex number ("0x04010000" for "4.1.0-dev")
#
weechat_stable="4.9.1"
weechat_devel="4.9.2-dev"
weechat_stable="4.9.3"
weechat_devel="4.9.4-dev"
stable_major=$(echo "${weechat_stable}" | cut -d"." -f1)
stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2)