X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/89318c714454e11217505d2163d807d5d827f50a..fc37f2acaaa440c5265dc01fd693d8f5406f5cf9:/src/src/expand.c diff --git a/src/src/expand.c b/src/src/expand.c index acde8d516..6def3c102 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -5,6 +5,7 @@ /* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Functions for handling string expansion. */ @@ -12,6 +13,10 @@ #include "exim.h" +#ifdef MACRO_PREDEF +# include "macro_predef.h" +#endif + typedef unsigned esi_flags; #define ESI_NOFLAGS 0 #define ESI_BRACE_ENDS BIT(0) /* expansion should stop at } */ @@ -830,6 +835,76 @@ static var_entry var_table[] = { }; static int var_table_size = nelem(var_table); + +#ifdef MACRO_PREDEF + +/* dummies */ +uschar * fn_arc_domains(void) {return NULL;} +uschar * fn_hdrs_added(void) {return NULL;} +uschar * fn_queue_size(void) {return NULL;} +uschar * fn_recipients(void) {return NULL;} +uschar * sender_helo_verified_boolstr(void) {return NULL;} +uschar * smtp_cmd_hist(void) {return NULL;} + + + +static void +expansion_items(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(item_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_ITEM_%T", item_table[i]); + builtin_macro_create(buf); + } +} +static void +expansion_operators(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(op_table_underscore); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_underscore[i]); + builtin_macro_create(buf); + } +for (int i = 0; i < nelem(op_table_main); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_OP_%T", op_table_main[i]); + builtin_macro_create(buf); + } +} +static void +expansion_conditions(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(cond_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_COND_%T", cond_table[i]); + builtin_macro_create(buf); + } +} +static void +expansion_variables(void) +{ +uschar buf[64]; +for (int i = 0; i < nelem(var_table); i++) + { + spf(buf, sizeof(buf), CUS"_EXP_VAR_%T", var_table[i].name); + builtin_macro_create(buf); + } +} + +void +expansions(void) +{ +expansion_items(); +expansion_operators(); +expansion_conditions(); +expansion_variables(); +} + +#else /*!MACRO_PREDEF*/ + static uschar var_buffer[256]; static BOOL malformed_header; @@ -1860,7 +1935,7 @@ else if (Ustrncmp(name, "r_", 2) == 0) return node ? node->data.ptr : strict_acl_vars ? NULL : US""; } -/* Handle $auth variables. */ +/* Handle $auth, $regex variables. */ if (Ustrncmp(name, "auth", 4) == 0) { @@ -1869,6 +1944,7 @@ if (Ustrncmp(name, "auth", 4) == 0) if (!*endptr && n != 0 && n <= AUTH_VARS) return auth_vars[n-1] ? auth_vars[n-1] : US""; } +#ifdef WITH_CONTENT_SCAN else if (Ustrncmp(name, "regex", 5) == 0) { uschar *endptr; @@ -1876,6 +1952,7 @@ else if (Ustrncmp(name, "regex", 5) == 0) if (!*endptr && n != 0 && n <= REGEX_VARS) return regex_vars[n-1] ? regex_vars[n-1] : US""; } +#endif /* For all other variables, search the table */ @@ -6542,6 +6619,9 @@ while (*s) if (item_type == EITEM_FILTER) { BOOL condresult; + /* the condition could modify $value, as a side-effect */ + uschar * save_value = lookup_value; + if (!eval_condition(expr, &resetok, &condresult)) { iterate_item = save_iterate_item; @@ -6550,6 +6630,7 @@ while (*s) expand_string_message, name); goto EXPAND_FAILED; } + lookup_value = save_value; DEBUG(D_expand) debug_printf_indent("%s: condition is %s\n", name, condresult? "true":"false"); if (condresult) @@ -6558,14 +6639,12 @@ while (*s) continue; /* FALSE => skip this item */ } - /* EITEM_MAP and EITEM_REDUCE */ - - else + else /* EITEM_MAP and EITEM_REDUCE */ { + /* the expansion could modify $value, as a side-effect */ uschar * t = expand_string_internal(expr, ESI_BRACE_ENDS | ESI_HONOR_DOLLAR | flags, NULL, &resetok, NULL); - temp = t; - if (!temp) + if (!(temp = t)) { iterate_item = save_iterate_item; expand_string_message = string_sprintf("%s inside \"%s\" item", @@ -6958,68 +7037,73 @@ while (*s) case 3: goto EXPAND_FAILED; } - g = string_catn(g, US"SRS0=", 5); - - /* ${l_4:${hmac{md5}{SRS_SECRET}{${lc:$return_path}}}}= */ - hmac_md5(sub[0], string_copylc(sub[1]), cksum, sizeof(cksum)); - g = string_catn(g, cksum, sizeof(cksum)); - g = string_catn(g, US"=", 1); - - /* ${base32:${eval:$tod_epoch/86400&0x3ff}}= */ + if (sub[1] && *(sub[1])) { - struct timeval now; - unsigned long i; - gstring * h = NULL; - - gettimeofday(&now, NULL); - for (unsigned long i = (now.tv_sec / 86400) & 0x3ff; i; i >>= 5) - h = string_catn(h, &base32_chars[i & 0x1f], 1); - if (h) while (h->ptr > 0) - g = string_catn(g, &h->s[--h->ptr], 1); - } - g = string_catn(g, US"=", 1); + g = string_catn(g, US"SRS0=", 5); - /* ${domain:$return_path}=${local_part:$return_path} */ - { - int start, end, domain; - uschar * t = parse_extract_address(sub[1], &expand_string_message, - &start, &end, &domain, FALSE); - uschar * s; + /* ${l_4:${hmac{md5}{SRS_SECRET}{${lc:$return_path}}}}= */ + hmac_md5(sub[0], string_copylc(sub[1]), cksum, sizeof(cksum)); + g = string_catn(g, cksum, sizeof(cksum)); + g = string_catn(g, US"=", 1); - if (!t) - goto EXPAND_FAILED; + /* ${base32:${eval:$tod_epoch/86400&0x3ff}}= */ + { + struct timeval now; + unsigned long i; + gstring * h = NULL; - if (domain > 0) g = string_cat(g, t + domain); + gettimeofday(&now, NULL); + for (unsigned long i = (now.tv_sec / 86400) & 0x3ff; i; i >>= 5) + h = string_catn(h, &base32_chars[i & 0x1f], 1); + if (h) while (h->ptr > 0) + g = string_catn(g, &h->s[--h->ptr], 1); + } g = string_catn(g, US"=", 1); - s = domain > 0 ? string_copyn(t, domain - 1) : t; - if ((quoted = Ustrchr(s, '"') != NULL)) + /* ${domain:$return_path}=${local_part:$return_path} */ { - gstring * h = NULL; - DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n"); - while (*s) /* de-quote */ + int start, end, domain; + uschar * t = parse_extract_address(sub[1], &expand_string_message, + &start, &end, &domain, FALSE); + uschar * s; + + if (!t) + goto EXPAND_FAILED; + + if (domain > 0) g = string_cat(g, t + domain); + g = string_catn(g, US"=", 1); + + s = domain > 0 ? string_copyn(t, domain - 1) : t; + if ((quoted = Ustrchr(s, '"') != NULL)) { - while (*s && *s != '"') h = string_catn(h, s++, 1); - if (*s) s++; - while (*s && *s != '"') h = string_catn(h, s++, 1); - if (*s) s++; + gstring * h = NULL; + DEBUG(D_expand) debug_printf_indent("auto-quoting local part\n"); + while (*s) /* de-quote */ + { + while (*s && *s != '"') h = string_catn(h, s++, 1); + if (*s) s++; + while (*s && *s != '"') h = string_catn(h, s++, 1); + if (*s) s++; + } + gstring_release_unused(h); + s = string_from_gstring(h); } - gstring_release_unused(h); - s = string_from_gstring(h); + g = string_cat(g, s); } - g = string_cat(g, s); - } - /* Assume that if the original local_part had quotes - it was for good reason */ + /* Assume that if the original local_part had quotes + it was for good reason */ - if (quoted) yield = string_catn(yield, US"\"", 1); - yield = string_catn(yield, g->s, g->ptr); - if (quoted) yield = string_catn(yield, US"\"", 1); + if (quoted) yield = string_catn(yield, US"\"", 1); + yield = string_catn(yield, g->s, g->ptr); + if (quoted) yield = string_catn(yield, US"\"", 1); - /* @$original_domain */ - yield = string_catn(yield, US"@", 1); - yield = string_cat(yield, sub[2]); + /* @$original_domain */ + yield = string_catn(yield, US"@", 1); + yield = string_cat(yield, sub[2]); + } + else + DEBUG(D_expand) debug_printf_indent("null return_path for srs-encode\n"); break; } @@ -8710,9 +8794,11 @@ 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", US auth_vars[i], &e); +#ifdef WITH_CONTENT_SCAN /* 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", US regex_vars[i], &e); +#endif /* check known-name variables */ for (var_entry * v = var_table; v < var_table + var_table_size; v++) @@ -8849,8 +8935,9 @@ search_tidyup(); return 0; } -#endif +#endif /*STAND_ALONE*/ +#endif /*!MACRO_PREDEF*/ /* vi: aw ai sw=2 */ /* End of expand.c */