commit 1e24934687420d59e055dc0425e5749362cac54a
parent 06b86af2291718112455397036f68c12dc58af0b
Author: Santtu Lakkala <inz@inz.fi>
Date: Wed, 9 Mar 2022 15:47:26 +0200
Always terminate server output
In some cases, the server message buffer might get truncated, always
terminate the string sent with CR+LF so the connection stays in a
reasonable state.
Diffstat:
M | ii.c | | | 38 | ++++++++++++++++++++++++-------------- |
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/ii.c b/ii.c
@@ -431,6 +431,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf)
{
char *p = NULL;
size_t buflen;
+ int w = 0;
if (buf[0] == '\0')
return;
@@ -454,9 +455,9 @@ proc_channels_input(int ircfd, Channel *c, char *buf)
{
/* password protected channel */
if (p)
- snprintf(msg, sizeof(msg), "JOIN %s %s\r\n", &buf[3], p + 1);
+ w = snprintf(msg, sizeof(msg), "JOIN %s %s\r\n", &buf[3], p + 1);
else
- snprintf(msg, sizeof(msg), "JOIN %s\r\n", &buf[3]);
+ w = snprintf(msg, sizeof(msg), "JOIN %s\r\n", &buf[3]);
channel_join(&buf[3]);
} else if (p) {
if ((c = channel_join(&buf[3])))
@@ -466,7 +467,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf)
break;
case 't': /* topic */
if (buf[3])
- snprintf(msg, sizeof(msg), "TOPIC %s :%s\r\n", c->name, &buf[3]);
+ w = snprintf(msg, sizeof(msg), "TOPIC %s :%s\r\n", c->name, &buf[3]);
break;
case 'a': /* away */
if (buf[3]) {
@@ -474,48 +475,57 @@ proc_channels_input(int ircfd, Channel *c, char *buf)
channel_print(c, msg);
}
if (buf[3])
- snprintf(msg, sizeof(msg), "AWAY :%s\r\n", &buf[3]);
+ w = snprintf(msg, sizeof(msg), "AWAY :%s\r\n", &buf[3]);
else
- snprintf(msg, sizeof(msg), "AWAY\r\n");
+ w = snprintf(msg, sizeof(msg), "AWAY\r\n");
break;
case 'n': /* change nick */
if (buf[3]) {
strlcpy(_nick, &buf[3], sizeof(_nick));
- snprintf(msg, sizeof(msg), "NICK %s\r\n", &buf[3]);
+ w = snprintf(msg, sizeof(msg), "NICK %s\r\n", &buf[3]);
}
break;
case 'l': /* leave */
if (c == channelmaster)
return;
if (buf[3])
- snprintf(msg, sizeof(msg), "PART %s :%s\r\n", c->name, &buf[3]);
+ w = snprintf(msg, sizeof(msg), "PART %s :%s\r\n", c->name, &buf[3]);
else
- snprintf(msg, sizeof(msg),
+ w = snprintf(msg, sizeof(msg),
"PART %s :leaving\r\n", c->name);
+ if (w >= sizeof(msg) - 1) {
+ msg[sizeof(msg) - 3] = '\r';
+ msg[sizeof(msg) - 2] = '\n';
+ }
ewritestr(ircfd, msg);
channel_leave(c);
return;
break;
case 'q': /* quit */
if (buf[3])
- snprintf(msg, sizeof(msg), "QUIT :%s\r\n", &buf[3]);
+ w = snprintf(msg, sizeof(msg), "QUIT :%s\r\n", &buf[3]);
else
- snprintf(msg, sizeof(msg),
+ w = snprintf(msg, sizeof(msg),
"QUIT %s\r\n", "bye");
ewritestr(ircfd, msg);
isrunning = 0;
return;
break;
default: /* raw IRC command */
- snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
+ w = snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
break;
}
} else {
/* raw IRC command */
- snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
+ w = snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]);
+ }
+ if (msg[0] == '\0')
+ return;
+ if (w >= sizeof(msg) - 1) {
+ msg[sizeof(msg) - 3] = '\r';
+ msg[sizeof(msg) - 2] = '\n';
}
- if (msg[0] != '\0')
- ewritestr(ircfd, msg);
+ ewritestr(ircfd, msg);
}
static void