If n becomes 0 at the same time that the end of either s1 or s2 are
reached, the next iteration of the while loop wouldn't happen, so we
wouldn't correctly return 0.
rfc_casecmp was broken because reaching terminator for str1 was used as
a terminal condition and str2 may be shorter than str1, resulting in an
oob read condition for str2.
rfc_ncasecmp was broken because it checked if n characters were checked
or if BOTH pointers reached their terminator, however the strings may
be different lengths and also less than n characters in length, meaning
that they don't both reach their terminators at the same time,
resulting in an oob read condition.
If ptr[0] is NULL, then strchr may return a pointer to the NULL
terminator for serv->nick_prefixes, making the if statement true, which
then leads to the pointer increment leaving ptr oob. Now we check to
ensure ptr[0] != NULL.
From the Linux manpages for strchr:
The terminating null byte is considered part of the string, so that if c is
specified as '\0', these functions return a pointer to the terminator.