diff -urN ../exim-4.94.orig/doc/NewStuff ./doc/NewStuff --- ../exim-4.94.orig/doc/NewStuff 2020-05-30 23:35:38.000000000 +0300 +++ ./doc/NewStuff 2020-06-07 19:25:13.210528000 +0300 @@ -74,6 +74,10 @@ 22. New main config option spf_smtp_comment_template to customise the $spf_smtp_comment variable + 8. Sqlite lookups accept a "file=" option to specify a per-operation + db file, replacing the previous prefix to the SQL string (which had + issues when the SQL used tainted values). + Version 4.93 diff -urN ../exim-4.94.orig/src/expand.c ./src/expand.c --- ../exim-4.94.orig/src/expand.c 2020-05-30 23:35:38.000000000 +0300 +++ ./src/expand.c 2020-06-07 19:25:26.413431000 +0300 @@ -4390,7 +4390,7 @@ goto EXPAND_FAILED; } -while (*s != 0) +while (*s) { uschar *value; uschar name[256]; @@ -4776,7 +4776,7 @@ int save_expand_nmax = save_expand_strings(save_expand_nstring, save_expand_nlength); - if ((expand_forbid & RDO_LOOKUP) != 0) + if (expand_forbid & RDO_LOOKUP) { expand_string_message = US"lookup expansions are not permitted"; goto EXPAND_FAILED; @@ -4875,22 +4875,8 @@ file types, the query (i.e. "key") starts with a file name. */ if (!key) - { - Uskip_whitespace(&filename); - key = filename; + key = search_args(stype, name, filename, &filename, opts); - if (mac_islookup(stype, lookup_querystyle)) - filename = NULL; - else - if (*filename == '/') - { - while (*key && !isspace(*key)) key++; - if (*key) *key++ = '\0'; - } - else - filename = NULL; - } - /* If skipping, don't do the next bit - just lookup_value == NULL, as if the entry was not found. Note that there is no search_close() function. Files are left open in case of re-use. At suitable places in higher logic, @@ -7208,9 +7194,8 @@ { int cnt = 0; int sep = 0; - uschar buffer[256]; - while (string_nextinlist(CUSS &sub, &sep, buffer, sizeof(buffer))) cnt++; + while (string_nextinlist(CUSS &sub, &sep, NULL, 0)) cnt++; yield = string_fmt_append(yield, "%d", cnt); continue; } diff -urN ../exim-4.94.orig/src/functions.h ./src/functions.h --- ../exim-4.94.orig/src/functions.h 2020-05-30 23:35:38.000000000 +0300 +++ ./src/functions.h 2020-06-07 19:25:34.612651000 +0300 @@ -446,6 +446,7 @@ extern gstring * route_show_supported(gstring *); extern void route_tidyup(void); +extern uschar *search_args(int, uschar *, uschar *, uschar **, const uschar *); extern uschar *search_find(void *, const uschar *, uschar *, int, const uschar *, int, int, int *, const uschar *); extern int search_findtype(const uschar *, int); diff -urN ../exim-4.94.orig/src/match.c ./src/match.c --- ../exim-4.94.orig/src/match.c 2020-05-30 23:35:38.000000000 +0300 +++ ./src/match.c 2020-06-07 19:25:45.848822000 +0300 @@ -286,22 +286,7 @@ /* Set the parameters for the three different kinds of lookup. */ -keyquery = semicolon + 1; -Uskip_whitespace(&keyquery); - -if (mac_islookup(search_type, lookup_absfilequery)) - { - filename = keyquery; - while (*keyquery && !isspace(*keyquery)) keyquery++; - filename = string_copyn(filename, keyquery - filename); - Uskip_whitespace(&keyquery); - } - -else if (!mac_islookup(search_type, lookup_querystyle)) - { - filename = keyquery; - keyquery = s; - } +keyquery = search_args(search_type, s, semicolon+1, &filename, opts); /* Now do the actual lookup; throw away the data returned unless it was asked for; partial matching is all handled inside search_find(). Note that there is diff -urN ../exim-4.94.orig/src/search.c ./src/search.c --- ../exim-4.94.orig/src/search.c 2020-05-30 23:35:38.000000000 +0300 +++ ./src/search.c 2020-06-07 19:25:56.434805000 +0300 @@ -217,6 +217,55 @@ } +/* Set the parameters for the three different kinds of lookup. +Arguments: + search_type the search-type code + search the search-type string + query argument for the search; filename or query + fnamep pointer to return filename + opts options + +Return: keyquery the search-type (for single-key) or query (for query-type) + */ +uschar * +search_args(int search_type, uschar * search, uschar * query, uschar ** fnamep, + const uschar * opts) +{ +Uskip_whitespace(&query); +if (mac_islookup(search_type, lookup_absfilequery)) + { /* query-style but with file (sqlite) */ + int sep = ','; + + /* Check options first for new-style file spec */ + if (opts) for (uschar * s; s = string_nextinlist(&opts, &sep, NULL, 0); ) + if (Ustrncmp(s, "file=", 5) == 0) + { + *fnamep = s+5; + return query; + } + + /* If no filename from options, use old-tyle space-sep prefix on query */ + if (*query == '/') + { + uschar * s = query; + while (*query && !isspace(*query)) query++; + *fnamep = string_copyn(s, query - s); + Uskip_whitespace(&query); + } + else + *fnamep = NULL; + return query; /* remainder after file skipped */ + } +if (!mac_islookup(search_type, lookup_querystyle)) + { /* single-key */ + *fnamep = query; + return search; /* modifiers important so use "keyquery" for them */ + } +*fnamep = NULL; /* else query-style */ +return query; +} + + /************************************************* * Release cached resources *