|
|
8d4e70d |
From 0be57b4f449ce9289734f630873391ef1831dd3c Mon Sep 17 00:00:00 2001
|
|
|
8d4e70d |
From: Michael Catanzaro <mcatanzaro@gnome.org>
|
|
|
8d4e70d |
Date: Thu, 24 Sep 2020 07:03:10 -0500
|
|
|
8d4e70d |
Subject: [PATCH] Properly handle long IRC messages
|
|
|
8d4e70d |
|
|
|
8d4e70d |
IRC messages are delimited by CRLF. When the string passed to
|
|
|
8d4e70d |
idle_parser_receive() doesn't end in \r or \n, the remaining parts get
|
|
|
8d4e70d |
stashed away to be used to form a message on the next call to
|
|
|
8d4e70d |
idle_parser_receive(). But telepathy-idle improperly assumes that the
|
|
|
8d4e70d |
next call to idle_parser_receive() will definitely contain \r or \n,
|
|
|
8d4e70d |
i.e. it assumes that an IRC message cannot be split between three calls
|
|
|
8d4e70d |
to idle_parser_receive(). That assumption is wrong.
|
|
|
8d4e70d |
|
|
|
8d4e70d |
Fixes polari#147
|
|
|
8d4e70d |
---
|
|
|
8d4e70d |
src/idle-parser.c | 26 +++++++++++++++++++++-----
|
|
|
8d4e70d |
1 file changed, 21 insertions(+), 5 deletions(-)
|
|
|
8d4e70d |
|
|
|
8d4e70d |
diff --git a/src/idle-parser.c b/src/idle-parser.c
|
|
|
8d4e70d |
index 159e6cc..71ca8b1 100644
|
|
|
8d4e70d |
--- a/src/idle-parser.c
|
|
|
8d4e70d |
+++ b/src/idle-parser.c
|
|
|
8d4e70d |
@@ -151,6 +151,7 @@ struct _IdleParserPrivate {
|
|
|
8d4e70d |
|
|
|
8d4e70d |
/* continuation line buffer */
|
|
|
8d4e70d |
gchar split_buf[IRC_MSG_MAXLEN + 3];
|
|
|
8d4e70d |
+ guint split_buf_used;
|
|
|
8d4e70d |
|
|
|
8d4e70d |
/* message handlers */
|
|
|
8d4e70d |
GSList *handlers[IDLE_PARSER_LAST_MESSAGE_CODE];
|
|
|
8d4e70d |
@@ -226,6 +227,13 @@ strnlen(const char *msg, size_t maxlen)
|
|
|
8d4e70d |
}
|
|
|
8d4e70d |
#endif
|
|
|
8d4e70d |
|
|
|
8d4e70d |
+static void clear_split_buf(IdleParser *parser) {
|
|
|
8d4e70d |
+ IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser);
|
|
|
8d4e70d |
+
|
|
|
8d4e70d |
+ memset(priv->split_buf, '\0', IRC_MSG_MAXLEN + 3);
|
|
|
8d4e70d |
+ priv->split_buf_used = 0;
|
|
|
8d4e70d |
+}
|
|
|
8d4e70d |
+
|
|
|
8d4e70d |
void idle_parser_receive(IdleParser *parser, const gchar *msg) {
|
|
|
8d4e70d |
IdleParserPrivate *priv = IDLE_PARSER_GET_PRIVATE(parser);
|
|
|
8d4e70d |
guint i;
|
|
|
8d4e70d |
@@ -245,7 +253,7 @@ void idle_parser_receive(IdleParser *parser, const gchar *msg) {
|
|
|
8d4e70d |
if ((lasti == 0) && (priv->split_buf[0] != '\0')) {
|
|
|
8d4e70d |
g_strlcpy(g_stpcpy(concat_buf, priv->split_buf), msg, i + 1);
|
|
|
8d4e70d |
tmp = concat_buf;
|
|
|
8d4e70d |
- memset(priv->split_buf, '\0', IRC_MSG_MAXLEN + 3);
|
|
|
8d4e70d |
+ clear_split_buf(parser);
|
|
|
8d4e70d |
} else {
|
|
|
8d4e70d |
tmp = g_strndup(msg + lasti, i - lasti);
|
|
|
8d4e70d |
}
|
|
|
8d4e70d |
@@ -264,10 +272,18 @@ void idle_parser_receive(IdleParser *parser, const gchar *msg) {
|
|
|
8d4e70d |
}
|
|
|
8d4e70d |
}
|
|
|
8d4e70d |
|
|
|
8d4e70d |
- if (!line_ends)
|
|
|
8d4e70d |
- g_strlcpy(priv->split_buf, msg + lasti, (IRC_MSG_MAXLEN + 3) - lasti);
|
|
|
8d4e70d |
- else
|
|
|
8d4e70d |
- memset(priv->split_buf, '\0', IRC_MSG_MAXLEN + 3);
|
|
|
8d4e70d |
+ if (!line_ends) {
|
|
|
8d4e70d |
+ len = strlen(msg + lasti);
|
|
|
8d4e70d |
+ if (len > (IRC_MSG_MAXLEN + 3) - priv->split_buf_used - 1) {
|
|
|
8d4e70d |
+ IDLE_DEBUG("Discarding content that exceeds maximum message length: \"%s\"", msg + lasti);
|
|
|
8d4e70d |
+ clear_split_buf(parser);
|
|
|
8d4e70d |
+ } else {
|
|
|
8d4e70d |
+ g_strlcpy(priv->split_buf + priv->split_buf_used, msg + lasti, (IRC_MSG_MAXLEN + 3) - priv->split_buf_used);
|
|
|
8d4e70d |
+ priv->split_buf_used += len;
|
|
|
8d4e70d |
+ }
|
|
|
8d4e70d |
+ } else {
|
|
|
8d4e70d |
+ clear_split_buf(parser);
|
|
|
8d4e70d |
+ }
|
|
|
8d4e70d |
}
|
|
|
8d4e70d |
|
|
|
8d4e70d |
void idle_parser_add_handler(IdleParser *parser, IdleParserMessageCode code, IdleParserMessageHandler handler, gpointer user_data) {
|
|
|
8d4e70d |
--
|
|
|
8d4e70d |
GitLab
|
|
|
8d4e70d |
|