diff --git a/ChangeLog.adoc b/ChangeLog.adoc index ef1aa87fa..862c4d429 100644 --- a/ChangeLog.adoc +++ b/ChangeLog.adoc @@ -31,6 +31,7 @@ Bug fixes:: * core: fix memory leak in completion * core: flush stdout/stderr before forking in hook_process function (issue #1441) * core: fix evaluation of condition with nested "if" (issue #1434) + * irc: fix crash when a new message 005 is received with longer nick prefixes * irc: fix crash when receiving a malformed message 324 (channel mode) * irc: add nick changes in the hotlist (except self nick change) * irc: case-insensitive comparison on incoming CTCP command, force upper case on CTCP replies (issue #1439) diff --git a/src/plugins/irc/irc-nick.c b/src/plugins/irc/irc-nick.c index 5dbe3a256..06b9d79b7 100644 --- a/src/plugins/irc/irc-nick.c +++ b/src/plugins/irc/irc-nick.c @@ -643,6 +643,53 @@ irc_nick_set_mode (struct t_irc_server *server, struct t_irc_channel *channel, } } +/* + * Reallocates the "prefixes" string in all nicks of all channels on the server + * (after 005 has been received). + */ + +void +irc_nick_realloc_prefixes (struct t_irc_server *server, + int old_length, int new_length) +{ + struct t_irc_channel *ptr_channel; + struct t_irc_nick *ptr_nick; + char *new_prefixes; + + for (ptr_channel = server->channels; ptr_channel; + ptr_channel = ptr_channel->next_channel) + { + for (ptr_nick = ptr_channel->nicks; ptr_nick; + ptr_nick = ptr_nick->next_nick) + { + if (ptr_nick->prefixes) + { + new_prefixes = realloc (ptr_nick->prefixes, new_length + 1); + if (new_prefixes) + { + ptr_nick->prefixes = new_prefixes; + if (new_length > old_length) + { + memset (ptr_nick->prefixes + old_length, + ' ', + new_length - old_length); + } + ptr_nick->prefixes[new_length] = '\0'; + } + } + else + { + ptr_nick->prefixes = malloc (new_length + 1); + if (ptr_nick->prefixes) + { + memset (ptr_nick->prefixes, ' ', new_length); + ptr_nick->prefixes[new_length] = '\0'; + } + } + } + } +} + /* * Removes a nick from a channel. */ diff --git a/src/plugins/irc/irc-nick.h b/src/plugins/irc/irc-nick.h index caccb2932..a5f57ca41 100644 --- a/src/plugins/irc/irc-nick.h +++ b/src/plugins/irc/irc-nick.h @@ -74,6 +74,8 @@ extern void irc_nick_change (struct t_irc_server *server, extern void irc_nick_set_mode (struct t_irc_server *server, struct t_irc_channel *channel, struct t_irc_nick *nick, int set, char mode); +extern void irc_nick_realloc_prefixes (struct t_irc_server *server, + int old_length, int new_length); extern void irc_nick_free (struct t_irc_server *server, struct t_irc_channel *channel, struct t_irc_nick *nick); diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index eeacc06b7..d66b50657 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -988,11 +988,14 @@ irc_server_set_prefix_modes_chars (struct t_irc_server *server, const char *prefix) { char *pos; - int i, length_modes, length_chars; + int i, old_length_chars, length_modes, length_chars; if (!server || !prefix) return; + old_length_chars = (server->prefix_chars) ? + strlen (server->prefix_chars) : 0; + /* free previous values */ if (server->prefix_modes) { @@ -1032,6 +1035,10 @@ irc_server_set_prefix_modes_chars (struct t_irc_server *server, } } } + + length_chars = (server->prefix_chars) ? strlen (server->prefix_chars) : 0; + if (server->prefix_chars && (length_chars != old_length_chars)) + irc_nick_realloc_prefixes (server, old_length_chars, length_chars); } /*