X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/22ed7a5295f196fce32563f6e9c669110dd36f4d..5732024c9991f1e220ad203087997ca467a5cef7:/src/src/expand.c diff --git a/src/src/expand.c b/src/src/expand.c index 4e1ffbb24..f1f0a4a38 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -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 variables */ +/* check auth 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", auth_vars[i], &e); + assert_variable_notin(US"auth", US auth_vars[i], &e); -/* check regex variables */ +/* check regex variables. assert_variable_notin() treats as const. */ for (int i = 0; i < REGEX_VARS; i++) if (regex_vars[i]) - assert_variable_notin(US"regex", regex_vars[i], &e); + assert_variable_notin(US"regex", US regex_vars[i], &e); /* check known-name variables */ for (var_entry * v = var_table; v < var_table + var_table_size; v++)