.section "Expansion of lists" "SECTlistexpand"
.cindex "expansion" "of lists"
-Each list is expanded as a single string before it is used.
+.new
+Each list, after any leading change-of-separator specification
+(see &<<SECTlistsepchange>>&) is expanded as a single string,
.cindex "tainted data" tracking
-&*Note*&: As a result, if any componend was tainted then the
-entire result string becomes tainted.
+&*Note*&: As a result, if any component was tainted then the
+entire expansion result string becomes tainted.
+
+Splitting out a leading explicit change-of-separator permits
+one being safely used on a list that has tainted components
+while still detecting the use of a tainted setting.
+The latter is not permitted.
+.wen
&'Exception: the router headers_remove option, where list-item
splitting is done before string-expansion.'&
where &'x.y'& does not match. It's best to avoid negation altogether in
referenced lists if you can.
+.new
+The list item which references a named list (&"+<listname>"&)
+may not be tainted.
+.wen
+
.cindex "hiding named list values"
.cindex "named lists" "hiding value of"
Some named list definitions may contain sensitive data, for example, passwords for
differ only in their names.
The value for a match will be the primary host name.
+.new
+The pattern may not be tainted.
+.wen
.next
see the &%allow_domain_literals%& main option.
The value for a match will be the string &`@[]`&.
+.new
+The pattern may not be tainted.
+.wen
.next
but a secondary MX target is. &"Primary"& means an MX record with the lowest
preference value &-- there may of course be more than one of them.
+.new
+The pattern may not be tainted.
+.wen
+
The MX lookup that takes place when matching a pattern of this type is
performed with the resolver options for widening names turned off. Thus, for
example, a single-component domain will &'not'& be expanded by adding the
performed caselessly, regular expressions that match against an entire address
become case-sensitive after &"+caseful"& has been seen.
+.new
+This string may not be tainted.
+To do caseful matching on list elements whic are tainted,
+place them in a named list.
+.wen
+
.section "Local part lists" "SECTlocparlis"
&%caseful_local_part%& is set true in a router, matching in the &%local_parts%&
option is case-sensitive from the start.
+.new
+This string may not be tainted.
+To do caseful matching on list elements whic are tainted,
+place them in a named list.
+.wen
+
If a local part list is indirected to a file (see section &<<SECTfilnamlis>>&),
comments are handled in the same way as address lists &-- they are recognized
only if the # is preceded by white space or the start of the line.
.cindex "list" "selecting by condition"
.cindex "expansion" "selecting from list by condition"
.vindex "&$item$&"
-After expansion, <&'string'&> is interpreted as a list, colon-separated by
-default, but the separator can be changed in the usual way (&<<SECTlistsepchange>>&).
-For each item
-in this list, its value is placed in &$item$&, and then the condition is
-evaluated.
+.new
+<&'string1'&> first has the part after any change-of-list-separator
+(see &<<SECTlistsepchange>>&) expanded,
+then the whole is taken as a list.
+.wen
+The default separator for the list is a colon.
+
+For each item in this list,
+its value is placed in &$item$&, and then the condition is evaluated.
Any modification of &$value$& by this evaluation is discarded.
If the condition is true, &$item$& is added to the output as an
item in a new list; if the condition is false, the item is discarded. The
apart from an optional leading minus,
and leading and trailing white space (which is ignored).
-After expansion, <&'string1'&> is interpreted as a list, colon-separated by
-default, but the separator can be changed in the usual way (&<<SECTlistsepchange>>&).
+.new
+The <&'string1'&> argument, after any leading change-of-separator
+(see &<<SECTlistsepchange>>&),
+is expanded and the whole forms the list.
+.wen
+By default, the list separator is a colon.
The first field of the list is numbered one.
If the number is negative, the fields are
.vitem &*${map{*&<&'string1'&>&*}{*&<&'string2'&>&*}}*&
.cindex "expansion" "list creation"
.vindex "&$item$&"
-After expansion, <&'string1'&> is interpreted as a list, colon-separated by
-default, but the separator can be changed in the usual way (&<<SECTlistsepchange>>&).
-For each item
-in this list, its value is place in &$item$&, and then <&'string2'&> is
+.new
+<&'string1'&> first has the part after any change-of-list-separator
+(see &<<SECTlistsepchange>>&) expanded,
+then the whole is taken as a list.
+.wen
+The default separator for the list is a colon.
+
+For each item in this list,
+its value is place in &$item$&, and then <&'string2'&> is
expanded and added to the output as an item in a new list. The separator used
for the output list is the same as the one used for the input, but a separator
setting is not included in the output. For example:
.cindex "list" "reducing to a scalar"
.vindex "&$value$&"
.vindex "&$item$&"
-This operation reduces a list to a single, scalar string. After expansion,
-<&'string1'&> is interpreted as a list, colon-separated by default, but the
-separator can be changed in the usual way (&<<SECTlistsepchange>>&).
+This operation reduces a list to a single, scalar string.
+
+.new
+<&'string1'&> first has the part after any change-of-list-separator
+(see &<<SECTlistsepchange>>&) expanded,
+then the whole is taken as a list.
+.wen
+The default separator for the list is a colon.
+
Then <&'string2'&> is expanded and
assigned to the &$value$& variable. After this, each item in the <&'string1'&>
list is assigned to &$item$&, in turn, and <&'string3'&> is expanded for each of
.cindex sorting "a list"
.cindex list sorting
.cindex expansion "list sorting"
-After expansion, <&'string'&> is interpreted as a list, colon-separated by
-default, but the separator can be changed in the usual way (&<<SECTlistsepchange>>&).
+.new
+<&'string'&> first has the part after any change-of-list-separator
+(see &<<SECTlistsepchange>>&) expanded,
+then the whole is taken as a list.
+.wen
+The default separator for the list is a colon.
+
The <&'comparator'&> argument is interpreted as the operator
of a two-argument expansion condition.
The numeric operators plus ge, gt, le, lt (and ~i variants) are supported.
.cindex "list" "item count"
.cindex "list" "count of items"
.cindex "&%listcount%& expansion item"
-The string is interpreted as a list and the number of items is returned.
+The part of the string after any leading change-of-separator is expanded,
+then the whole is interpreted as a list and the number of items is returned.
.vitem &*${listnamed:*&<&'name'&>&*}*&&~and&~&*${listnamed_*&<&'type'&>&*:*&<&'name'&>&*}*&
.cindex "expansion" "&*forall*& condition"
.cindex "expansion" "&*forany*& condition"
.vindex "&$item$&"
-These conditions iterate over a list. The first argument is expanded to form
-the list. By default, the list separator is a colon, but it can be changed by
-the normal method (&<<SECTlistsepchange>>&).
+These conditions iterate over a list.
+.new
+The first argument, after any leading change-of-separator
+(see &<<SECTlistsepchange>>&),
+is expanded and the whole forms the list.
+.wen
+By default, the list separator is a colon.
+
The second argument is interpreted as a condition that is to
be applied to each item in the list in turn. During the interpretation of the
condition, the current list item is placed in a variable called &$item$&.
&*inlisti&~{*&<&'subject'&>&*}{*&<&'list'&>&*}*&
.cindex "string" "comparison"
.cindex "list" "iterative conditions"
-Both strings are expanded; the second string is treated as a list of simple
-strings; if the first string is a member of the second, then the condition
-is true.
+The <&'subject'&> string is expanded.
+.new
+The <&'list'&> first has any change-of-list-separator
++(see &<<SECTlistsepchange>>&) retained verbatim,
++then the remainder is expanded.
++.wen
+The whole is treated as a list of simple strings;
+if the subject string is a member of that list, then the condition is true.
For the case-independent &%inlisti%& condition, case is defined per the system C locale.
These are simpler to use versions of the more powerful &*forany*& condition.
Note that <&'string2'&> is not itself subject to string expansion, unless
Exim was built with the EXPAND_LISTMATCH_RHS option.
+.new
+For the latter case, only the part after any leading
+change-of-separator specification is expanded.
+.wen
Consult section &<<SECThoslispatip>>& for further details of these patterns.
.endd
.cindex "&`+caseful`&"
For address lists, the matching starts off caselessly, but the &`+caseful`&
-item can be used, as in all address lists, to cause subsequent items to
-have their local parts matched casefully. Domains are always matched
-caselessly.
+item can be used, as in all address lists, to cause subsequent items
+(including those of referenced named lists)
+to have their local parts matched casefully.
+Domains are always matched caselessly.
The variable &$value$& will be set for a successful match and can be
used in the success clause of an &%if%& expansion item using the condition.
Note that <&'string2'&> is not itself subject to string expansion, unless
Exim was built with the EXPAND_LISTMATCH_RHS option.
+.new
+For the latter case, only the part after any leading
+change-of-separator specification is expanded.
+.wen
&*Note*&: Host lists are &'not'& supported in this way. This is because
hosts have two identities: a name and an IP address, and it is not clear