AmendHub

Download:

jcs

/

wallops

/

amendments

/

84

irc: Cope with input buffer getting full of non-lines

This should only happen on a rogue server, but we shouldn't fall
over ourselves dealing with it.

jcs made amendment 84 2 months ago
--- irc.c Wed Sep 11 09:58:59 2024 +++ irc.c Wed Sep 11 16:25:38 2024 @@ -359,10 +359,23 @@ irc_get_line(struct irc_connection *conn, size_t *rets if (conn->ibuf[n + 1] != '\n') continue; - memcpy(conn->line, conn->ibuf, n + 1); - conn->line[n] = '\0'; - if (retsize != NULL) - *retsize = n + 1; + if (conn->flushing_ibuf) { + conn->flushing_ibuf = false; + conn->line[0] = '\0'; + } else if (n + 1 >= sizeof(conn->line) - 1) { + /* + * Line is too long to process but we can't take part of it, + * so bail on it and hope it wasn't something important :( + */ + chatter_printf(conn->chatter, NULL, NULL, + "*!* Line too long to process"); + conn->line[0] = '\0'; + } else { + memcpy(conn->line, conn->ibuf, n + 1); + conn->line[n] = '\0'; + if (retsize != NULL) + *retsize = n + 1; + } if (n == conn->ibuflen - 2) { conn->ibuflen = 0; @@ -375,6 +388,18 @@ irc_get_line(struct irc_connection *conn, size_t *rets return conn->line; } + if (n >= sizeof(conn->ibuf) - 1) { + /* + * ibuf is full with no newline but we can't empty the buffer and + * start the next iteration in the middle of this line, so + * consider ibuf bogus until we see a newline. + */ + conn->flushing_ibuf = true; + conn->ibuflen = 0; + chatter_printf(conn->chatter, NULL, NULL, + "*!* ibuf with no newline, flushing"); + } + return NULL; } @@ -411,7 +436,10 @@ irc_process_server(struct irc_connection *conn) memset(&msg, 0, sizeof(msg)); word = strsep(&line, " "); - + if (word == NULL) + /* server sent us a blank line? */ + return false; + /* extract source before command */ if (word[0] == ':') { /* ":server.name 001 jcs :Hi" -> msg.source=server.name */ @@ -667,6 +695,7 @@ irc_process_server(struct irc_connection *conn) if ((channel = irc_find_channel(conn, msg.arg[0]))) { if (strcmp(user->nick, conn->nick) == 0) { irc_dealloc_channel(channel); + channel = NULL; /* we don't need to print anything */ } else { irc_remove_nick_from_channel(channel, user->nick); @@ -1179,10 +1208,8 @@ irc_create_channel(struct irc_connection *conn, char * short n; SLIST_FOREACH(channel, &conn->channels_list, list) { - if (strcasecmp(channel->name, channame) == 0) { - /* TODO: chatter_switch_to_channel(channel) */ + if (strcasecmp(channel->name, channame) == 0) return channel; - } } channel = xmalloczero(sizeof(struct irc_channel)); --- irc.h Tue Sep 10 09:17:34 2024 +++ irc.h Wed Sep 11 15:54:07 2024 @@ -92,6 +92,7 @@ struct irc_connection { char line[512]; short ibuflen; short linelen; + bool flushing_ibuf; /* docs say 4*MTU+1024, but MTU will probably be <1500 */ unsigned char tcp_buf[(4 * 1500) + 2048]; };