Set $value for match_<list-type> and inlist
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 11 Mar 2022 15:54:26 +0000 (15:54 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Fri, 11 Mar 2022 16:05:52 +0000 (16:05 +0000)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/expand.c

index 1f0f473d804cf0de17200613447e959fec6f7f92..105e2fc5d514ea88b3e5005ecf5fadf7fd210d79 100644 (file)
@@ -11902,6 +11902,19 @@ ${if inlisti{Needle}{fOo:NeeDLE:bAr}}
   ${if forany{fOo:NeeDLE:bAr}{eqi{$item}{Needle}}}
 .endd
 
+.new
+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.
+.cindex "tainted data" "de-tainting"
+It will have the same taint status as the list; expansions such as
+.code
+${if inlist {$h_mycode:} {0 : 1 : 42} {$value}}
+.endd
+can be used for de-tainting.
+Any previous &$value$& is restored after the if.
+.wen
+
+
 .vitem &*isip&~{*&<&'string'&>&*}*&  &&&
        &*isip4&~{*&<&'string'&>&*}*& &&&
        &*isip6&~{*&<&'string'&>&*}*&
@@ -12098,6 +12111,18 @@ 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.
 
+.new
+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.
+.cindex "tainted data" "de-tainting"
+It will have the same taint status as the list; expansions such as
+.code
+${if match_local_part {$local_part} {alice : bill : charlotte : dave} {$value}}
+.endd
+can be used for de-tainting.
+Any previous &$value$& is restored after the if.
+.wen
+
 Note that <&'string2'&> is not itself subject to string expansion, unless
 Exim was built with the EXPAND_LISTMATCH_RHS option.
 
index 730508adc944d618d08c338920a96b14d3023cf9..11004e33a59376c6d024e8c32420b69c6a66a81d 100644 (file)
@@ -23,6 +23,10 @@ Version 4.96
     built using untrusted data ("tainted").  For now lack of quoting is merely
     logged; a future release will upgrade this to an error.
 
+ 7. The expansion conditions match_<list-type> and inlist now set $value for
+    the expansion of the "true" result of the ${if}.  With a static list, this
+    can be used for de-tainting.
+
 Version 4.95
 ------------
 
index b7719f642a6027044ffe04a657aedc4c6783036a..85619acfef4c5994ac6cc5655ba664b41690e000 100644 (file)
@@ -2964,12 +2964,12 @@ switch(cond_type = identify_operator(&s, &opname))
 
     case ECOND_MATCH_ADDRESS:  /* Match in an address list */
       rc = match_address_list(sub[0], TRUE, FALSE, &(sub[1]), NULL, -1, 0,
-                             NULL);
+                             CUSS &lookup_value);
       goto MATCHED_SOMETHING;
 
     case ECOND_MATCH_DOMAIN:   /* Match in a domain list */
       rc = match_isinlist(sub[0], &(sub[1]), 0, &domainlist_anchor, NULL,
-       MCL_DOMAIN + MCL_NOEXPAND, TRUE, NULL);
+       MCL_DOMAIN + MCL_NOEXPAND, TRUE, CUSS &lookup_value);
       goto MATCHED_SOMETHING;
 
     case ECOND_MATCH_IP:       /* Match IP address in a host list */
@@ -3003,13 +3003,13 @@ switch(cond_type = identify_operator(&s, &opname))
               &cb,                       /* argument for function */
               MCL_HOST,                  /* type of check */
               sub[0],                    /* text for debugging */
-              NULL);                     /* where to pass back data */
+              CUSS &lookup_value);       /* where to pass back data */
        }
       goto MATCHED_SOMETHING;
 
     case ECOND_MATCH_LOCAL_PART:
       rc = match_isinlist(sub[0], &(sub[1]), 0, &localpartlist_anchor, NULL,
-       MCL_LOCALPART + MCL_NOEXPAND, TRUE, NULL);
+       MCL_LOCALPART + MCL_NOEXPAND, TRUE, CUSS &lookup_value);
       /* Fall through */
       /* VVVVVVVVVVVV */
       MATCHED_SOMETHING:
@@ -3187,6 +3187,7 @@ switch(cond_type = identify_operator(&s, &opname))
         if (compare(sub[0], iterate_item) == 0)
           {
           tempcond = TRUE;
+         lookup_value = iterate_item;
           break;
           }
        }
@@ -4801,6 +4802,7 @@ while (*s)
       const uschar *next_s;
       int save_expand_nmax =
         save_expand_strings(save_expand_nstring, save_expand_nlength);
+      uschar * save_lookup_value = lookup_value;
 
       Uskip_whitespace(&s);
       if (!(next_s = eval_condition(s, &resetok, skipping ? NULL : &cond)))
@@ -4834,6 +4836,7 @@ while (*s)
       /* Restore external setting of expansion variables for continuation
       at this level. */
 
+      lookup_value = save_lookup_value;
       restore_expand_strings(save_expand_nmax, save_expand_nstring,
         save_expand_nlength);
       break;
@@ -6544,6 +6547,9 @@ while (*s)
         item of the output list, add in a space if the new item begins with the
         separator character, or is an empty string. */
 
+/*XXX is there not a standard support function for this, appending to a list? */
+/* yes, string_append_listele(), but it depends on lack of text before the list */
+
         if (  yield && yield->ptr != save_ptr
           && (temp[0] == *outsep || temp[0] == 0))
           yield = string_catn(yield, US" ", 1);