X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f3ebb786e451da973560f1c9d8cdb151d25108b5..ecb371298ce4ab016d055de06cff252098e6e603:/src/src/filter.c diff --git a/src/src/filter.c b/src/src/filter.c index 3da616700..1dbae43e9 100644 --- a/src/src/filter.c +++ b/src/src/filter.c @@ -3,6 +3,7 @@ *************************************************/ /* Copyright (c) University of Cambridge 1995 - 2018 */ +/* Copyright (c) The Exim Maintainers 2020 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -50,7 +51,7 @@ typedef struct condition_block { /* Miscellaneous other declarations */ static uschar **error_pointer; -static uschar *log_filename; +static const uschar *log_filename; static int filter_options; static int line_number; static int expect_endif; @@ -1424,10 +1425,7 @@ static BOOL test_condition(condition_block *c, BOOL toplevel) { BOOL yield = FALSE; -const pcre *re; uschar *exp[2], *p, *pp; -const uschar *regcomp_error = NULL; -int regcomp_error_offset; int val[2]; int i; @@ -1510,7 +1508,7 @@ switch (c->type) parse_extract_address(pp, &error, &start, &end, &domain, FALSE); *p = saveend; - if (filter_thisaddress != NULL) + if (filter_thisaddress) { if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0) @@ -1587,28 +1585,34 @@ switch (c->type) case cond_matches: case cond_MATCHES: - if ((filter_test != FTEST_NONE && debug_selector != 0) || - (debug_selector & D_filter) != 0) { - debug_printf_indent("Match expanded arguments:\n"); - debug_printf_indent(" Subject = %s\n", exp[0]); - debug_printf_indent(" Pattern = %s\n", exp[1]); - } + const pcre2_code *re; + int err; + PCRE2_SIZE offset; - re = pcre_compile(CS exp[1], - PCRE_COPT | ((c->type == cond_matches)? PCRE_CASELESS : 0), - (const char **)®comp_error, ®comp_error_offset, NULL); + if ((filter_test != FTEST_NONE && debug_selector != 0) || + (debug_selector & D_filter) != 0) + { + debug_printf_indent("Match expanded arguments:\n"); + debug_printf_indent(" Subject = %s\n", exp[0]); + debug_printf_indent(" Pattern = %s\n", exp[1]); + } - if (re == NULL) - { - *error_pointer = string_sprintf("error while compiling " - "regular expression \"%s\": %s at offset %d", - exp[1], regcomp_error, regcomp_error_offset); - return FALSE; - } + if (!(re = pcre2_compile((PCRE2_SPTR)exp[1], PCRE2_ZERO_TERMINATED, + PCRE_COPT | (c->type == cond_matches ? PCRE2_CASELESS : 0), + &err, &offset, pcre_cmp_ctx))) + { + uschar errbuf[128]; + pcre2_get_error_message(err, errbuf, sizeof(errbuf)); + *error_pointer = string_sprintf("error while compiling " + "regular expression \"%s\": %s at offset %ld", + exp[1], errbuf, (long)offset); + return FALSE; + } - yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1); - break; + yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1); + break; + } /* For above and below, convert the strings to numbers */ @@ -1669,7 +1673,7 @@ Returns: FF_DELIVERED success, a significant action was taken static int interpret_commands(filter_cmd *commands, address_item **generated) { -uschar *s; +const uschar *s; int mode; address_item *addr; BOOL condition_value; @@ -1678,7 +1682,7 @@ while (commands) { int ff_ret; uschar *fmsg, *ff_name; - uschar *expargs[MAILARGS_STRING_COUNT]; + const uschar *expargs[MAILARGS_STRING_COUNT]; int i, n[2]; @@ -1710,7 +1714,7 @@ while (commands) case add_command: for (i = 0; i < 2; i++) { - uschar *ss = expargs[i]; + const uschar *ss = expargs[i]; uschar *end; if (i == 1 && (*ss++ != 'n' || ss[1] != 0)) @@ -1749,11 +1753,11 @@ while (commands) uschar *error; uschar *ss = parse_extract_address(s, &error, &start, &end, &domain, FALSE); - if (ss != NULL) - expargs[i] = ((filter_options & RDO_REWRITE) != 0)? - rewrite_address(ss, TRUE, FALSE, global_rewrite_rules, - rewrite_existflags) : - rewrite_address_qualify(ss, TRUE); + if (ss) + expargs[i] = filter_options & RDO_REWRITE + ? rewrite_address(ss, TRUE, FALSE, global_rewrite_rules, + rewrite_existflags) + : rewrite_address_qualify(ss, TRUE); else { *error_pointer = string_sprintf("malformed address \"%s\" in " @@ -1807,9 +1811,8 @@ while (commands) af_ignore_error flag if necessary, and the errors address, which can be set in a system filter and to the local address in user filters. */ - addr = deliver_make_addr(expargs[0], TRUE); /* TRUE => copy s */ - addr->prop.errors_address = (s == NULL)? - s : string_copy(s); /* Default is NULL */ + addr = deliver_make_addr(US expargs[0], TRUE); /* TRUE => copy s, so deconst ok */ + addr->prop.errors_address = !s ? NULL : string_copy(s); /* Default is NULL */ if (commands->noerror) addr->prop.ignore_error = TRUE; addr->next = *generated; *generated = addr; @@ -1849,7 +1852,7 @@ while (commands) af_pfr and af_file flags, the af_ignore_error flag if necessary, and the mode value. */ - addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */ + addr = deliver_make_addr(US s, TRUE); /* TRUE => copy s, so deconst ok */ setflag(addr, af_pfr); setflag(addr, af_file); if (commands->noerror) addr->prop.ignore_error = TRUE; @@ -1879,7 +1882,7 @@ while (commands) each command argument is expanded in the transport after the command has been split up into separate arguments. */ - addr = deliver_make_addr(s, TRUE); /* TRUE => copy s */ + addr = deliver_make_addr(US s, TRUE); /* TRUE => copy s, so deconst ok */ setflag(addr, af_pfr); setflag(addr, af_expand_pipe); if (commands->noerror) addr->prop.ignore_error = TRUE; @@ -1953,7 +1956,7 @@ while (commands) (long int)geteuid()); if (log_fd < 0) { - if (log_filename == NULL) + if (!log_filename) { *error_pointer = US"attempt to obey \"logwrite\" command " "without a previous \"logfile\""; @@ -1962,7 +1965,7 @@ while (commands) log_fd = Uopen(log_filename, O_CREAT|O_APPEND|O_WRONLY, log_mode); if (log_fd < 0) { - *error_pointer = string_open_failed(errno, "filter log file \"%s\"", + *error_pointer = string_open_failed("filter log file \"%s\"", log_filename); return FF_ERROR; } @@ -1976,9 +1979,8 @@ while (commands) } } else - { - DEBUG(D_filter) debug_printf_indent("skipping logwrite (verifying or testing)\n"); - } + DEBUG(D_filter) + debug_printf_indent("skipping logwrite (verifying or testing)\n"); break; /* Header addition and removal is available only in the system filter. The @@ -1991,16 +1993,19 @@ while (commands) s = expargs[0]; if (filter_test != FTEST_NONE) - printf("Headers %s \"%s\"\n", (subtype == TRUE)? "add" : - (subtype == FALSE)? "remove" : "charset", string_printing(s)); + printf("Headers %s \"%s\"\n", + subtype == TRUE ? "add" + : subtype == FALSE ? "remove" + : "charset", + string_printing(s)); if (subtype == TRUE) { while (isspace(*s)) s++; - if (s[0] != 0) + if (*s) { - header_add(htype_other, "%s%s", s, (s[Ustrlen(s)-1] == '\n')? - "" : "\n"); + header_add(htype_other, "%s%s", s, + s[Ustrlen(s)-1] == '\n' ? "" : "\n"); header_last->type = header_checkname(header_last, FALSE); if (header_last->type >= 'a') header_last->type = htype_other; } @@ -2009,11 +2014,9 @@ while (commands) else if (subtype == FALSE) { int sep = 0; - uschar *ss; - const uschar *list = s; - uschar buffer[128]; - while ((ss = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) - != NULL) + const uschar * list = s; + + for (uschar * ss; ss = string_nextinlist(&list, &sep, NULL, 0); ) header_remove(0, ss); } @@ -2043,18 +2046,18 @@ while (commands) ff_name = US"freeze"; ff_ret = FF_FREEZE; - DEFERFREEZEFAIL: - fmsg = expargs[0]; - if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, US" ... (truncated)"); - fmsg = US string_printing(fmsg); - *error_pointer = fmsg; + DEFERFREEZEFAIL: + *error_pointer = fmsg = US string_printing(Ustrlen(expargs[0]) > 1024 + ? string_sprintf("%.1000s ... (truncated)", expargs[0]) + : string_copy(expargs[0])); if (filter_test != FTEST_NONE) { indent(); printf("%c%s text \"%s\"\n", toupper(ff_name[0]), ff_name+1, fmsg); } - else DEBUG(D_filter) debug_printf_indent("Filter: %s \"%s\"\n", ff_name, fmsg); + else + DEBUG(D_filter) debug_printf_indent("Filter: %s \"%s\"\n", ff_name, fmsg); return ff_ret; case finish_command: @@ -2064,19 +2067,19 @@ while (commands) printf("%sinish\n", (commands->seen)? "Seen f" : "F"); } else - { DEBUG(D_filter) debug_printf_indent("Filter: %sfinish\n", - (commands->seen)? " Seen " : ""); - } + commands->seen ? " Seen " : ""); finish_obeyed = TRUE; - return filter_delivered? FF_DELIVERED : FF_NOTDELIVERED; + return filter_delivered ? FF_DELIVERED : FF_NOTDELIVERED; case if_command: { uschar *save_address = filter_thisaddress; int ok = FF_DELIVERED; condition_value = test_condition(commands->args[0].c, TRUE); - if (*error_pointer != NULL) ok = FF_ERROR; else + if (*error_pointer) + ok = FF_ERROR; + else { output_indent += 2; ok = interpret_commands(commands->args[condition_value? 1:2].f, @@ -2084,7 +2087,7 @@ while (commands) output_indent -= 2; } filter_thisaddress = save_address; - if (finish_obeyed || (ok != FF_DELIVERED && ok != FF_NOTDELIVERED)) + if (finish_obeyed || ok != FF_DELIVERED && ok != FF_NOTDELIVERED) return ok; } break; @@ -2096,7 +2099,7 @@ while (commands) case mail_command: case vacation_command: - if (return_path == NULL || return_path[0] == 0) + if (!return_path || !*return_path) { if (filter_test != FTEST_NONE) printf("%s command ignored because return_path is empty\n", @@ -2126,10 +2129,10 @@ while (commands) for (i = 0; i < MAILARGS_STRING_COUNT; i++) { - uschar *p; - uschar *s = expargs[i]; + const uschar *p; + const uschar *s = expargs[i]; - if (s == NULL) continue; + if (!s) continue; if (i != mailarg_index_text) for (p = s; *p != 0; p++) { @@ -2161,12 +2164,12 @@ while (commands) else { - uschar *pp; + const uschar *pp; for (pp = p + 1;; pp++) { c = *pp; if (c == ':' && pp != p + 1) break; - if (c == 0 || c == ':' || isspace(*pp)) + if (!c || c == ':' || isspace(c)) { *error_pointer = string_sprintf("\\n not followed by space or " "valid header name in \"%.1024s\" in %s command", @@ -2181,7 +2184,7 @@ while (commands) /* The string is OK */ - commands->args[i].u = s; + commands->args[i].u = s; /*XXX loses track of const */ } /* Proceed with mail or vacation command */ @@ -2196,7 +2199,7 @@ while (commands) commands->noerror ? " (noerror)" : ""); for (i = 1; i < MAILARGS_STRING_COUNT; i++) { - uschar *arg = commands->args[i].u; + const uschar *arg = commands->args[i].u; if (arg) { int len = Ustrlen(mailargs[i]); @@ -2369,8 +2372,9 @@ Returns: TRUE if the message is deemed to be personal BOOL filter_personal(string_item *aliases, BOOL scan_cc) { -uschar *self, *self_from, *self_to; -uschar *psself = NULL, *psself_from = NULL, *psself_to = NULL; +const uschar *self, *self_from, *self_to; +uschar *psself = NULL; +const uschar *psself_from = NULL, *psself_to = NULL; rmark reset_point = store_mark(); BOOL yield; header_line *h; @@ -2388,12 +2392,11 @@ Previously the test was for "auto-". */ for (h = header_list; h; h = h->next) { - uschar *s; if (h->type == htype_old) continue; if (strncmpic(h->text, US"List-", 5) == 0) { - s = h->text + 5; + uschar * s = h->text + 5; if (strncmpic(s, US"Id:", 3) == 0 || strncmpic(s, US"Help:", 5) == 0 || strncmpic(s, US"Subscribe:", 10) == 0 || @@ -2406,12 +2409,12 @@ for (h = header_list; h; h = h->next) else if (strncmpic(h->text, US"Auto-submitted:", 15) == 0) { - s = h->text + 15; - while (isspace(*s)) s++; + uschar * s = h->text + 15; + Uskip_whitespace(&s); if (strncmpic(s, US"no", 2) != 0) return FALSE; s += 2; - while (isspace(*s)) s++; - if (*s != 0) return FALSE; + Uskip_whitespace(&s); + if (*s) return FALSE; } } @@ -2424,18 +2427,18 @@ self_to = rewrite_one(self, rewrite_to, NULL, FALSE, US"", global_rewrite_rules); -if (self_from == NULL) self_from = self; -if (self_to == NULL) self_to = self; +if (!self_from) self_from = self; +if (self_to) self_to = self; /* If there's a prefix or suffix set, we must include the prefixed/ suffixed version of the local part in the tests. */ -if (deliver_localpart_prefix != NULL || deliver_localpart_suffix != NULL) +if (deliver_localpart_prefix || deliver_localpart_suffix) { psself = string_sprintf("%s%s%s@%s", - (deliver_localpart_prefix == NULL)? US"" : deliver_localpart_prefix, + deliver_localpart_prefix ? deliver_localpart_prefix : US"", deliver_localpart, - (deliver_localpart_suffix == NULL)? US"" : deliver_localpart_suffix, + deliver_localpart_suffix ? deliver_localpart_suffix : US"", deliver_domain); psself_from = rewrite_one(psself, rewrite_from, NULL, FALSE, US"", global_rewrite_rules); @@ -2505,7 +2508,7 @@ filter_interpret(uschar *filter, int options, address_item **generated, int i; int yield = FF_ERROR; uschar *ptr = filter; -uschar *save_headers_charset = headers_charset; +const uschar *save_headers_charset = headers_charset; filter_cmd *commands = NULL; filter_cmd **lastcmdptr = &commands;