diff options
author | dequis <dx@dxzone.com.ar> | 2015-12-05 21:43:14 -0300 |
---|---|---|
committer | dequis <dx@dxzone.com.ar> | 2015-12-05 21:43:14 -0300 |
commit | f4396c4d16f67cb28effd86a636b9db8fa48821c (patch) | |
tree | e9efab31eab56eb76b9d88d3f99e96627a017422 | |
parent | ed431c389887080dc4fa45e30d051ce733f4ce57 (diff) |
irc_send_names: refactor to use GString instead of the stack
Because modifying this code was making me REALLY uncomfortable.
This still only allocates memory once. Needing to extend the string
would be a bug in the length checks, but at least that's harmless now.
-rw-r--r-- | irc_send.c | 27 |
1 files changed, 17 insertions, 10 deletions
@@ -201,34 +201,41 @@ void irc_send_kick(irc_channel_t *ic, irc_user_t *iu, irc_user_t *kicker, const kicker->host, ic->name, iu->nick, reason ? : ""); } +#define IRC_NAMES_LEN 385 + void irc_send_names(irc_channel_t *ic) { GSList *l; - char namelist[385] = ""; + GString *namelist = g_string_sized_new(IRC_NAMES_LEN); /* RFCs say there is no error reply allowed on NAMES, so when the channel is invalid, just give an empty reply. */ for (l = ic->users; l; l = l->next) { irc_channel_user_t *icu = l->data; irc_user_t *iu = icu->iu; + size_t extra_len = strlen(iu->nick); + char prefix; - if (strlen(namelist) + strlen(iu->nick) > sizeof(namelist) - 4) { - irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist); - *namelist = 0; + if (namelist->len + extra_len > IRC_NAMES_LEN - 4) { + irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str); + g_string_truncate(namelist, 0); } - namelist[strlen(namelist) + 1] = '\0'; - namelist[strlen(namelist)] = irc_channel_user_get_prefix(icu); + if ((prefix = irc_channel_user_get_prefix(icu))) { + g_string_append_c(namelist, prefix); + } - strcat(namelist, iu->nick); - strcat(namelist, " "); + g_string_append(namelist, iu->nick); + g_string_append_c(namelist, ' '); } - if (*namelist) { - irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist); + if (namelist->len) { + irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str); } irc_send_num(ic->irc, 366, "%s :End of /NAMES list", ic->name); + + g_string_free(namelist, TRUE); } void irc_send_topic(irc_channel_t *ic, gboolean topic_change) |