fix possible crash on user deletion
[srvx.git] / src / tools.c
index 8f0c2998cfe8cb719212a6a577c6a7370a30f0ec..b10bc7be4379b5b573008142c58bb539ffe9c9c3 100644 (file)
@@ -316,6 +316,8 @@ irc_pton(irc_in_addr_t *addr, unsigned char *bits, const char *input)
         uint32_t ip4;
         pos = irc_pton_ip4(input, bits, &ip4);
         if (pos) {
+/* glibc's htons() macro is not -Wshadow-safe. */
+#undef htons
             addr->in6[5] = htons(65535);
             addr->in6[6] = htons(ntohl(ip4) >> 16);
             addr->in6[7] = htons(ntohl(ip4) & 65535);
@@ -385,6 +387,14 @@ irccasestr(const char *haystack, const char *needle) {
     return NULL;
 }
 
+char *
+ircstrlower(char *str) {
+    size_t ii;
+    for (ii = 0; str[ii] != '\0'; ++ii)
+        str[ii] = tolower(str[ii]);
+    return str;
+}
+
 int
 split_line(char *line, int irc_colon, int argv_size, char *argv[])
 {
@@ -581,7 +591,9 @@ extern const char *hidden_host_suffix;
 int
 user_matches_glob(struct userNode *user, const char *orig_glob, int flags)
 {
+    irc_in_addr_t mask;
     char *glob, *marker;
+    unsigned char mask_bits;
 
     /* Make a writable copy of the glob */
     glob = alloca(strlen(orig_glob)+1);
@@ -602,7 +614,8 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int flags)
         return 0;
     }
     *marker = 0;
-    if (!match_ircglob(user->ident, glob))
+    if (((IsFakeIdent(user) && IsHiddenHost(user) && (flags & MATCH_VISIBLE)) || !match_ircglob(user->ident, glob)) &&
+        !(IsFakeIdent(user) && match_ircglob(user->fakeident, glob)))
         return 0;
     glob = marker + 1;
     /* Check for a fakehost match. */
@@ -620,8 +633,8 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int flags)
         && (IsFakeHost(user) || (hidden_host_suffix && user->handle_info)))
         return 0;
     /* If it might be an IP glob, test that. */
-    if (!glob[strspn(glob, "0123456789./*?")]
-        && match_ircglob(irc_ntoa(&user->ip), glob))
+    if (irc_pton(&mask, &mask_bits, glob)
+        && irc_check_mask(&user->ip, &mask, mask_bits))
         return 1;
     /* None of the above; could only be a hostname match. */
     return match_ircglob(user->hostname, glob);