Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package weechat for openSUSE:Factory checked 
in at 2026-06-09 14:22:41
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/weechat (Old)
 and      /work/SRC/openSUSE:Factory/.weechat.new.2375 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "weechat"

Tue Jun  9 14:22:41 2026 rev:94 rq:1358018 version:4.9.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/weechat/weechat.changes  2026-06-01 
18:09:14.935351525 +0200
+++ /work/SRC/openSUSE:Factory/.weechat.new.2375/weechat.changes        
2026-06-09 14:26:51.232814132 +0200
@@ -1,0 +2,21 @@
+Mon Jun  8 14:32:55 UTC 2026 - Hunter Wardlaw <[email protected]>
+
+- Update to 4.9.2:
+  * 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 (#2322)
+  * relay: limit size of received websocket frame and HTTP body to 
+    prevent memory exhaustion
+  * 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)
+  * xfer: replace directory separator in remote nick by underscore in 
+    download filename to prevent writing the file outside the download 
+    directory (#2321)
+  * xfer: fix out-of-bounds read when receiving empty line in DCC 
+    chat (#2323)
+
+-------------------------------------------------------------------

Old:
----
  weechat-4.9.1.tar.xz
  weechat-4.9.1.tar.xz.asc

New:
----
  weechat-4.9.2.tar.xz
  weechat-4.9.2.tar.xz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ weechat.spec ++++++
--- /var/tmp/diff_new_pack.m1ZLRk/_old  2026-06-09 14:26:52.396862247 +0200
+++ /var/tmp/diff_new_pack.m1ZLRk/_new  2026-06-09 14:26:52.396862247 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           weechat
-Version:        4.9.1
+Version:        4.9.2
 Release:        0
 Summary:        Multi-protocol extensible Chat Client
 License:        GPL-3.0-or-later

++++++ weechat-4.9.1.tar.xz -> weechat-4.9.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/CHANGELOG.md 
new/weechat-4.9.2/CHANGELOG.md
--- old/weechat-4.9.1/CHANGELOG.md      2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/CHANGELOG.md      2026-06-07 09:25:09.000000000 +0200
@@ -6,6 +6,19 @@
 
 # WeeChat ChangeLog
 
+## 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 ([#2322](https://github.com/weechat/weechat/issues/2322))
+- relay: limit size of received websocket frame and HTTP body to prevent 
memory exhaustion
+- 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)
 
 ### Fixed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/core/core-string.c 
new/weechat-4.9.2/src/core/core-string.c
--- old/weechat-4.9.1/src/core/core-string.c    2026-05-31 13:46:04.000000000 
+0200
+++ new/weechat-4.9.2/src/core/core-string.c    2026-06-07 09:25:09.000000000 
+0200
@@ -1965,6 +1965,9 @@
     if (!string || !search || !replace)
         return NULL;
 
+    if (!search[0])
+        return strdup (string);
+
     length1 = strlen (search);
     length2 = strlen (replace);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/irc/irc-ctcp.c 
new/weechat-4.9.2/src/plugins/irc/irc-ctcp.c
--- old/weechat-4.9.1/src/plugins/irc/irc-ctcp.c        2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/irc/irc-ctcp.c        2026-06-07 
09:25:09.000000000 +0200
@@ -857,7 +857,7 @@
              * double-quote
              */
             pos = strrchr (pos_file, '"');
-            if (!pos || (pos == pos_file))
+            if (!pos || (pos == pos_file) || !pos[1])
             {
                 weechat_printf (
                     ctxt->server->buffer,
@@ -1032,7 +1032,7 @@
              * double-quote
              */
             pos = strrchr (pos_file, '"');
-            if (!pos || (pos == pos_file))
+            if (!pos || (pos == pos_file) || !pos[1])
             {
                 weechat_printf (
                     ctxt->server->buffer,
@@ -1176,7 +1176,7 @@
              * double-quote
              */
             pos = strrchr (pos_file, '"');
-            if (!pos || (pos == pos_file))
+            if (!pos || (pos == pos_file) || !pos[1])
             {
                 weechat_printf (
                     ctxt->server->buffer,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/irc/irc-protocol.c 
new/weechat-4.9.2/src/plugins/irc/irc-protocol.c
--- old/weechat-4.9.1/src/plugins/irc/irc-protocol.c    2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/irc/irc-protocol.c    2026-06-07 
09:25:09.000000000 +0200
@@ -4164,16 +4164,25 @@
         if (ctxt->server->isupport)
         {
             length_isupport = strlen (ctxt->server->isupport);
-            isupport2 = realloc (ctxt->server->isupport,
-                                 length_isupport +  /* existing */
-                                 1 +  /* space */
-                                 length +  /* new */
-                                 1);
-            if (isupport2)
+            /*
+             * limit the size of the accumulated ISUPPORT data: once the
+             * maximum is reached, ignore the extra data (protection against a
+             * server flooding "005" messages, which would consume all the
+             * memory)
+             */
+            if (length_isupport + 1 + length < IRC_SERVER_ISUPPORT_MAX_LENGTH)
             {
-                ctxt->server->isupport = isupport2;
-                strcat (ctxt->server->isupport, " ");
-                strcat (ctxt->server->isupport, str_info);
+                isupport2 = realloc (ctxt->server->isupport,
+                                     length_isupport +  /* existing */
+                                     1 +  /* space */
+                                     length +  /* new */
+                                     1);
+                if (isupport2)
+                {
+                    ctxt->server->isupport = isupport2;
+                    strcat (ctxt->server->isupport, " ");
+                    strcat (ctxt->server->isupport, str_info);
+                }
             }
         }
         else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/irc/irc-server.c 
new/weechat-4.9.2/src/plugins/irc/irc-server.c
--- old/weechat-4.9.1/src/plugins/irc/irc-server.c      2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/irc/irc-server.c      2026-06-07 
09:25:09.000000000 +0200
@@ -3409,6 +3409,14 @@
 
     if (server->unterminated_message)
     {
+        /*
+         * limit the size of the unterminated message: once the maximum is
+         * reached, ignore the extra data (protection against a server sending
+         * a very long line without end-of-line, which would consume all the
+         * memory)
+         */
+        if (strlen (server->unterminated_message) >= 
IRC_SERVER_RECV_MSG_MAX_LENGTH)
+            return;
         unterminated_message2 =
             realloc (server->unterminated_message,
                      (strlen (server->unterminated_message) +
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/irc/irc-server.h 
new/weechat-4.9.2/src/plugins/irc/irc-server.h
--- old/weechat-4.9.1/src/plugins/irc/irc-server.h      2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/irc/irc-server.h      2026-06-07 
09:25:09.000000000 +0200
@@ -144,6 +144,15 @@
 #define IRC_SERVER_MULTILINE_DEFAULT_MAX_BYTES 4096
 #define IRC_SERVER_MULTILINE_DEFAULT_MAX_LINES 24
 
+/*
+ * maximum length of an unterminated message (a received line without
+ * end-of-line) and of the accumulated "005" (ISUPPORT) data; these limits
+ * protect against a server sending a huge amount of data without end-of-line
+ * (or a flood of "005" messages), which would consume all the memory
+ */
+#define IRC_SERVER_RECV_MSG_MAX_LENGTH (64 * 1024)
+#define IRC_SERVER_ISUPPORT_MAX_LENGTH (64 * 1024)
+
 /* casemapping (string comparisons for nicks/channels) */
 enum t_irc_server_casemapping
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/relay/relay-http.c 
new/weechat-4.9.2/src/plugins/relay/relay-http.c
--- old/weechat-4.9.1/src/plugins/relay/relay-http.c    2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/relay/relay-http.c    2026-06-07 
09:25:09.000000000 +0200
@@ -513,6 +513,19 @@
     if (!partial_message || !*partial_message)
         return;
 
+    /*
+     * reject the body if its announced length is too big: this prevents a
+     * client from forcing an unbounded allocation by announcing a huge
+     * "Content-Length"
+     */
+    if (request->content_length > RELAY_HTTP_BODY_MAX_LENGTH)
+    {
+        free (*partial_message);
+        *partial_message = NULL;
+        request->status = RELAY_HTTP_END;
+        return;
+    }
+
     num_bytes_missing = request->content_length
         - request->body_size;
     if (num_bytes_missing <= 0)
@@ -993,6 +1006,14 @@
 
     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);
@@ -1695,7 +1716,7 @@
     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]);
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/relay/relay-http.h 
new/weechat-4.9.2/src/plugins/relay/relay-http.h
--- old/weechat-4.9.1/src/plugins/relay/relay-http.h    2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/relay/relay-http.h    2026-06-07 
09:25:09.000000000 +0200
@@ -57,6 +57,22 @@
 #define RELAY_HTTP_ERROR_METHOD_NOT_ALLOWED   "Method Not Allowed"
 #define RELAY_HTTP_ERROR_OUT_OF_MEMORY        "Out of memory"
 
+/*
+ * maximum length of an HTTP request body: used as an upper bound on the
+ * "Content-Length" accepted from a client, to prevent a client from forcing
+ * an unbounded allocation by announcing a huge body
+ */
+#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                  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/relay/relay-websocket.c 
new/weechat-4.9.2/src/plugins/relay/relay-websocket.c
--- old/weechat-4.9.1/src/plugins/relay/relay-websocket.c       2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/relay/relay-websocket.c       2026-06-07 
09:25:09.000000000 +0200
@@ -703,6 +703,14 @@
             index_buffer += length_frame_size;
         }
 
+        /*
+         * reject the frame if its announced length is too big: this prevents
+         * a client from forcing an unbounded allocation (and unbounded
+         * accumulation of partial frames) by announcing a huge frame
+         */
+        if (length_frame > WEBSOCKET_FRAME_MAX_LENGTH)
+            return 0;
+
         if (masked_frame)
         {
             /* read mask (4 bytes) */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/relay/relay-websocket.h 
new/weechat-4.9.2/src/plugins/relay/relay-websocket.h
--- old/weechat-4.9.1/src/plugins/relay/relay-websocket.h       2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/relay/relay-websocket.h       2026-06-07 
09:25:09.000000000 +0200
@@ -42,6 +42,14 @@
 #define WEBSOCKET_SUB_PROTOCOL_API_WEECHAT "api.weechat"
 
 /*
+ * maximum length of a websocket frame received from a client (or a remote
+ * WeeChat): used as an upper bound on the announced frame payload length, to
+ * prevent a client from forcing an unbounded allocation by announcing a huge
+ * frame and dribbling its payload
+ */
+#define WEBSOCKET_FRAME_MAX_LENGTH (8 * 1024 * 1024)
+
+/*
  * maximum size of a decompressed websocket frame (with "permessage-deflate"):
  * used as an upper bound when inflating, to prevent a small compressed frame
  * from decompressing to an unbounded amount of data ("deflate bomb")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/xfer/xfer-chat.c 
new/weechat-4.9.2/src/plugins/xfer/xfer-chat.c
--- old/weechat-4.9.1/src/plugins/xfer/xfer-chat.c      2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/xfer/xfer-chat.c      2026-06-07 
09:25:09.000000000 +0200
@@ -162,7 +162,7 @@
             {
                 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--;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/src/plugins/xfer/xfer-file.c 
new/weechat-4.9.2/src/plugins/xfer/xfer-file.c
--- old/weechat-4.9.1/src/plugins/xfer/xfer-file.c      2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/src/plugins/xfer/xfer-file.c      2026-06-07 
09:25:09.000000000 +0200
@@ -251,7 +251,7 @@
 void
 xfer_file_find_filename (struct t_xfer *xfer)
 {
-    char *dir_separator, *path;
+    char *dir_separator, *path, *nick;
     struct t_hashtable *options;
 
     if (!XFER_IS_FILE(xfer->type))
@@ -287,12 +287,20 @@
     {
         strcat (xfer->local_filename, dir_separator);
     }
-    free (dir_separator);
     if (weechat_config_boolean (xfer_config_file_use_nick_in_filename))
     {
-        strcat (xfer->local_filename, xfer->remote_nick);
+        /*
+         * the remote nick comes from the server and can contain a directory
+         * separator: replace it so the nick cannot make the file be written
+         * outside the download directory
+         */
+        nick = (dir_separator) ?
+            weechat_string_replace (xfer->remote_nick, dir_separator, "_") : 
NULL;
+        strcat (xfer->local_filename, (nick) ? nick : xfer->remote_nick);
+        free (nick);
         strcat (xfer->local_filename, ".");
     }
+    free (dir_separator);
     strcat (xfer->local_filename, xfer->filename);
 
     free (path);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/tests/unit/core/test-core-string.cpp 
new/weechat-4.9.2/tests/unit/core/test-core-string.cpp
--- old/weechat-4.9.1/tests/unit/core/test-core-string.cpp      2026-05-31 
13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/core/test-core-string.cpp      2026-06-07 
09:25:09.000000000 +0200
@@ -1454,6 +1454,8 @@
     WEE_TEST_STR(NULL, string_replace ("string", NULL, "replace"));
     WEE_TEST_STR(NULL, string_replace (NULL, "search", "replace"));
 
+    WEE_TEST_STR("test abc def", string_replace("test abc def", "", "xxx"));
+
     WEE_TEST_STR("test abc def", string_replace("test abc def", "xyz", "xxx"));
     WEE_TEST_STR("test xxx def", string_replace("test abc def", "abc", "xxx"));
     WEE_TEST_STR("xxx test xxx def xxx",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/weechat-4.9.1/tests/unit/plugins/irc/test-irc-protocol.cpp 
new/weechat-4.9.2/tests/unit/plugins/irc/test-irc-protocol.cpp
--- old/weechat-4.9.1/tests/unit/plugins/irc/test-irc-protocol.cpp      
2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/plugins/irc/test-irc-protocol.cpp      
2026-06-07 09:25:09.000000000 +0200
@@ -305,7 +305,7 @@
 
     void server_recv (const char *command)
     {
-        char str_command[4096];
+        char str_command[8192];
 
         record_start ();
         arraylist_clear (sent_messages);
@@ -3867,6 +3867,44 @@
 }
 
 /*
+ * Test functions:
+ *   irc_protocol_cb_005 (accumulated ISUPPORT is bounded)
+ */
+
+TEST(IrcProtocolWithServer, 005_limit)
+{
+    char str_msg[4096], str_value[3500];
+    size_t length1, length2;
+    int i;
+
+    SRV_INIT;
+
+    memset (str_value, 'X', sizeof (str_value) - 1);
+    str_value[sizeof (str_value) - 1] = '\0';
+    snprintf (str_msg, sizeof (str_msg),
+              ":server 005 alice TEST=%s :are supported", str_value);
+
+    /* flood the server with "005" messages */
+    for (i = 0; i < 100; i++)
+    {
+        server_recv (str_msg);
+    }
+    CHECK(ptr_server->isupport);
+    length1 = strlen (ptr_server->isupport);
+
+    /* the accumulated ISUPPORT data must be bounded */
+    CHECK(length1 <= IRC_SERVER_ISUPPORT_MAX_LENGTH + sizeof (str_value));
+
+    /* receiving more "005" messages must not grow it any further */
+    for (i = 0; i < 100; i++)
+    {
+        server_recv (str_msg);
+    }
+    length2 = strlen (ptr_server->isupport);
+    LONGS_EQUAL(length1, length2);
+}
+
+/*
  * Test functions:
  *   irc_protocol_cb_005 (infos from server, multiple messages)
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/weechat-4.9.1/tests/unit/plugins/irc/test-irc-server.cpp 
new/weechat-4.9.2/tests/unit/plugins/irc/test-irc-server.cpp
--- old/weechat-4.9.1/tests/unit/plugins/irc/test-irc-server.cpp        
2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/plugins/irc/test-irc-server.cpp        
2026-06-07 09:25:09.000000000 +0200
@@ -67,6 +67,49 @@
 
 /*
  * Test functions:
+ *   irc_server_msgq_add_unterminated (via irc_server_msgq_add_buffer)
+ *
+ * Check that data received without any end-of-line does not grow the
+ * unterminated message buffer without limit.
+ */
+
+TEST(IrcServer, MsgqAddBufferLimit)
+{
+    struct t_irc_server *server;
+    char chunk[4097];
+    int i;
+    size_t length1, length2;
+
+    server = irc_server_alloc ("server_msgq");
+    CHECK(server);
+
+    memset (chunk, 'a', sizeof (chunk) - 1);
+    chunk[sizeof (chunk) - 1] = '\0';
+
+    /* feed a lot of data with no end-of-line */
+    for (i = 0; i < 100; i++)
+    {
+        irc_server_msgq_add_buffer (server, chunk);
+    }
+    CHECK(server->unterminated_message);
+    length1 = strlen (server->unterminated_message);
+
+    /* the buffer must be bounded (not ~400 KB) */
+    CHECK(length1 <= IRC_SERVER_RECV_MSG_MAX_LENGTH + sizeof (chunk));
+
+    /* feeding more data must not grow the buffer any further */
+    for (i = 0; i < 100; i++)
+    {
+        irc_server_msgq_add_buffer (server, chunk);
+    }
+    length2 = strlen (server->unterminated_message);
+    LONGS_EQUAL(length1, length2);
+
+    irc_server_free (server);
+}
+
+/*
+ * Test functions:
  *   irc_server_search
  */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/weechat-4.9.1/tests/unit/plugins/relay/test-relay-http.cpp 
new/weechat-4.9.2/tests/unit/plugins/relay/test-relay-http.cpp
--- old/weechat-4.9.1/tests/unit/plugins/relay/test-relay-http.cpp      
2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/plugins/relay/test-relay-http.cpp      
2026-06-07 09:25:09.000000000 +0200
@@ -41,6 +41,7 @@
 #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"
 
@@ -163,6 +164,35 @@
 
 /*
  * Test functions:
+ *   relay_http_add_to_body (body too large is rejected)
+ */
+
+TEST(RelayHttp, AddToBodyLimit)
+{
+    struct t_relay_http_request *request;
+    char *partial;
+
+    request = relay_http_request_alloc ();
+    CHECK(request);
+
+    /* announce a body larger than the maximum allowed */
+    request->status = RELAY_HTTP_BODY;
+    request->content_length = RELAY_HTTP_BODY_MAX_LENGTH + 1;
+    partial = strdup ("some body data");
+
+    relay_http_add_to_body (request, &partial);
+
+    /* the body must be rejected: nothing allocated, request ended */
+    POINTERS_EQUAL(NULL, request->body);
+    LONGS_EQUAL(0, request->body_size);
+    POINTERS_EQUAL(NULL, partial);
+    LONGS_EQUAL(RELAY_HTTP_END, request->status);
+
+    relay_http_request_free (request);
+}
+
+/*
+ * Test functions:
  *   relay_http_url_decode
  */
 
@@ -993,6 +1023,69 @@
 }
 
 /*
+ * 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
  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/weechat-4.9.1/tests/unit/plugins/relay/test-relay-websocket.cpp 
new/weechat-4.9.2/tests/unit/plugins/relay/test-relay-websocket.cpp
--- old/weechat-4.9.1/tests/unit/plugins/relay/test-relay-websocket.cpp 
2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/plugins/relay/test-relay-websocket.cpp 
2026-06-07 09:25:09.000000000 +0200
@@ -510,7 +510,44 @@
 
 TEST(RelayWebsocket, DecodeFrame)
 {
-    /* TODO: write tests */
+    struct t_relay_websocket_frame *frames;
+    char *partial_ws_frame;
+    int num_frames, partial_ws_frame_size;
+    /* small unmasked binary frame with payload "hello" */
+    unsigned char frame_ok[7] = { 0x82, 0x05, 'h', 'e', 'l', 'l', 'o' };
+    /* masked frame announcing a 1 GB payload (64-bit length field) */
+    unsigned char frame_too_big[10] = {
+        0x82, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+    };
+
+    /* a valid small frame is decoded */
+    frames = NULL;
+    num_frames = 0;
+    partial_ws_frame = NULL;
+    partial_ws_frame_size = 0;
+    LONGS_EQUAL(1, relay_websocket_decode_frame (
+                    frame_ok, sizeof (frame_ok), 0, NULL,
+                    &frames, &num_frames, &partial_ws_frame,
+                    &partial_ws_frame_size));
+    LONGS_EQUAL(1, num_frames);
+    CHECK(frames);
+    LONGS_EQUAL(5, frames[0].payload_size);
+    MEMCMP_EQUAL("hello", frames[0].payload, 5);
+    free (frames[0].payload);
+    free (frames);
+    free (partial_ws_frame);
+
+    /* a frame announcing an oversized payload is rejected (return 0) */
+    frames = NULL;
+    num_frames = 0;
+    partial_ws_frame = NULL;
+    partial_ws_frame_size = 0;
+    LONGS_EQUAL(0, relay_websocket_decode_frame (
+                    frame_too_big, sizeof (frame_too_big), 1, NULL,
+                    &frames, &num_frames, &partial_ws_frame,
+                    &partial_ws_frame_size));
+    free (frames);
+    free (partial_ws_frame);
 }
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/weechat-4.9.1/tests/unit/plugins/xfer/test-xfer-file.cpp 
new/weechat-4.9.2/tests/unit/plugins/xfer/test-xfer-file.cpp
--- old/weechat-4.9.1/tests/unit/plugins/xfer/test-xfer-file.cpp        
2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/tests/unit/plugins/xfer/test-xfer-file.cpp        
2026-06-07 09:25:09.000000000 +0200
@@ -25,6 +25,11 @@
 
 extern "C"
 {
+#include <stdlib.h>
+#include <string.h>
+#include "src/core/core-config-file.h"
+#include "src/plugins/xfer/xfer.h"
+#include "src/plugins/xfer/xfer-config.h"
 #include "src/plugins/xfer/xfer-file.h"
 }
 
@@ -33,6 +38,42 @@
 };
 
 /*
+ * Build a "file recv" xfer with the given remote nick (and a fixed filename),
+ * call xfer_file_find_filename and return a copy of the basename of the local
+ * filename (the part after the last directory separator).
+ *
+ * Note: result must be freed after use.
+ */
+
+static char *
+test_find_filename_basename (const char *remote_nick)
+{
+    struct t_xfer xfer;
+    char *pos, *result;
+
+    memset (&xfer, 0, sizeof (xfer));
+    xfer.type = XFER_TYPE_FILE_RECV_ACTIVE;
+    xfer.remote_nick = strdup (remote_nick);
+    xfer.filename = strdup ("test.txt");
+
+    xfer_file_find_filename (&xfer);
+
+    result = NULL;
+    if (xfer.local_filename)
+    {
+        pos = strrchr (xfer.local_filename, DIR_SEPARATOR_CHAR);
+        result = strdup ((pos) ? pos + 1 : xfer.local_filename);
+    }
+
+    free (xfer.remote_nick);
+    free (xfer.filename);
+    free (xfer.local_filename);
+    free (xfer.temp_local_filename);
+
+    return result;
+}
+
+/*
  * Test functions:
  *   xfer_file_search_crc32
  */
@@ -91,7 +132,30 @@
 
 TEST(XferFile, FindFilename)
 {
-    /* TODO: write tests */
+    char *basename;
+
+    config_file_option_set (xfer_config_file_download_path, 
"/tmp/weechat_test_xfer", 1);
+
+    /* remote nick without directory separator: used as-is */
+    basename = test_find_filename_basename ("alice");
+    STRCMP_EQUAL("alice.test.txt", basename);
+    free (basename);
+
+    /*
+     * remote nick with a directory separator: the separator is replaced by
+     * "_" so the nick cannot make the file be written outside the download
+     * directory
+     */
+    basename = test_find_filename_basename ("../foo");
+    STRCMP_EQUAL(".._foo.test.txt", basename);
+    free (basename);
+
+    /* all directory separators in the nick are replaced */
+    basename = test_find_filename_basename ("a/b/c");
+    STRCMP_EQUAL("a_b_c.test.txt", basename);
+    free (basename);
+
+    config_file_option_unset (xfer_config_file_download_path);
 }
 
 /*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/weechat-4.9.1/version.sh new/weechat-4.9.2/version.sh
--- old/weechat-4.9.1/version.sh        2026-05-31 13:46:04.000000000 +0200
+++ new/weechat-4.9.2/version.sh        2026-06-07 09:25:09.000000000 +0200
@@ -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.1"
+weechat_stable="4.9.2"
+weechat_devel="4.9.2"
 
 stable_major=$(echo "${weechat_stable}" | cut -d"." -f1)
 stable_minor=$(echo "${weechat_stable}" | cut -d"." -f2)

Reply via email to