X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fmatch.c;h=65d44198e6a25b82f81e31a5ee09b9b3c130eaa2;hb=43ba45ce62100bc1dbc9b04b5d869f59026783f5;hp=d4c3008ba38286fbb23824e5d59303bb3d6f4dde;hpb=fa0798c026131e183625e88dab4fb33b552cbb7e;p=exim.git diff --git a/src/src/match.c b/src/src/match.c index d4c3008ba..65d44198e 100644 --- a/src/src/match.c +++ b/src/src/match.c @@ -106,7 +106,7 @@ void *handle; error = error; /* Keep clever compilers from complaining */ -if (valueptr != NULL) *valueptr = NULL; /* For non-lookup matches */ +if (valueptr) *valueptr = NULL; /* For regular expressions, use cb->origsubject rather than cb->subject so that it works if the pattern uses (?-i) to turn off case-independence, overriding @@ -120,7 +120,7 @@ expand_nmax until the match is assured. */ expand_nmax = -1; if (expand_setup == 0) { - expand_nstring[0] = s; + expand_nstring[0] = s; /* $0 (might be) the matched subject in full */ expand_nlength[0] = Ustrlen(s); } else if (expand_setup > 0) expand_setup--; @@ -131,11 +131,13 @@ required. */ if (pattern[0] == '^') { const pcre * re = regex_must_compile(pattern, cb->caseless, FALSE); - return (expand_setup < 0 - ? pcre_exec(re, NULL, CCS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) >= 0 - : regex_match_and_setup(re, s, 0, expand_setup) - ) - ? OK : FAIL; + if (expand_setup < 0 + ? pcre_exec(re, NULL, CCS s, Ustrlen(s), 0, PCRE_EOPT, NULL, 0) < 0 + : !regex_match_and_setup(re, s, 0, expand_setup) + ) + return FAIL; + if (valueptr) *valueptr = pattern; /* "value" gets the RE */ + return OK; } /* Tail match */ @@ -153,11 +155,11 @@ if (pattern[0] == '*') return FAIL; if (expand_setup >= 0) { - expand_nstring[++expand_setup] = s; + expand_nstring[++expand_setup] = s; /* write a $n, the matched subject variable-part */ expand_nlength[expand_setup] = slen - patlen; - expand_nmax = expand_setup; + expand_nmax = expand_setup; /* commit also $0, the matched subject */ } - if (valueptr) *valueptr = pattern; + if (valueptr) *valueptr = pattern - 1; /* "value" gets the (original) pattern */ return OK; } @@ -177,12 +179,13 @@ if (cb->at_is_special && pattern[0] == '@') if (Ustrcmp(pattern, "@[]") == 0) { int slen = Ustrlen(s); - if (s[0] != '[' && s[slen-1] != ']') return FAIL; + if (s[0] != '[' && s[slen-1] != ']') return FAIL; /*XXX should this be || ? */ for (ip_address_item * ip = host_find_interfaces(); ip; ip = ip->next) if (Ustrncmp(ip->address, s+1, slen - 2) == 0 && ip->address[slen - 2] == 0) { - if (valueptr) *valueptr = pattern; + if (expand_setup >= 0) expand_nmax = expand_setup; /* commit $0, the IP addr */ + if (valueptr) *valueptr = pattern; /* "value" gets the pattern */ return OK; } return FAIL; @@ -234,9 +237,11 @@ if (cb->at_is_special && pattern[0] == '@') return DEFER; } - if (rc != HOST_FOUND_LOCAL || secy) - if (prim || !removed) return FAIL; - if (valueptr) *valueptr = pattern; + if ((rc != HOST_FOUND_LOCAL || secy) && (prim || !removed)) + return FAIL; + + if (expand_setup >= 0) expand_nmax = expand_setup; /* commit $0, the matched subject */ + if (valueptr) *valueptr = pattern; /* "value" gets the patterm */ return OK; /*** The above line used to be the following line, but this is incorrect, @@ -259,21 +264,9 @@ if ((semicolon = Ustrchr(pattern, ';')) == NULL) { if (cb->caseless ? strcmpic(s, pattern) != 0 : Ustrcmp(s, pattern) != 0) return FAIL; - if (expand_setup >= 0) expand_nmax = expand_setup; - if (valueptr) *valueptr = pattern; + if (expand_setup >= 0) expand_nmax = expand_setup; /* Original code! $0 gets the matched subject */ + if (valueptr) *valueptr = pattern; /* "value" gets the pattern */ return OK; - -/* -XXX looks like $0 may be usable -XXX could add setting of *valueptr to all the OK returns; seems doable here, the Q - is: what effect would it have at config-file level. domain_data & local_part_data - would get filled in... might anyone be checking it for emptiness? I think the docs - do not say "will be empty otherwise", so that seems ok. -XXX WORRY: we get new caching of named-list match results. Is that cache checked - for the key being matched? -XXX could also add $0 fill-in with the matching text for pattern? RE already has it, - tailmatch already has it, @[] => dotted.quad.etc, @mx => h->address ? -*/ } /* Otherwise we have a lookup item. The lookup type, including partial, etc. is @@ -357,7 +350,7 @@ match_check_string(const uschar *s, const uschar *pattern, int expand_setup, { check_string_block cb; cb.origsubject = s; -cb.subject = caseless? string_copylc(s) : string_copy(s); +cb.subject = caseless ? string_copylc(s) : string_copy(s); cb.expand_setup = expand_setup; cb.use_partial = use_partial; cb.caseless = caseless; @@ -389,13 +382,13 @@ switch(type) case MCL_STRING: case MCL_DOMAIN: case MCL_LOCALPART: - return ((check_string_block *)arg)->subject; + return ((check_string_block *)arg)->subject; case MCL_HOST: - return ((check_host_block *)arg)->host_address; + return ((check_host_block *)arg)->host_address; case MCL_ADDRESS: - return ((check_address_block *)arg)->address; + return ((check_address_block *)arg)->address; } return US""; /* In practice, should never happen */ } @@ -694,7 +687,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) nb->cache_data = p; if (*valueptr) DEBUG(D_lists) debug_printf("data from lookup saved for " - "cache for %s: %s\n", ss, *valueptr); + "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr); } } } @@ -706,7 +699,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0))) else { DEBUG(D_lists) debug_printf("cached %s match for %s\n", - ((bits & (-bits)) == bits)? "yes" : "no", ss); + (bits & (-bits)) == bits ? "yes" : "no", ss); cached = US" - cached"; if (valueptr) @@ -968,12 +961,17 @@ match_isinlist(const uschar *s, const uschar **listptr, int sep, unsigned int *local_cache_bits = cache_bits; check_string_block cb; cb.origsubject = s; -cb.subject = caseless? string_copylc(s) : string_copy(s); -cb.expand_setup = (sep > UCHAR_MAX)? 0 : -1; +cb.subject = caseless ? string_copylc(s) : string_copy(s); +cb.at_is_special = FALSE; +switch (type & ~MCL_NOEXPAND) + { + case MCL_DOMAIN: cb.at_is_special = TRUE; /*FALLTHROUGH*/ + case MCL_LOCALPART: cb.expand_setup = 0; break; + default: cb.expand_setup = sep > UCHAR_MAX ? 0 : -1; break; + } cb.use_partial = TRUE; cb.caseless = caseless; -cb.at_is_special = (type == MCL_DOMAIN || type == MCL_DOMAIN + MCL_NOEXPAND); -if (valueptr != NULL) *valueptr = NULL; +if (valueptr) *valueptr = NULL; return match_check_list(listptr, sep, anchorptr, &local_cache_bits, check_string, &cb, type, s, valueptr); }