static int match_tail(const char *word, Segment seg[], int nseg, int nstar, int spare) { int code; for (; nseg; seg++,nseg--) { code = seg[0].code; if (code < 0) { /* (-code) single wildcards "#" */ word += (-code); }else if (seg[0].code > 0) { /* literal text */ if (strncmp(word, seg[0].text, code) != 0) { return 0; } word += code; }else{ /* multiple wildcard "*" */ if (nstar) { for (; spare >= 0; word++,spare--) { if (match_tail(word, seg+1, nseg-1, nstar-1, spare)) { return 1; /* tail matched */ } } return 0; }else{ return match_tail(word+spare, seg+1, nseg-1, 0, 0); } } } return (word[0]=='\0'); }
/* Checks whether string S matches each element of ACCEPTS. A list element are matched either with fnmatch() or match_tail(), according to whether the element contains wildcards or not. If the BACKWARD is 0, don't do backward comparison -- just compare them normally. */ static int in_acclist (const char *const *accepts, const char *s, int backward) { for (; *accepts; accepts++) { if (has_wildcards_p (*accepts)) { /* fnmatch returns 0 if the pattern *does* match the string. */ if (fnmatch (*accepts, s, 0) == 0) return 1; } else { if (backward) { if (match_tail (s, *accepts)) return 1; } else { if (!strcmp (s, *accepts)) return 1; } } } return 0; }
static int check_domain_match (const char *cookie_domain, const char *host) { static char *special_toplevel_domains[] = { ".com", ".edu", ".net", ".org", ".gov", ".mil", ".int" }; int i, required_dots; DEBUGP (("cdm: 1")); /* Numeric address requires exact match. It also requires HOST to be an IP address. */ if (numeric_address_p (cookie_domain)) return 0 == strcmp (cookie_domain, host); DEBUGP ((" 2")); /* For the sake of efficiency, check for exact match first. */ if (!strcasecmp (cookie_domain, host)) return 1; DEBUGP ((" 3")); required_dots = 3; for (i = 0; i < ARRAY_SIZE (special_toplevel_domains); i++) if (match_tail (cookie_domain, special_toplevel_domains[i])) { required_dots = 2; break; } /* If the domain does not start with '.', require one less dot. This is so that domains like "altavista.com" (which should be ".altavista.com") are accepted. */ if (*cookie_domain != '.') --required_dots; if (count_char (cookie_domain, '.') < required_dots) return 0; DEBUGP ((" 4")); if (!match_tail (host, cookie_domain)) return 0; DEBUGP ((" 5")); /* Don't allow domain "bar.com" to match host "foobar.com". */ if (*cookie_domain != '.') { int dlen = strlen (cookie_domain); int hlen = strlen (host); /* cookie host: hostname.foobar.com */ /* desired domain: bar.com */ /* '.' must be here in host-> ^ */ if (hlen > dlen && host[hlen - dlen - 1] != '.') return 0; } DEBUGP ((" 6")); return 1; }
int match_word(const char *word) { int spare = strlen(word) - match_min; if (spare < 0) return 0; return match_tail(word, segment, numseg, numstar, spare); }