Use %ld not %l
[exim.git] / src / src / filter.c
index c5081698f33533e205eead4f27a364b87b9d977a..dfcc80271f1b08efef0b2286221d2c0a59f8777a 100644 (file)
@@ -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;
 
@@ -1587,26 +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;
 
-    if (!(re = pcre_compile(CS exp[1],
-      PCRE_COPT | ((c->type == cond_matches)? PCRE_CASELESS : 0),
-      CCSS &regcomp_error, &regcomp_error_offset, 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 ((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]);
+       }
 
-    yield = regex_match_and_setup(re, exp[0], PCRE_EOPT, -1);
-    break;
+      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;
+      }
 
     /* For above and below, convert the strings to numbers */
 
@@ -1667,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;
@@ -1676,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];
 
@@ -1708,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))
@@ -1805,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;
@@ -1847,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;
@@ -1877,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;
@@ -1951,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\"";
@@ -1960,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;
            }
@@ -1974,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
@@ -2007,18 +2011,16 @@ 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);
          }
 
        /* This setting lasts only while the filter is running; on exit, the
        variable is reset to the previous value. */
 
-       else headers_charset = s;
+       else headers_charset = s;       /*XXX loses track of const */
        }
       break;
 
@@ -2042,7 +2044,7 @@ while (commands)
       ff_ret = FF_FREEZE;
 
       DEFERFREEZEFAIL:
-      fmsg = expargs[0];
+      fmsg = expargs[0];               /*XXX loses track of const */
       if (Ustrlen(fmsg) > 1024) Ustrcpy(fmsg + 1000, US" ... (truncated)");
       fmsg = US string_printing(fmsg);
       *error_pointer = fmsg;
@@ -2125,7 +2127,7 @@ while (commands)
        for (i = 0; i < MAILARGS_STRING_COUNT; i++)
          {
          uschar *p;
-         uschar *s = expargs[i];
+         const uschar *s = expargs[i];
 
          if (s == NULL) continue;
 
@@ -2179,7 +2181,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 */
@@ -2367,8 +2369,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;
@@ -2430,9 +2433,9 @@ suffixed version of the local part in the tests. */
 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);