[exim-cvs] Expansion item ${listquote }. Bug 1066

Startseite
Nachricht löschen
Nachricht beantworten
Autor: Exim Git Commits Mailing List
Datum:  
To: exim-cvs
Betreff: [exim-cvs] Expansion item ${listquote }. Bug 1066
Gitweb: https://git.exim.org/exim.git/commitdiff/48b30ae1141cbce9fe6f1153f368dd63a4505775
Commit:     48b30ae1141cbce9fe6f1153f368dd63a4505775
Parent:     0b4dfe7aa1f12214abdfa1037497d6c49a471612
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Mon Apr 6 16:20:35 2020 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Mon Apr 6 16:20:35 2020 +0100


    Expansion item ${listquote }.  Bug 1066
---
 doc/doc-txt/NewStuff         |  2 ++
 src/src/expand.c             | 55 ++++++++++++++++++++++++++++++--------------
 test/scripts/0000-Basic/0002 |  8 +++++++
 test/stdout/0002             |  8 +++++++
 4 files changed, 56 insertions(+), 17 deletions(-)


diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 80d3525..f922f2c 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -54,6 +54,8 @@ Version 4.94
 14. Options on pgsql and mysql lookups, to specify server separate from the
     lookup string.


+15. Expansion item ${listquote {<char} {<item>}}
+


 Version 4.93
diff --git a/src/src/expand.c b/src/src/expand.c
index 789f099..6d9a169 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -117,6 +117,7 @@ static uschar *item_table[] = {
 #endif
   US"length",
   US"listextract",
+  US"listquote",
   US"lookup",
   US"map",
   US"nhash",
@@ -151,6 +152,7 @@ enum {
 #endif
   EITEM_LENGTH,
   EITEM_LISTEXTRACT,
+  EITEM_LISTQUOTE,
   EITEM_LOOKUP,
   EITEM_MAP,
   EITEM_NHASH,
@@ -2744,7 +2746,7 @@ switch(cond_type = identify_operator(&s, &opname))
     if (*s++ != '{') goto COND_FAILED_CURLY_START;    /*}*/


     switch(read_subs(sub, nelem(sub), 1,
-      &s, yield == NULL, TRUE, US"acl", resetok))
+      &s, yield == NULL, TRUE, name, resetok))
       {
       case 1: expand_string_message = US"too few arguments or bracketing "
         "error for acl";
@@ -2795,7 +2797,7 @@ switch(cond_type = identify_operator(&s, &opname))
     uschar *sub[4];
     while (isspace(*s)) s++;
     if (*s++ != '{') goto COND_FAILED_CURLY_START;    /* }-for-text-editors */
-    switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, US"saslauthd",
+    switch(read_subs(sub, nelem(sub), 2, &s, yield == NULL, TRUE, name,
             resetok))
       {
       case 1: expand_string_message = US"too few arguments or bracketing "
@@ -3457,7 +3459,7 @@ switch(cond_type = identify_operator(&s, &opname))
     uschar cksum[4];
     BOOL boolvalue = FALSE;


-    switch(read_subs(sub, 2, 2, CUSS &s, yield == NULL, FALSE, US"inbound_srs", resetok))
+    switch(read_subs(sub, 2, 2, CUSS &s, yield == NULL, FALSE, name, resetok))
       {
       case 1: expand_string_message = US"too few arguments or bracketing "
     "error for inbound_srs";
@@ -4599,7 +4601,7 @@ while (*s != 0)
       uschar *user_msg;
       int rc;


-      switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, US"acl",
+      switch(read_subs(sub, nelem(sub), 1, &s, skipping, TRUE, name,
               &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
@@ -4980,7 +4982,7 @@ while (*s != 0)
         }


       switch(read_subs(sub_arg, EXIM_PERL_MAX_ARGS + 1, 1, &s, skipping, TRUE,
-           US"perl", &resetok))
+           name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -5051,7 +5053,7 @@ while (*s != 0)
       uschar *sub_arg[3];
       uschar *p,*domain;


-      switch(read_subs(sub_arg, 3, 2, &s, skipping, TRUE, US"prvs", &resetok))
+      switch(read_subs(sub_arg, 3, 2, &s, skipping, TRUE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -5125,7 +5127,7 @@ while (*s != 0)
       prvscheck_address = NULL;
       prvscheck_keynum = NULL;


-      switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs", &resetok))
+      switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -5157,7 +5159,7 @@ while (*s != 0)
         prvscheck_keynum = string_copy(key_num);


         /* Now expand the second argument */
-        switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, US"prvs", &resetok))
+        switch(read_subs(sub_arg, 1, 1, &s, skipping, FALSE, name, &resetok))
           {
           case 1: goto EXPAND_FAILED_CURLY;
           case 2:
@@ -5211,7 +5213,7 @@ while (*s != 0)
         /* Now expand the final argument. We leave this till now so that
         it can include $prvscheck_result. */


-        switch(read_subs(sub_arg, 1, 0, &s, skipping, TRUE, US"prvs", &resetok))
+        switch(read_subs(sub_arg, 1, 0, &s, skipping, TRUE, name, &resetok))
           {
           case 1: goto EXPAND_FAILED_CURLY;
           case 2:
@@ -5232,7 +5234,7 @@ while (*s != 0)
            We need to make sure all subs are expanded first, so as to skip over
            the entire item. */


-        switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, US"prvs", &resetok))
+        switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok))
           {
           case 1: goto EXPAND_FAILED_CURLY;
           case 2:
@@ -5255,7 +5257,7 @@ while (*s != 0)
         goto EXPAND_FAILED;
         }


-      switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, US"readfile", &resetok))
+      switch(read_subs(sub_arg, 2, 1, &s, skipping, TRUE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -5305,7 +5307,7 @@ while (*s != 0)
       /* Read up to 4 arguments, but don't do the end of item check afterwards,
       because there may be a string for expansion on failure. */


-      switch(read_subs(sub_arg, 4, 2, &s, skipping, FALSE, US"readsocket", &resetok))
+      switch(read_subs(sub_arg, 4, 2, &s, skipping, FALSE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:                             /* Won't occur: no end check */
@@ -5692,7 +5694,7 @@ while (*s != 0)
       int o2m;
       uschar *sub[3];


-      switch(read_subs(sub, 3, 3, &s, skipping, TRUE, US"tr", &resetok))
+      switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -5904,7 +5906,7 @@ while (*s != 0)
       int save_expand_nmax =
         save_expand_strings(save_expand_nstring, save_expand_nlength);


-      switch(read_subs(sub, 3, 3, &s, skipping, TRUE, US"sg", &resetok))
+      switch(read_subs(sub, 3, 3, &s, skipping, TRUE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -6253,7 +6255,7 @@ while (*s != 0)


       for (int i = 0; i < 2; i++)
         {
-        while (isspace(*s)) s++;
+        skip_whitespace(&s);
         if (*s != '{')                    /*'}'*/
       {
       expand_string_message = string_sprintf(
@@ -6338,6 +6340,23 @@ while (*s != 0)
       continue;
       }


+    case EITEM_LISTQUOTE:
+      {
+      uschar * sub[2];
+      switch(read_subs(sub, 2, 2, &s, skipping, TRUE, name, &resetok))
+        {
+        case 1: goto EXPAND_FAILED_CURLY;
+        case 2:
+        case 3: goto EXPAND_FAILED;
+        }
+      for (uschar sep = *sub[0], c; c = *sub[1]; sub[1]++)
+    {
+    if (c == sep) yield = string_catn(yield, sub[1], 1);
+    yield = string_catn(yield, sub[1], 1);
+    }
+      continue;
+      }
+
 #ifndef DISABLE_TLS
     case EITEM_CERTEXTRACT:
       {
@@ -6347,7 +6366,7 @@ while (*s != 0)
         save_expand_strings(save_expand_nstring, save_expand_nlength);


       /* Read the field argument */
-      while (isspace(*s)) s++;
+      skip_whitespace(&s);
       if (*s != '{')                    /*}*/
     {
     expand_string_message = US"missing '{' for field arg of certextract";
@@ -6825,7 +6844,7 @@ while (*s != 0)
         }


       switch(read_subs(argv, EXPAND_DLFUNC_MAX_ARGS + 2, 2, &s, skipping,
-           TRUE, US"dlfunc", &resetok))
+           TRUE, name, &resetok))
         {
         case 1: goto EXPAND_FAILED_CURLY;
         case 2:
@@ -7445,6 +7464,8 @@ while (*s != 0)
         continue;
     }


+      /* quote a list-item for the given list-separator */
+
       /* mask applies a mask to an IP address; for example the result of
       ${mask:131.111.10.206/28} is 131.111.10.192/28. */


diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002
index 2bf8f16..db8d709 100644
--- a/test/scripts/0000-Basic/0002
+++ b/test/scripts/0000-Basic/0002
@@ -126,6 +126,14 @@ listextract: ${listextract{-5}{a:b:c:d}}
listextract: ${listextract{ 5}{a:b:c:d}{}{fail}}
listextract: ${listextract{ 5}{a:b:c:d}{}fail}

+listquote: ${listquote{:}{abcd}}
+listquote: ${listquote{:}{ab:cd}}
+listquote: ${listquote{:}{:a:b:c:d:}}
+listquote: ${listquote{:}{ab::cd}}
+listquote: ${listquote{;}{ab:cd}}
+listquote: ${listquote{;}{ab;cd}}
+listquote: ${listquote{ }{ ab cd}}
+
sort: ${sort{3:2:1:4}{<}{$item}}
sort: ${sort {<, 3,2,1,4}{>}{$item}}
sort: ${sort{c:B:a:aa}{lti}{$item}}
diff --git a/test/stdout/0002 b/test/stdout/0002
index 01e96fe..4345a09 100644
--- a/test/stdout/0002
+++ b/test/stdout/0002
@@ -115,6 +115,14 @@
> listextract: fail
> Failed: "listextract" failed and "fail" requested
>

+> listquote: abcd
+> listquote: ab::cd
+> listquote: ::a::b::c::d::
+> listquote: ab::::cd
+> listquote: ab:cd
+> listquote: ab;;cd
+> listquote: ab cd
+>
> sort: 1:2:3:4
> sort: 4,3,2,1
> sort: a:aa:B:c