constification
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 13 Sep 2021 11:37:35 +0000 (12:37 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 13 Sep 2021 11:37:35 +0000 (12:37 +0100)
src/src/exim.c
src/src/expand.c
src/src/globals.c
src/src/globals.h
src/src/regex.c

index ff1aa49db56762a6192bf1132e4942d8ce0299d7..833045018cb352c20f65196420e894135c9ffb7e 100644 (file)
@@ -150,12 +150,8 @@ pcre_mtc_ctx = pcre2_match_context_create(pcre_gen_ctx);
 *************************************************/
 
 /* This function runs a regular expression match, and sets up the pointers to
-the matched substrings.  The matched strings are copied.
-
-We might consider tracing the uses of expand_nstring to see if consitification
-is viable, and save the copy cost by just using the pointers into the subject string.
-Pre-pcre2 we did that without noticing, so it might just work - or might have been
-a bug. It was certainly a risk in the implemenation.
+the matched substrings.  The matched strings are copied so the lifetime of
+the subject is not a problem.
 
 Arguments:
   re          the compiled expression
index 2bd78aac6b69d91b3cb373d4fbfbdc1578733447..88d4e756f34aef9cc73aaba73ce741e7181472d1 100644 (file)
@@ -1854,7 +1854,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 +1892,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 +2560,7 @@ switch(cond_type = identify_operator(&s, &opname))
 
   case ECOND_DEF:
     {
-    uschar * t;
+    const uschar * t;
 
     if (*s != ':')
       {
@@ -3606,7 +3606,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 +3633,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;
@@ -4474,7 +4474,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 +4503,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 +4560,7 @@ while (*s)
 
   if (isalpha((*(++s))))
     {
+    const uschar * value;
     int len;
     int newsize = 0;
     gstring * g = NULL;
@@ -4603,7 +4603,7 @@ while (*s)
       But there is no error here - nothing gets inserted. */
 
       if (!value)
-        {
+        {              /*{*/
         if (Ustrchr(name, '}')) malformed_header = TRUE;
         continue;
         }
@@ -4633,7 +4633,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);
@@ -8114,6 +8114,7 @@ while (*s)
                                                /*{*/
   if (*s++ == '}')
     {
+    const uschar * value;
     int len;
     int newsize = 0;
     gstring * g = NULL;
@@ -8140,7 +8141,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 +8564,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 +8586,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++)
index f54a2522783b2e8a7913f625a53a46f80e278c12..7dfbc76080930e586d59e62c06be2c6555531c1c 100644 (file)
@@ -658,7 +658,7 @@ auth_instance auth_defaults    = {
 
 uschar *auth_defer_msg         = US"reason not recorded";
 uschar *auth_defer_user_msg    = US"";
-uschar *auth_vars[AUTH_VARS];
+const uschar *auth_vars[AUTH_VARS];
 int     auto_thaw              = 0;
 #ifdef WITH_CONTENT_SCAN
 int     av_failed              = FALSE;        /* boolean but accessed as vtype_int*/
@@ -924,7 +924,7 @@ int     expand_level               = 0;             /* Nesting depth, indent for debug */
 int     expand_forbid          = 0;
 int     expand_nlength[EXPAND_MAXN+1];
 int     expand_nmax            = -1;
-uschar *expand_nstring[EXPAND_MAXN+1];
+const uschar *expand_nstring[EXPAND_MAXN+1];
 uschar *expand_string_message;
 uschar *extra_local_interfaces = NULL;
 
@@ -1320,7 +1320,7 @@ const pcre2_code *regex_EARLY_PIPE   = NULL;
 #endif
 const pcre2_code *regex_ismsgid      = NULL;
 const pcre2_code *regex_smtp_code    = NULL;
-uschar *regex_vars[REGEX_VARS];
+const uschar *regex_vars[REGEX_VARS];
 #ifdef WHITELIST_D_MACROS
 const pcre2_code *regex_whitelisted_macro = NULL;
 #endif
index 193eed6c5a94ac7f58bbc7a614c0b463cdff897e..95b8a08dc69a46d94bfbfcb92060e5dfc3aca56b 100644 (file)
@@ -372,7 +372,7 @@ extern auth_instance *auths;           /* Chain of instantiated auths */
 extern auth_instance auth_defaults;    /* Default values */
 extern uschar *auth_defer_msg;         /* Error message for log */
 extern uschar *auth_defer_user_msg;    /* Error message for user */
-extern uschar *auth_vars[];            /* $authn variables */
+extern const uschar *auth_vars[];      /* $authn variables */
 extern int     auto_thaw;              /* Auto-thaw interval */
 #ifdef WITH_CONTENT_SCAN
 extern int     av_failed;              /* TRUE if the AV process failed */
@@ -600,7 +600,7 @@ extern int     expand_level;               /* Nesting depth; indent for debug */
 extern int     expand_forbid;          /* RDO flags for forbidding things */
 extern int     expand_nlength[];       /* Lengths of numbered strings */
 extern int     expand_nmax;            /* Max numerical value */
-extern uschar *expand_nstring[];       /* Numbered strings */
+extern const uschar *expand_nstring[];       /* Numbered strings */
 extern BOOL    extract_addresses_remove_arguments; /* Controls -t behaviour */
 extern uschar *extra_local_interfaces; /* Local, non-listen interfaces */
 
@@ -882,9 +882,9 @@ extern const pcre2_code  *regex_SIZE;        /* For recognizing SIZE settings */
 #ifndef DISABLE_PIPE_CONNECT
 extern const pcre2_code  *regex_EARLY_PIPE;  /* For recognizing PIPE_CONNCT */
 #endif
-extern const pcre2_code  *regex_ismsgid;     /* Compiled r.e. for message it */
+extern const pcre2_code  *regex_ismsgid;     /* Compiled r.e. for message ID */
 extern const pcre2_code  *regex_smtp_code;   /* For recognizing SMTP codes */
-extern uschar *regex_vars[];           /* $regexN variables */
+extern const uschar *regex_vars[];           /* $regexN variables */
 #ifdef WHITELIST_D_MACROS
 extern const pcre2_code  *regex_whitelisted_macro; /* For -D macro values */
 #endif
index 2c14eb2d9df0dd7a8dbe707d26ec83753591ee10..a3d6659a6428e1003bd2ef93ca900ccb9f4f93e2 100644 (file)
@@ -85,7 +85,7 @@ for (pcre_list * ri = re_list_head; ri; ri = ri->next)
       PCRE2_UCHAR * cstr;
       PCRE2_SIZE cslen;
       pcre2_substring_get_bynumber(md, nn, &cstr, &cslen);
-      regex_vars[nn-1] = US cstr;
+      regex_vars[nn-1] = CUS cstr;
       }
 
     return OK;