tidying
[exim.git] / src / src / expand.c
index 4e1ffbb24f1ae7d024a22b8ff2d17ebb40fb5656..f1f0a4a3819ca53e4ef93d82aaa1e8cad25f000c 100644 (file)
@@ -3,7 +3,7 @@
 *************************************************/
 
 /* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -177,7 +177,7 @@ in alphabetical order. There are two tables, because underscore is used in some
 cases to introduce arguments, whereas for other it is part of the name. This is
 an historical mis-design. */
 
-static uschar *op_table_underscore[] = {
+static uschar * op_table_underscore[] = {
   US"from_utf8",
   US"local_part",
   US"quote_local_part",
@@ -1593,7 +1593,7 @@ Returns:        NULL if the header does not exist, else a pointer to a new
 */
 
 static uschar *
-find_header(uschar *name, int *newsize, unsigned flags, uschar *charset)
+find_header(uschar *name, int *newsize, unsigned flags, const uschar *charset)
 {
 BOOL found = !name;
 int len = name ? Ustrlen(name) : 0;
@@ -1760,8 +1760,6 @@ const uschar * where;
 #ifndef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
 uschar * sname;
 #endif
-fd_set fds;
-struct timeval tv;
 
 if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
   {
@@ -1805,9 +1803,7 @@ if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0)
 buf[0] = NOTIFY_QUEUE_SIZE_REQ;
 if (send(fd, buf, 1, 0) < 0) { where = US"send"; goto bad; }
 
-FD_ZERO(&fds); FD_SET(fd, &fds);
-tv.tv_sec = 2; tv.tv_usec = 0;
-if (select(fd + 1, (SELECT_ARG2_TYPE *)&fds, NULL, NULL, &tv) != 1)
+if (poll_one_fd(fd, POLLIN, 2 * 1000) != 1)
   {
   DEBUG(D_expand) debug_printf("no daemon response; using local evaluation\n");
   len = snprintf(CS buf, sizeof(buf), "%u", queue_count_cached());
@@ -1854,7 +1850,7 @@ Returns:        NULL if the variable does not exist, or
                 something non-NULL if exists_only is TRUE
 */
 
-static uschar *
+static const uschar *
 find_variable(uschar *name, BOOL exists_only, BOOL skipping, int *newsize)
 {
 var_entry * vp;
@@ -1892,15 +1888,15 @@ if (Ustrncmp(name, "auth", 4) == 0)
   {
   uschar *endptr;
   int n = Ustrtoul(name + 4, &endptr, 10);
-  if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
-    return !auth_vars[n-1] ? US"" : auth_vars[n-1];
+  if (!*endptr && n != 0 && n <= AUTH_VARS)
+    return auth_vars[n-1] ? auth_vars[n-1] : US"";
   }
 else if (Ustrncmp(name, "regex", 5) == 0)
   {
   uschar *endptr;
   int n = Ustrtoul(name + 5, &endptr, 10);
-  if (*endptr == 0 && n != 0 && n <= REGEX_VARS)
-    return !regex_vars[n-1] ? US"" : regex_vars[n-1];
+  if (!*endptr && n != 0 && n <= REGEX_VARS)
+    return regex_vars[n-1] ? regex_vars[n-1] : US"";
   }
 
 /* For all other variables, search the table */
@@ -2560,7 +2556,7 @@ switch(cond_type = identify_operator(&s, &opname))
 
   case ECOND_DEF:
     {
-    uschar * t;
+    const uschar * t;
 
     if (*s != ':')
       {
@@ -2982,7 +2978,7 @@ switch(cond_type = identify_operator(&s, &opname))
        uschar errbuf[128];
        pcre2_get_error_message(err, errbuf, sizeof(errbuf));
        expand_string_message = string_sprintf("regular expression error in "
-         "\"%s\": %s at offset %d", sub[1], errbuf, offset);
+         "\"%s\": %s at offset %ld", sub[1], errbuf, (long)offset);
        return NULL;
        }
 
@@ -3494,9 +3490,9 @@ switch(cond_type = identify_operator(&s, &opname))
 
     srs_recipient = string_sprintf("%.*s%.*S%.*s@%.*S",        /* lowercased */
                      quoting, "\"",
-                     ovec[9]-ovec[8], sub[0] + ovec[8],        /* substring 4 */
+                     (int) (ovec[9]-ovec[8]), sub[0] + ovec[8],  /* substr 4 */
                      quoting, "\"",
-                     ovec[7]-ovec[6], sub[0] + ovec[6]);       /* substring 3 */
+                     (int) (ovec[7]-ovec[6]), sub[0] + ovec[6]); /* substr 3 */
 
     /* If a zero-length secret was given, we're done.  Otherwise carry on
     and validate the given SRS local_part againt our secret. */
@@ -3606,7 +3602,7 @@ Returns:                the value of expand max to save
 */
 
 static int
-save_expand_strings(uschar **save_expand_nstring, int *save_expand_nlength)
+save_expand_strings(const uschar **save_expand_nstring, int *save_expand_nlength)
 {
 for (int i = 0; i <= expand_nmax; i++)
   {
@@ -3633,7 +3629,7 @@ Returns:                nothing
 */
 
 static void
-restore_expand_strings(int save_expand_nmax, uschar **save_expand_nstring,
+restore_expand_strings(int save_expand_nmax, const uschar **save_expand_nstring,
   int *save_expand_nlength)
 {
 expand_nmax = save_expand_nmax;
@@ -4319,7 +4315,6 @@ tree_node *t = NULL;
 const uschar * list;
 int sep = 0;
 uschar * item;
-uschar * suffix = US"";
 BOOL needsep = FALSE;
 #define LISTNAMED_BUF_SIZE 256
 uschar b[LISTNAMED_BUF_SIZE];
@@ -4335,10 +4330,10 @@ if (!listtype)          /* no-argument version */
   }
 else switch(*listtype) /* specific list-type version */
   {
-  case 'a': t = tree_search(addresslist_anchor,   name); suffix = US"_a"; break;
-  case 'd': t = tree_search(domainlist_anchor,    name); suffix = US"_d"; break;
-  case 'h': t = tree_search(hostlist_anchor,      name); suffix = US"_h"; break;
-  case 'l': t = tree_search(localpartlist_anchor, name); suffix = US"_l"; break;
+  case 'a': t = tree_search(addresslist_anchor,   name); break;
+  case 'd': t = tree_search(domainlist_anchor,    name); break;
+  case 'h': t = tree_search(hostlist_anchor,      name); break;
+  case 'l': t = tree_search(localpartlist_anchor, name); break;
   default:
     expand_string_message = US"bad suffix on \"list\" operator";
     return yield;
@@ -4474,7 +4469,7 @@ rmark reset_point = store_mark();
 gstring * yield = string_get(Ustrlen(string) + 64);
 int item_type;
 const uschar *s = string;
-uschar *save_expand_nstring[EXPAND_MAXN+1];
+const uschar *save_expand_nstring[EXPAND_MAXN+1];
 int save_expand_nlength[EXPAND_MAXN+1];
 BOOL resetok = TRUE;
 
@@ -4503,7 +4498,6 @@ if ((m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansi
 
 while (*s)
   {
-  uschar *value;
   uschar name[256];
 
   /* \ escapes the next character, which must exist, or else
@@ -4561,6 +4555,7 @@ while (*s)
 
   if (isalpha((*(++s))))
     {
+    const uschar * value;
     int len;
     int newsize = 0;
     gstring * g = NULL;
@@ -4592,7 +4587,7 @@ while (*s)
       unsigned flags = *name == 'r' ? FH_WANT_RAW
                      : *name == 'l' ? FH_WANT_RAW|FH_WANT_LIST
                      : 0;
-      uschar * charset = *name == 'b' ? NULL : headers_charset;
+      const uschar * charset = *name == 'b' ? NULL : headers_charset;
 
       s = read_header_name(name, sizeof(name), s);
       value = find_header(name, &newsize, flags, charset);
@@ -4603,7 +4598,7 @@ while (*s)
       But there is no error here - nothing gets inserted. */
 
       if (!value)
-        {
+        {              /*{*/
         if (Ustrchr(name, '}')) malformed_header = TRUE;
         continue;
         }
@@ -4633,7 +4628,7 @@ while (*s)
       yield = g;
       yield->size = newsize;
       yield->ptr = len;
-      yield->s = value;
+      yield->s = US value; /* known to be in new store i.e. a copy, so deconst safe */
       }
     else
       yield = string_catn(yield, value, len);
@@ -5864,7 +5859,7 @@ while (*s)
         uschar errbuf[128];
        pcre2_get_error_message(err, errbuf, sizeof(errbuf));
         expand_string_message = string_sprintf("regular expression error in "
-          "\"%s\": %s at offset %l", sub[1], errbuf, (long)roffset);
+          "\"%s\": %s at offset %ld", sub[1], errbuf, (long)roffset);
         goto EXPAND_FAILED;
         }
       md = pcre2_match_data_create(EXPAND_MAXN + 1, pcre_gen_ctx);
@@ -7569,7 +7564,7 @@ while (*s)
       else
         {
         int n;
-        uschar *opt = Ustrchr(arg, '_');
+        uschar * opt = Ustrchr(arg, '_');
 
         if (opt) *opt++ = 0;
 
@@ -8114,6 +8109,7 @@ while (*s)
                                                /*{*/
   if (*s++ == '}')
     {
+    const uschar * value;
     int len;
     int newsize = 0;
     gstring * g = NULL;
@@ -8140,7 +8136,7 @@ while (*s)
       yield = g;
       yield->size = newsize;
       yield->ptr = len;
-      yield->s = value;
+      yield->s = US value; /* known to be in new store i.e. a copy, so deconst safe */
       }
     else
       yield = string_catn(yield, value, len);
@@ -8563,6 +8559,7 @@ typedef struct {
   const uschar *var_data;
 } err_ctx;
 
+/* Called via tree_walk, which allows nonconst name/data.  Our usage is const. */
 static void
 assert_variable_notin(uschar * var_name, uschar * var_data, void * ctx)
 {
@@ -8584,13 +8581,14 @@ err_ctx e = { .region_start = ptr, .region_end = US ptr + len,
 tree_walk(acl_var_c, assert_variable_notin, &e);
 tree_walk(acl_var_m, assert_variable_notin, &e);
 
-/* check auth<n> variables */
+/* check auth<n> variables.
+assert_variable_notin() treats as const, so deconst is safe. */
 for (int i = 0; i < AUTH_VARS; i++) if (auth_vars[i])
-  assert_variable_notin(US"auth<n>", auth_vars[i], &e);
+  assert_variable_notin(US"auth<n>", US auth_vars[i], &e);
 
-/* check regex<n> variables */
+/* check regex<n> variables. assert_variable_notin() treats as const. */
 for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i])
-  assert_variable_notin(US"regex<n>", regex_vars[i], &e);
+  assert_variable_notin(US"regex<n>", US regex_vars[i], &e);
 
 /* check known-name variables */
 for (var_entry * v = var_table; v < var_table + var_table_size; v++)