X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/3ea5fee7ededf856288148f63cdca633c072f7a1..0284952c9f6edad14e18ce588cb21eb04d92c91f:/src/match.c?ds=sidebyside diff --git a/src/match.c b/src/match.c index 12e4c01..7ebc0c2 100644 --- a/src/match.c +++ b/src/match.c @@ -16,14 +16,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: match.c 3532 2007-07-14 13:32:18Z jilles $ * */ #include "stdinc.h" #include "config.h" #include "client.h" #include "ircd.h" -#include "irc_string.h" +#include "match.h" /* * Compare if a given string (name) matches the given @@ -178,11 +177,14 @@ int mask_match(const char *mask, const char *name) } +#define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this + and we have long lines to parse */ /** Check a string against a mask. - * This test checks using traditional IRC wildcards only: '*' means - * match zero or more characters of any type; '?' means match exactly - * one character of any type; '#' means match exactly one character - * that is a number. + * This test checks using extended wildcards: '*' means match zero + * or more characters of any type; '?' means match exactly one + * character of any type; '#' means match exactly one character that + * is a number; '@' means match exactly one character that is a + * letter; '\s' means match a space. * * This function supports escaping, so that a wildcard may be matched * exactly. @@ -191,96 +193,118 @@ int mask_match(const char *mask, const char *name) * @param[in] name String to check against \a mask. * @return Zero if \a mask matches \a name, non-zero if no match. */ -int match_esc(const char *mask, const char *name) +int +match_esc(const char *mask, const char *name) { - const char *m = mask, *n = name; - const char *m_tmp = mask, *n_tmp = name; - int star_p; + const unsigned char *m = (const unsigned char *)mask; + const unsigned char *n = (const unsigned char *)name; + const unsigned char *ma = (const unsigned char *)mask; + const unsigned char *na = (const unsigned char *)name; + int wild = 0; + int calls = 0; + int quote = 0; + int match1 = 0; s_assert(mask != NULL); s_assert(name != NULL); - for (;;) + if(!mask || !name) + return 0; + + /* if the mask is "*", it matches everything */ + if((*m == '*') && (*(m + 1) == '\0')) + return 1; + + while(calls++ < MATCH_MAX_CALLS) { - switch (*m) + if(quote) + quote++; + if(quote == 3) + quote = 0; + if(*m == '\\' && !quote) { - case '\0': - if (!*n) - return 1; - backtrack: - if (m_tmp == mask) - return 0; - m = m_tmp; - n = ++n_tmp; - break; - case '\\': - m++; - /* allow escaping to force capitalization */ - if (*m++ != *n++) - goto backtrack; - break; - case '*': - case '?': - for (star_p = 0;; m++) - { - if (*m == '*') - star_p = 1; - else if (*m == '?') - { - if (!*n++) - goto backtrack; - } - else - break; - } - if (star_p) - { - if (!*m) - return 1; - else if (*m == '\\') - { - m_tmp = ++m; - if (!*m) - return 0; - for (n_tmp = n; *n && *n != *m; n++); - } - else if (*m == '#') - { - m_tmp = m; - for (n_tmp = n; *n && !IsDigit(*n); n++); - } - else if (*m == '@') - { - m_tmp = m; - for (n_tmp = n; *n && !IsLetter(*n); n++); - } - else - { - m_tmp = m; - for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++); - } - } - /* and fall through */ - default: - if (!*n) - return (*m != '\0' ? 0 : 1); - if (*m == '#') - { - if (!IsDigit(*n)) - goto backtrack; - } - else if (*m == '@') - { - if (!IsLetter(*n)) - goto backtrack; - } - else if (ToLower(*m) != ToLower(*n)) - goto backtrack; - m++; - n++; - break; + m++; + quote = 1; + continue; + } + if(!quote && *m == '*') + { + /* + * XXX - shouldn't need to spin here, the mask should have been + * collapsed before match is called + */ + while(*m == '*') + m++; + + wild = 1; + ma = m; + na = n; + + if(*m == '\\') + { + m++; + /* This means it is an invalid mask -A1kmm. */ + if(!*m) + return 0; + quote++; + continue; + } + } + + if(!*m) + { + if(!*n) + return 1; + if(quote) + return 0; + for(m--; (m > (const unsigned char *)mask) && (*m == '?'); m--);; + + if(*m == '*' && (m > (const unsigned char *)mask)) + return 1; + if(!wild) + return 0; + m = ma; + n = ++na; + } + else if(!*n) + { + /* + * XXX - shouldn't need to spin here, the mask should have been + * collapsed before match is called + */ + if(quote) + return 0; + while(*m == '*') + m++; + return (*m == 0); + } + + if(quote) + match1 = *m == 's' ? *n == ' ' : ToLower(*m) == ToLower(*n); + else if(*m == '?') + match1 = 1; + else if(*m == '@') + match1 = IsLetter(*n); + else if(*m == '#') + match1 = IsDigit(*n); + else + match1 = ToLower(*m) == ToLower(*n); + if(match1) + { + if(*m) + m++; + if(*n) + n++; + } + else + { + if(!wild) + return 0; + m = ma; + n = ++na; } } + return 0; } int comp_with_mask(void *addr, void *dest, u_int mask) @@ -307,7 +331,7 @@ int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask iaddr = &((struct sockaddr_in *)addr)->sin_addr; idest = &((struct sockaddr_in *)dest)->sin_addr; } -#ifdef IPV6 +#ifdef RB_IPV6 else { iaddr = &((struct sockaddr_in6 *)addr)->sin6_addr; @@ -346,7 +370,7 @@ int match_ips(const char *s1, const char *s2) if (cidrlen == 0) return 0; -#ifdef IPV6 +#ifdef RB_IPV6 if (strchr(mask, ':') && strchr(address, ':')) { aftype = AF_INET6; @@ -364,8 +388,8 @@ int match_ips(const char *s1, const char *s2) else return 0; - inetpton(aftype, address, ipptr); - inetpton(aftype, mask, maskptr); + rb_inet_pton(aftype, address, ipptr); + rb_inet_pton(aftype, mask, maskptr); if (comp_with_mask(ipptr, maskptr, cidrlen)) return 1; else @@ -414,7 +438,7 @@ int match_cidr(const char *s1, const char *s2) if (cidrlen == 0) return 0; -#ifdef IPV6 +#ifdef RB_IPV6 if (strchr(ip, ':') && strchr(ipmask, ':')) { aftype = AF_INET6; @@ -432,8 +456,8 @@ int match_cidr(const char *s1, const char *s2) else return 0; - inetpton(aftype, ip, ipptr); - inetpton(aftype, ipmask, maskptr); + rb_inet_pton(aftype, ip, ipptr); + rb_inet_pton(aftype, ipmask, maskptr); if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address)) return 1; else @@ -677,7 +701,7 @@ const unsigned int CharAttrs[] = { /* , */ PRINT_C | NONEOS_C, /* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C, /* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C, -/* / */ PRINT_C | CHAN_C | NONEOS_C, +/* / */ PRINT_C | CHAN_C | NONEOS_C | HOST_C, /* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C, /* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C, /* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,