Skip to content
Permalink
Browse files Browse the repository at this point in the history
irc: fix crash when a new message 005 is received with longer nick pr…
…efixes

Thanks to Stuart Nevans Locke for reporting the issue.
  • Loading branch information
flashcode committed Feb 9, 2020
1 parent 5edbeea commit 40ccacb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
1 change: 1 addition & 0 deletions ChangeLog.adoc
Expand Up @@ -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)
Expand Down
47 changes: 47 additions & 0 deletions src/plugins/irc/irc-nick.c
Expand Up @@ -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.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/irc/irc-nick.h
Expand Up @@ -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);
Expand Down
9 changes: 8 additions & 1 deletion src/plugins/irc/irc-server.c
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}

/*
Expand Down

2 comments on commit 40ccacb

@setharnold
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have a CVE number? If not, has anyone applied for one yet?

Thanks

@flashcode
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@setharnold: it's in progress, I'll put the CVE id as soon as possible on the security page: https://weechat.org/doc/security/

Please sign in to comment.