X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/48a53b7fdcd495fe49d43e395446b225e8193925..HEAD:/src/src/filtertest.c diff --git a/src/src/filtertest.c b/src/src/filtertest.c index 092febaa4..35d939ee0 100644 --- a/src/src/filtertest.c +++ b/src/src/filtertest.c @@ -1,11 +1,11 @@ -/* $Cambridge: exim/src/src/filtertest.c,v 1.7 2005/08/30 10:07:58 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2005 */ +/* Copyright (c) The Exim Maintainers 2021 - 2024 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* Code for the filter test function. */ @@ -22,9 +22,10 @@ we can set up the message_body variables at the same time (in normal use, the message_body variables are not set up unless needed). The reading code is written out here rather than having options in read_message_data, in order to -keep that function as efficient as possible. Handling message_body_end is -somewhat more tedious. Pile it all into a circular buffer and sort out at the -end. +keep that function as efficient as possible. (Later: this function is now +global because it is also used by the -bem testing option.) Handling +message_body_end is somewhat more tedious. Pile it all into a circular buffer +and sort out at the end. Arguments: dot_ended TRUE if message already terminated by '.' @@ -32,7 +33,7 @@ Arguments: Returns: nothing */ -static void +void read_message_body(BOOL dot_ended) { register int ch; @@ -46,11 +47,11 @@ body_len = 0; body_linecount = 0; header_size = message_size; -if (!dot_ended && !feof(stdin)) +if (!dot_ended && !stdin_feof()) { - if (!dot_ends) + if (!f.dot_ends) { - while ((ch = getc(stdin)) != EOF) + while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF) { if (ch == 0) body_zerocount++; if (ch == '\n') body_linecount++; @@ -63,7 +64,7 @@ if (!dot_ended && !feof(stdin)) else { int ch_state = 1; - while ((ch = getc(stdin)) != EOF) + while ((ch = stdin_getc(GETC_BUFFER_UNLIMITED)) != EOF) { if (ch == 0) body_zerocount++; switch (ch_state) @@ -96,7 +97,7 @@ if (!dot_ended && !feof(stdin)) if (s > message_body_end + message_body_visible) s = message_body_end; message_size++; } - READ_END: ch = ch; /* Some compilers don't like null statements */ + READ_END: ; } if (s == message_body_end || s[-1] != '\n') body_linecount++; } @@ -113,7 +114,7 @@ if (body_len >= message_body_visible) int above = message_body_visible - below; if (above > 0) { - uschar *temp = store_get(below); + uschar * temp = store_get(below, GET_UNTAINTED); memcpy(temp, message_body_end, below); memmove(message_body_end, s+1, above); memcpy(message_body_end + above, temp, below); @@ -142,6 +143,30 @@ while (body_end_len > 0) +static int +exim_filter_interpret(const uschar * filebuf, int options, + address_item ** addrp, uschar ** error) +{ +#ifdef DISABLE_EXIM_FILTER + printf("exim: Exim-filtering not available\n"); + return FF_ERROR; +#else + +const misc_module_info * mi; +uschar * errstr = NULL; +typedef int (*fn_t)(const uschar *, int, address_item **, uschar **); +if (!(mi = misc_mod_find(US"exim_filter", &errstr))) + { + printf("exim: Exim-filtering not available: %s\n", errstr ? errstr : US"?"); + return FF_ERROR; + } +return(((fn_t *) mi->functions)[EXIM_INTERPRET]) + (filebuf, options, addrp, error); +#endif +} + + + /************************************************* * Test a mail filter * *************************************************/ @@ -162,7 +187,7 @@ Returns: TRUE if no errors */ BOOL -filter_runtest(int fd, uschar *filename, BOOL is_system, BOOL dot_ended) +filter_runtest(int fd, const uschar * filename, BOOL is_system, BOOL dot_ended) { int rc, filter_type; BOOL yield; @@ -179,7 +204,7 @@ if (fstat(fd, &statbuf) != 0) return FALSE; } -filebuf = store_get(statbuf.st_size + 1); +filebuf = store_get(statbuf.st_size + 1, filename); rc = read(fd, filebuf, statbuf.st_size); (void)close(fd); @@ -200,8 +225,8 @@ filter_type = rda_is_filter(filebuf); if (is_system && filter_type == FILTER_FORWARD) filter_type = FILTER_EXIM; printf("Testing %s file \"%s\"\n\n", - (filter_type == FILTER_EXIM)? "Exim filter" : - (filter_type == FILTER_SIEVE)? "Sieve filter" : + filter_type == FILTER_EXIM ? "Exim filter" : + filter_type == FILTER_SIEVE ? "Sieve filter" : "forward file", filename); @@ -232,13 +257,13 @@ if (filter_type == FILTER_FORWARD) return FALSE; } - if (generated == NULL) + if (!generated) printf("exim: no addresses generated from forward file\n"); else { printf("exim: forward file generated:\n"); - while (generated != NULL) + while (generated) { printf(" %s\n", generated->address); generated = generated->next; @@ -251,7 +276,7 @@ if (filter_type == FILTER_FORWARD) /* For a filter, set up the message_body variables and the message size if this is the first time this function has been called. */ -if (message_body == NULL) read_message_body(dot_ended); +if (!message_body) read_message_body(dot_ended); /* Now pass the filter file to the function that interprets it. Because filter_test is not FILTER_NONE, the interpreter will output comments about what @@ -260,21 +285,30 @@ testing a system filter that is going to be followed by a user filter test. */ if (is_system) { - system_filtering = TRUE; - enable_dollar_recipients = TRUE; /* Permit $recipients in system filter */ - yield = filter_interpret - (filebuf, - RDO_DEFER|RDO_FAIL|RDO_FILTER|RDO_FREEZE|RDO_REWRITE, &generated, &error); - enable_dollar_recipients = FALSE; - system_filtering = FALSE; + f.system_filtering = TRUE; + f.enable_dollar_recipients = TRUE; /* Permit $recipients in system filter */ + yield = exim_filter_interpret(filebuf, + RDO_DEFER|RDO_FAIL|RDO_FILTER|RDO_FREEZE|RDO_REWRITE, &generated, &error); + f.enable_dollar_recipients = FALSE; + f.system_filtering = FALSE; } -else +else if (filter_type == FILTER_SIEVE) { - yield = (filter_type == FILTER_SIEVE)? - sieve_interpret(filebuf, RDO_REWRITE, NULL, NULL, NULL, &generated, &error) - : - filter_interpret(filebuf, RDO_REWRITE, &generated, &error); + const misc_module_info * mi; + uschar * errstr = NULL; + typedef int (*fn_t)(const uschar *, int, const sieve_block *, + address_item **, uschar **); + if (!(mi = misc_mod_find(US"sieve_filter", &errstr))) + { + printf("exim: Sieve filtering not available: %s\n", errstr ? errstr : US"?"); + yield = FF_ERROR; + } + else + yield = (((fn_t *) mi->functions)[SIEVE_INTERPRET]) + (filebuf, RDO_REWRITE, NULL, &generated, &error); } +else + yield = exim_filter_interpret(filebuf, RDO_REWRITE, &generated, &error); return yield != FF_ERROR; }