Bug #262
openusing ircnet bip crashes if a channel has two nicks different only by one "~"
50%
Description
nitram reported:
as soon as i join a channel that has the nicks "~mc" and "mc" on ircnet bip crashes with "11-11-2011 15:55:44 FATAL: Element with key mc already in hash b9495ce0
I found two problems:
First, in irc_353 function ( source:src/irc.c@a46b8bd2#L1362 ) we discard '~' character when storing operator/voice mask foreach nickname. For example if the irc server send'ircnet.optilian.net' ':ircnet.optilian.net 353 pilou = #plopplopplop :pilou ~lolll219 lolll219 ' (user pilou joining ircnet.optilian.net where tho users ~lolll219 lolll219 are here)
we store operator/voice mask of lolll219 twice (once for ~lolll219 and another for lolll219).
This lead to many errors:
- if either
lolll219or~lolll219have a not empty operator/voice mask, then problem reported by nitram appears: the secondhash_insertfails.
- when
~lolll219orlolll219send ircpartcommand,irc_partfunction ( source:src/irc.c@a46b8bd2#L1498 ) encounters problem.
If~lolll219quit then his operator/voice mask can not be found (it was not stored) and thenirc_partreturnERR_PROTOCOL:13-11-2011 14:38:22 ERROR: [ircnet] Error in protocol, closing... 13-11-2011 14:38:22 ERROR: [ircnet] reconnecting in 0 seconds
- If
lolll219quit then an assertion fails, indeed thelolll219key is present twice in the operator/voice mask hash:13-11-2011 14:37:29 FATAL: 80b3288 appears twice in list
Second problem: it should not be possible to store two identical key in one hash. list_remove_if_exists function ( source:src/util.c@a46b8bd2#L370 ) - called by irc_part - verify this assertion and the assertion fails.
Currently insertion of two identical keys occurs because instead of checking if the hash contains already an identical key, we check if the value corresponding to this key is NULL or not ( source:src/util.c@a46b8bd2#L566 ):
void hash_insert(hash_t *hash, const char *key, void *ptr)
[...]
if (hash_get(hash, key))
fatal("Element with key %s already in hash %x\n", key, hash);
So it's possible to store many identical key associated to 0/NULL value.
And the associated value for the key in operator/voice mask hash can be 0/NULL:
long int ovmask = 0; [...] hash_insert(&channel->ovmasks, nick, (void *)ovmask);
Files