1
0
mirror of https://github.com/weechat/weechat.git synced 2026-07-03 16:23:14 +02:00

Compare commits

..

10 Commits

Author SHA1 Message Date
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
13 changed files with 114 additions and 16 deletions
+1 -1
View File
@@ -131,7 +131,7 @@ jobs:
sudo apt-get update -qq sudo apt-get update -qq
sudo apt-get --yes --no-install-recommends install ${{ env.CHECK_DEPS_UBUNTU }} sudo apt-get --yes --no-install-recommends install ${{ env.CHECK_DEPS_UBUNTU }}
pipx install msgcheck ruff pipx install msgcheck ruff
cargo install --version 0.0.10 poexam cargo install --version 0.0.12 poexam
- name: Check gettext files (msgcheck) - name: Check gettext files (msgcheck)
run: msgcheck po/*.po run: msgcheck po/*.po
+2
View File
@@ -7,9 +7,11 @@ select = [
"checks", "checks",
] ]
ignore = [ ignore = [
"acronyms",
"brackets", "brackets",
"double-quotes", "double-quotes",
"double-words", "double-words",
"functions",
"header", "header",
"html-tags", "html-tags",
"paths", "paths",
+12 -3
View File
@@ -6,6 +6,15 @@ SPDX-License-Identifier: GPL-3.0-or-later
# WeeChat ChangeLog # WeeChat ChangeLog
## Version 4.9.3 (under dev)
### Fixed
- 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) ## Version 4.9.2 (2026-06-07)
### Fixed ### Fixed
@@ -25,9 +34,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)) - 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 - 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: 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)) - 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)) - 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) ## Version 4.9.0 (2026-03-29)
+7
View File
@@ -1028,6 +1028,13 @@ Path parameters:
confused with the buffer number, which is different) confused with the buffer number, which is different)
* `buffer_name` (string, **required**): buffer name * `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: Request example: get nicks of a buffer:
[source,shell] [source,shell]
+8
View File
@@ -1040,6 +1040,14 @@ Paramètres de chemin :
confondre avec le numéro du tampon, qui est différent) confondre avec le numéro du tampon, qui est différent)
* `buffer_name` (chaîne, **obligatoire**) : nom du tampon * `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 : Exemple de requête : obtenir les pseudos d'un tampon :
[source,shell] [source,shell]
+8 -1
View File
@@ -1024,12 +1024,19 @@ GET /api/buffers/{id_бафера}/nicks
GET /api/buffers/{име_бафера}/nicks GET /api/buffers/{име_бафера}/nicks
---- ----
Параметри упита: Параметри путање:
* `id_бафера` (цео број, **обавезно**): јединствени идентификатор бафера (не треба * `id_бафера` (цео број, **обавезно**): јединствени идентификатор бафера (не треба
да се помеша са бројем бафера, то је нешто друго) да се помеша са бројем бафера, то је нешто друго)
* `име_бафера` (стринг, **обавезно**): име бафера * `име_бафера` (стринг, **обавезно**): име бафера
Параметри упита:
* `colors` (стринг, није обавезно, подразумевано: `ansi`): како се враћају стрингови са кодовима боје:
** `ansi`: враћају се ANSI кодови боје
** `weechat`: враћају се WeeChat интерни кодови боје
** `strip`: уклањају се боје
Пример захтева: врати надимке бафера: Пример захтева: врати надимке бафера:
[source,shell] [source,shell]
+2 -2
View File
@@ -29,7 +29,7 @@ msgstr ""
"Project-Id-Version: WeeChat\n" "Project-Id-Version: WeeChat\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n" "Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2026-03-21 17:24+0100\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" "Last-Translator: Nils Görs <weechatter@arcor.de>\n"
"Language-Team: German <kde-i18n-de@kde.org>\n" "Language-Team: German <kde-i18n-de@kde.org>\n"
"Language: de_DE\n" "Language: de_DE\n"
@@ -17330,7 +17330,7 @@ msgstr ""
"Um Tastenkurzbefehle im Skript-Buffer direkt nutzen zu können (zum Beispiel: " "Um Tastenkurzbefehle im Skript-Buffer direkt nutzen zu können (zum Beispiel: "
"alt+i = installieren, alt+r = entfernen, ...), muss diese Einstellung " "alt+i = installieren, alt+r = entfernen, ...), muss diese Einstellung "
"aktiviert werden. Andernfalls können Aktionen nur über die Eingabezeile " "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\")" msgid "color for status \"autoloaded\" (\"a\")"
msgstr "Farbe in der der Status \"autoloaded\" (\"a\") dargestellt werden soll" msgstr "Farbe in der der Status \"autoloaded\" (\"a\") dargestellt werden soll"
+19 -1
View File
@@ -581,7 +581,13 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
int port) int port)
{ {
struct t_network_socks5 socks5; 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; int username_len, password_len, addr_len, addr_buffer_len;
unsigned char *addr_buffer; unsigned char *addr_buffer;
char *username, *password; char *username, *password;
@@ -630,6 +636,18 @@ network_pass_socks5proxy (struct t_proxy *proxy, int sock, const char *address,
username_len = strlen (username); username_len = strlen (username);
password_len = strlen (password); 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 */ /* make username/password buffer */
buffer[0] = 1; buffer[0] = 1;
buffer[1] = (unsigned char) username_len; buffer[1] = (unsigned char) username_len;
+31
View File
@@ -3804,6 +3804,7 @@ gui_buffer_close (struct t_gui_buffer *buffer)
gui_hotlist_remove_buffer (buffer, 1); gui_hotlist_remove_buffer (buffer, 1);
free (buffer->hotlist_removed); free (buffer->hotlist_removed);
buffer->hotlist_removed = NULL;
if (gui_hotlist_initial_buffer == buffer) if (gui_hotlist_initial_buffer == buffer)
gui_hotlist_initial_buffer = NULL; gui_hotlist_initial_buffer = NULL;
@@ -3822,55 +3823,85 @@ gui_buffer_close (struct t_gui_buffer *buffer)
/* free all lines */ /* free all lines */
gui_line_free_all (buffer); gui_line_free_all (buffer);
free (buffer->own_lines); free (buffer->own_lines);
buffer->own_lines = NULL;
free (buffer->mixed_lines); free (buffer->mixed_lines);
buffer->mixed_lines = NULL;
/* free some data */ /* free some data */
gui_buffer_undo_free_all (buffer); gui_buffer_undo_free_all (buffer);
gui_history_buffer_free (buffer); gui_history_buffer_free (buffer);
gui_completion_free (buffer->completion); gui_completion_free (buffer->completion);
buffer->completion = NULL;
gui_nicklist_remove_all (buffer); gui_nicklist_remove_all (buffer);
gui_nicklist_remove_group (buffer, buffer->nicklist_root); gui_nicklist_remove_group (buffer, buffer->nicklist_root);
buffer->nicklist_root = NULL;
hashtable_free (buffer->hotlist_max_level_nicks); hashtable_free (buffer->hotlist_max_level_nicks);
buffer->hotlist_max_level_nicks = NULL;
gui_key_free_all (-1, &buffer->keys, &buffer->last_key, gui_key_free_all (-1, &buffer->keys, &buffer->last_key,
&buffer->keys_count, 0); &buffer->keys_count, 0);
gui_buffer_local_var_remove_all (buffer); gui_buffer_local_var_remove_all (buffer);
hashtable_free (buffer->local_variables); hashtable_free (buffer->local_variables);
buffer->local_variables = NULL;
free (buffer->plugin_name_for_upgrade); free (buffer->plugin_name_for_upgrade);
buffer->plugin_name_for_upgrade = NULL;
free (buffer->name); free (buffer->name);
buffer->name = NULL;
free (buffer->full_name); free (buffer->full_name);
buffer->full_name = NULL;
free (buffer->old_full_name); free (buffer->old_full_name);
buffer->old_full_name = NULL;
free (buffer->short_name); free (buffer->short_name);
buffer->short_name = NULL;
free (buffer->title); free (buffer->title);
buffer->title = NULL;
free (buffer->modes); free (buffer->modes);
buffer->modes = NULL;
free (buffer->input_prompt); free (buffer->input_prompt);
buffer->input_prompt = NULL;
free (buffer->input_buffer); free (buffer->input_buffer);
buffer->input_buffer = NULL;
free (buffer->input_undo_snap); free (buffer->input_undo_snap);
buffer->input_undo_snap = NULL;
free (buffer->text_search_input); free (buffer->text_search_input);
buffer->text_search_input = NULL;
if (buffer->text_search_regex_compiled) if (buffer->text_search_regex_compiled)
{ {
regfree (buffer->text_search_regex_compiled); regfree (buffer->text_search_regex_compiled);
free (buffer->text_search_regex_compiled); free (buffer->text_search_regex_compiled);
buffer->text_search_regex_compiled = NULL;
} }
free (buffer->highlight_words); free (buffer->highlight_words);
buffer->highlight_words = NULL;
free (buffer->highlight_disable_regex); free (buffer->highlight_disable_regex);
buffer->highlight_disable_regex = NULL;
if (buffer->highlight_disable_regex_compiled) if (buffer->highlight_disable_regex_compiled)
{ {
regfree (buffer->highlight_disable_regex_compiled); regfree (buffer->highlight_disable_regex_compiled);
free (buffer->highlight_disable_regex_compiled); free (buffer->highlight_disable_regex_compiled);
buffer->highlight_disable_regex_compiled = NULL;
} }
free (buffer->highlight_regex); free (buffer->highlight_regex);
buffer->highlight_regex = NULL;
if (buffer->highlight_regex_compiled) if (buffer->highlight_regex_compiled)
{ {
regfree (buffer->highlight_regex_compiled); regfree (buffer->highlight_regex_compiled);
free (buffer->highlight_regex_compiled); free (buffer->highlight_regex_compiled);
buffer->highlight_regex_compiled = NULL;
} }
free (buffer->highlight_tags_restrict); free (buffer->highlight_tags_restrict);
buffer->highlight_tags_restrict = NULL;
string_free_split_tags (buffer->highlight_tags_restrict_array); string_free_split_tags (buffer->highlight_tags_restrict_array);
buffer->highlight_tags_restrict_array = NULL;
free (buffer->highlight_tags); free (buffer->highlight_tags);
buffer->highlight_tags = NULL;
string_free_split_tags (buffer->highlight_tags_array); string_free_split_tags (buffer->highlight_tags_array);
buffer->highlight_tags_array = NULL;
free (buffer->input_callback_data); free (buffer->input_callback_data);
buffer->input_callback_data = NULL;
free (buffer->close_callback_data); free (buffer->close_callback_data);
buffer->close_callback_data = NULL;
free (buffer->nickcmp_callback_data); free (buffer->nickcmp_callback_data);
buffer->nickcmp_callback_data = NULL;
/* remove buffer from buffers list */ /* remove buffer from buffers list */
if (buffer->prev_buffer) if (buffer->prev_buffer)
+15 -2
View File
@@ -402,7 +402,10 @@ RELAY_API_PROTOCOL_CALLBACK(handshake)
if (json_body) if (json_body)
{ {
if (!cJSON_IsObject (json_body)) if (!cJSON_IsObject (json_body))
{
cJSON_Delete (json_body);
return RELAY_API_PROTOCOL_RC_BAD_REQUEST; return RELAY_API_PROTOCOL_RC_BAD_REQUEST;
}
json_algos = cJSON_GetObjectItem (json_body, "password_hash_algo"); json_algos = cJSON_GetObjectItem (json_body, "password_hash_algo");
if (json_algos) if (json_algos)
{ {
@@ -781,8 +784,13 @@ RELAY_API_PROTOCOL_CALLBACK(input)
char str_delay[32]; char str_delay[32];
json_body = cJSON_Parse (client->http_req->body); 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; 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 */ /* get buffer either by name or by id */
ptr_buffer = NULL; ptr_buffer = NULL;
@@ -908,8 +916,13 @@ RELAY_API_PROTOCOL_CALLBACK(completion)
struct t_gui_buffer *ptr_buffer; struct t_gui_buffer *ptr_buffer;
json_body = cJSON_Parse (client->http_req->body); 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; 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 */ /* get buffer either by name or by id */
ptr_buffer = NULL; ptr_buffer = NULL;
+6 -3
View File
@@ -653,7 +653,7 @@ relay_websocket_decode_frame (const unsigned char *buffer,
size_t size_decompressed; size_t size_decompressed;
char *payload_decompressed; char *payload_decompressed;
struct t_relay_websocket_frame *frames2, *ptr_frame; 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) if (!buffer || !frames || !num_frames)
return 0; return 0;
@@ -674,6 +674,9 @@ relay_websocket_decode_frame (const unsigned char *buffer,
opcode = buffer[index_buffer] & 15; opcode = buffer[index_buffer] & 15;
/* RSV1 indicates whether this message is compressed */
compressed = (buffer[index_buffer] & 64) ? 1 : 0;
/* check if frame is masked */ /* check if frame is masked */
masked_frame = (buffer[index_buffer + 1] & 128) ? 1 : 0; 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" * 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) if (!ws_deflate->strm_inflate)
{ {
+2 -2
View File
@@ -242,8 +242,8 @@ int
xfer_dcc_resume_hash (struct t_xfer *xfer) xfer_dcc_resume_hash (struct t_xfer *xfer)
{ {
char *buf; char *buf;
unsigned long long total_read; unsigned long long total_read, length_buf, to_read;
ssize_t length_buf, to_read, num_read; ssize_t num_read;
int ret, fd; int ret, fd;
total_read = 0; total_read = 0;
+1 -1
View File
@@ -42,7 +42,7 @@
# #
weechat_stable="4.9.2" weechat_stable="4.9.2"
weechat_devel="4.9.2" weechat_devel="4.9.3-dev"
stable_major=$(echo "${weechat_stable}" | cut -d"." -f1) stable_major=$(echo "${weechat_stable}" | cut -d"." -f1)
stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2) stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2)