[exim-cvs] JSON: add jsons extract variant, to strip quotes…

Inizio della pagina
Delete this message
Reply to this message
Autore: Exim Git Commits Mailing List
Data:  
To: exim-cvs
Oggetto: [exim-cvs] JSON: add jsons extract variant, to strip quotes from string results
Gitweb: https://git.exim.org/exim.git/commitdiff/386ab6457bb9dd4901391ffe7ceb5fbe08705c09
Commit:     386ab6457bb9dd4901391ffe7ceb5fbe08705c09
Parent:     1fa1333ca1a744ce7fa8af3fc73872b082631fe3
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Tue Jan 22 20:57:58 2019 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Jan 22 20:57:58 2019 +0000


    JSON: add jsons extract variant, to strip quotes from string results
---
 doc/doc-docbook/spec.xfpt    | 14 ++++++++++++--
 src/src/expand.c             | 19 ++++++++++++++++---
 test/scripts/0000-Basic/0002 |  3 +++
 test/stdout/0002             |  5 ++++-
 4 files changed, 35 insertions(+), 6 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index d21a718..d762f97 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -9412,6 +9412,8 @@ This forces an expansion failure (see section &<<SECTforexpfai>>&);
 .new
 .vitem "&*${extract json{*&<&'key'&>&*}{*&<&'string1'&>&*}{*&<&'string2'&>&*}&&&
        {*&<&'string3'&>&*}}*&"
+.vitem "&*${extract jsons{*&<&'key'&>&*}{*&<&'string1'&>&*}{*&<&'string2'&>&*}&&&
+       {*&<&'string3'&>&*}}*&"
 .cindex "expansion" "extracting from JSON object"
 .cindex JSON expansions
 The key and <&'string1'&> are first expanded separately. Leading and trailing
@@ -9425,8 +9427,11 @@ The expanded <&'string1'&> must be of the form:
 The braces, commas and colons, and the quoting of the member name are required;
 the spaces are optional.
 Matching of the key against the member names is done case-sensitively.
-If a returned value is a JSON string, it retains its leading and
+For the &"json"& variant,
+if a returned value is a JSON string, it retains its leading and
 trailing quotes.
+For the &"jsons"& variant, which is intended for use with JSON strings, the
+leading and trailing quotes are removed.
 . XXX should be a UTF-8 compare


 The results of matching are handled as above.
@@ -9467,6 +9472,8 @@ empty (for example, the fifth field above).
 .new
 .vitem "&*${extract json{*&<&'number'&>&*}}&&&
         {*&<&'string1'&>&*}{*&<&'string2'&>&*}{*&<&'string3'&>&*}}*&"
+.vitem "&*${extract jsons{*&<&'number'&>&*}}&&&
+        {*&<&'string1'&>&*}{*&<&'string2'&>&*}{*&<&'string3'&>&*}}*&"
 .cindex "expansion" "extracting from JSON array"
 .cindex JSON expansions
 The <&'number'&> argument must consist entirely of decimal digits,
@@ -9474,8 +9481,11 @@ apart from leading and trailing white space, which is ignored.


Field selection and result handling is as above;
there is no choice of field separator.
-If a returned value is a JSON string, it retains its leading and
+For the &"json"& variant,
+if a returned value is a JSON string, it retains its leading and
trailing quotes.
+For the &"jsons"& variant, which is intended for use with JSON strings, the
+leading and trailing quotes are removed.
.wen


diff --git a/src/src/expand.c b/src/src/expand.c
index 2f05737..6791487 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -5635,7 +5635,7 @@ while (*s != 0)
       uschar *sub[3];
       int save_expand_nmax =
         save_expand_strings(save_expand_nstring, save_expand_nlength);
-      enum {extract_basic, extract_json} fmt = extract_basic;
+      enum {extract_basic, extract_json, extract_jsons} fmt = extract_basic;


       while (isspace(*s)) s++;


@@ -5643,7 +5643,10 @@ while (*s != 0)

       if (*s != '{')                    /*}*/
     if (Ustrncmp(s, "json", 4) == 0)
-      {fmt = extract_json; s += 4;}
+      if (*(s += 4) == 's')
+        {fmt = extract_jsons; s++;}
+      else
+        fmt = extract_json;


       /* While skipping we cannot rely on the data for expansions being
       available (eg. $item) hence cannot decide on numeric vs. keyed.
@@ -5724,7 +5727,7 @@ while (*s != 0)
         if (*p == 0)
           {
           field_number *= x;
-          if (fmt != extract_json) j = 3;               /* Need 3 args */
+          if (fmt == extract_basic) j = 3;               /* Need 3 args */
           field_number_set = TRUE;
           }
             }
@@ -5751,6 +5754,7 @@ while (*s != 0)
       break;


     case extract_json:
+    case extract_jsons:
       {
       uschar * s, * item;
       const uschar * list;
@@ -5816,6 +5820,15 @@ while (*s != 0)
           }
         }
       }
+
+      if (fmt == extract_jsons)
+        if (!(lookup_value = dewrap(lookup_value, US"\"\"")))
+          {
+          expand_string_message =
+        string_sprintf("%s wrapping string result for extract jsons",
+          expand_string_message);
+          goto EXPAND_FAILED_CURLY;
+          }
     }


       /* If no string follows, $value gets substituted; otherwise there can
diff --git a/test/scripts/0000-Basic/0002 b/test/scripts/0000-Basic/0002
index 7a9b38d..3974452 100644
--- a/test/scripts/0000-Basic/0002
+++ b/test/scripts/0000-Basic/0002
@@ -893,6 +893,9 @@ ${extract json {Width} \
 ${extract json {2} {[116, 943, 234, 38793]} }
 ${extract json {2} {${extract json{IDs} {\{"other":"foo", "IDs": [116, 943, 234]\} }}} }


+${extract json {2} {["red", "green", "blue", "black"]} }
+${extract jsons{2} {["red", "green", "blue", "black"]} }
+
${extract json {seconds} { \{"hours":0, "mins":0, "seconds":59\} }}
${extract json {seconds} {${extract json {2} { ["irrelevant", \{"hours":0, "mins":0, "seconds":59\}] }}}}

diff --git a/test/stdout/0002 b/test/stdout/0002
index 44117a9..dd54b16 100644
--- a/test/stdout/0002
+++ b/test/stdout/0002
@@ -836,6 +836,9 @@ xyz
> 943
> 943
>

+> "green"
+> green
+>
> 59
> 59
>

@@ -845,7 +848,7 @@ xyz
> {"1":116, "2":943, "3":234}
> expect: {"1":116, "2":943, "3":234}
>

-> Failed: missing '"' wrapping string key for extract json
+> <>
> expect: <>
>
>