X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/0a49a7a4f1090b6f1ce1d0f9d969804c9226b53e..1d28cc061677bd07d9bed48dd84bd5c590247043:/src/src/routers/rf_get_munge_headers.c diff --git a/src/src/routers/rf_get_munge_headers.c b/src/src/routers/rf_get_munge_headers.c index 4282467c0..58b5bc7ad 100644 --- a/src/src/routers/rf_get_munge_headers.c +++ b/src/src/routers/rf_get_munge_headers.c @@ -1,11 +1,11 @@ -/* $Cambridge: exim/src/src/routers/rf_get_munge_headers.c,v 1.5 2009/11/16 19:50:38 nm4 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) The Exim Maintainers 2021 - 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 */ #include "../exim.h" #include "rf_functions.h" @@ -15,7 +15,7 @@ * Get additional headers for a router * *************************************************/ -/* This function is called by both routers to sort out the additional headers +/* This function is called by routers to sort out the additional headers and header remove list for a particular address. Arguments: @@ -34,86 +34,91 @@ rf_get_munge_headers(address_item *addr, router_instance *rblock, header_line **extra_headers, uschar **remove_headers) { /* Default is to retain existing headers */ +*extra_headers = addr->prop.extra_headers; -*extra_headers = addr->p.extra_headers; - -if (rblock->extra_headers != NULL) +if (rblock->extra_headers) { - header_line *h; - uschar *s = expand_string(rblock->extra_headers); + const uschar * list = rblock->extra_headers; + int sep = '\n'; + uschar * s, * t; + int slen; - if (s == NULL) - { - if (!expand_string_forcedfail) + while ((s = string_nextinlist(&list, &sep, NULL, 0))) + if (!(s = expand_string(t = s))) { - addr->message = string_sprintf("%s router failed to expand \"%s\": %s", - rblock->name, rblock->extra_headers, expand_string_message); - return DEFER; + if (!f.expand_string_forcedfail) + { + addr->message = string_sprintf( + "%s router failed to expand add_headers item \"%s\": %s", + rblock->name, t, expand_string_message); + return DEFER; + } } - } - - /* Expand succeeded. Put extra header at the start of the chain because - further down it may point to headers from other routers, which may be - shared with other addresses. The output function outputs them in reverse - order. */ - - else - { - int slen = Ustrlen(s); - if (slen > 0) + else if ((slen = Ustrlen(s)) > 0) { - h = store_get(sizeof(header_line)); + /* Expand succeeded. Put extra headers at the start of the chain because + further down it may point to headers from other routers, which may be + shared with other addresses. The output function outputs them in reverse + order. */ + + header_line * h = store_get(sizeof(header_line), GET_UNTAINTED); /* We used to use string_sprintf() to add the newline if needed, but that causes problems if the header line is exceedingly long (e.g. adding something to a pathologically long line). So avoid it. */ if (s[slen-1] == '\n') - { - h->text = s; - } + h->text = s; else - { - h->text = store_get(slen+2); - memcpy(h->text, s, slen); - h->text[slen++] = '\n'; - h->text[slen] = 0; - } - - h->next = addr->p.extra_headers; + { + h->text = store_get(slen+2, s); + memcpy(h->text, s, slen); + h->text[slen++] = '\n'; + h->text[slen] = 0; + } + + h->next = *extra_headers; h->type = htype_other; h->slen = slen; *extra_headers = h; } - } } /* Default is to retain existing removes */ +*remove_headers = addr->prop.remove_headers; -*remove_headers = addr->p.remove_headers; - -if (rblock->remove_headers != NULL) +/* Expand items from colon-sep list separately, then build new list */ +if (rblock->remove_headers) { - uschar *s = expand_string(rblock->remove_headers); - if (s == NULL) - { - if (!expand_string_forcedfail) + const uschar * list = rblock->remove_headers; + int sep = ':'; + uschar * s, * t; + gstring * g = NULL; + + if (*remove_headers) + g = string_cat(NULL, *remove_headers); + + while ((s = string_nextinlist(&list, &sep, NULL, 0))) + if (!(s = expand_string(t = s))) { - addr->message = string_sprintf("%s router failed to expand \"%s\": %s", - rblock->name, rblock->remove_headers, expand_string_message); - return DEFER; + if (!f.expand_string_forcedfail) + { + addr->message = string_sprintf( + "%s router failed to expand remove_headers item \"%s\": %s", + rblock->name, t, expand_string_message); + return DEFER; + } } - } - else if (*s != 0) - { - if (addr->p.remove_headers == NULL) - *remove_headers = s; - else - *remove_headers = string_sprintf("%s : %s", addr->p.remove_headers, s); - } + else if (*s) + g = string_append_listele(g, ':', s); + + if (g) + *remove_headers = g->s; } return OK; } +/* vi: aw ai sw=2 +*/ /* End of rf_get_munge_headers.c */