--- a/src/expand.c
+++ b/src/expand.c
-@@ -2115,6 +2115,55 @@ return ret;
+@@ -2147,6 +2147,55 @@ return ret;
/*************************************************
* Read and evaluate a condition *
-@@ -2145,6 +2194,7 @@ BOOL sub2_honour_dollar = TRUE;
+@@ -2177,6 +2226,7 @@ BOOL sub2_honour_dollar = TRUE;
int i, rc, cond_type, roffset;
int_eximarith_t num[2];
struct stat statbuf;
uschar name[256];
const uschar *sub[10];
-@@ -2157,37 +2207,7 @@ for (;;)
+@@ -2189,37 +2239,7 @@ for (;;)
if (*s == '!') { testfor = !testfor; s++; } else break;
}
{
/* def: tests for a non-empty variable, or for the existence of a header. If
yield == NULL we are in a skipping state, and don't care about the answer. */
-@@ -2506,7 +2526,7 @@ switch(cond_type)
+@@ -2538,7 +2558,7 @@ switch(cond_type)
{
if (i == 0) goto COND_FAILED_CURLY_START;
expand_string_message = string_sprintf("missing 2nd string in {} "
+ "after \"%s\"", opname);
return NULL;
}
- sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL,
-@@ -2518,7 +2538,7 @@ switch(cond_type)
+ if (!(sub[i] = expand_string_internal(s+1, TRUE, &s, yield == NULL,
+@@ -2553,7 +2573,7 @@ switch(cond_type)
conditions that compare numbers do not start with a letter. This just saves
checking for them individually. */
if (sub[i][0] == 0)
{
num[i] = 0;
-@@ -2832,7 +2852,7 @@ switch(cond_type)
+@@ -2867,7 +2887,7 @@ switch(cond_type)
uschar *save_iterate_item = iterate_item;
int (*compare)(const uschar *, const uschar *);
-- DEBUG(D_expand) debug_printf_indent("condition: %s\n", name);
-+ DEBUG(D_expand) debug_printf_indent("condition: %s\n", opname);
+- DEBUG(D_expand) debug_printf_indent("condition: %s item: %s\n", name, sub[0]);
++ DEBUG(D_expand) debug_printf_indent("condition: %s item: %s\n", opname, sub[0]);
tempcond = FALSE;
compare = cond_type == ECOND_INLISTI
-@@ -2871,14 +2891,14 @@ switch(cond_type)
+@@ -2909,14 +2929,14 @@ switch(cond_type)
if (*s != '{') /* }-for-text-editors */
{
expand_string_message = string_sprintf("each subcondition "
return NULL;
}
while (isspace(*s)) s++;
-@@ -2888,7 +2908,7 @@ switch(cond_type)
+@@ -2926,7 +2946,7 @@ switch(cond_type)
{
/* {-for-text-editors */
expand_string_message = string_sprintf("missing } at end of condition "
return NULL;
}
-@@ -2920,7 +2940,7 @@ switch(cond_type)
+@@ -2958,7 +2978,7 @@ switch(cond_type)
int sep = 0;
uschar *save_iterate_item = iterate_item;
while (isspace(*s)) s++;
if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
-@@ -2941,7 +2961,7 @@ switch(cond_type)
+@@ -2979,7 +2999,7 @@ switch(cond_type)
if (!(s = eval_condition(sub[1], resetok, NULL)))
{
expand_string_message = string_sprintf("%s inside \"%s\" condition",
return NULL;
}
while (isspace(*s)) s++;
-@@ -2951,7 +2971,7 @@ switch(cond_type)
+@@ -2989,7 +3009,7 @@ switch(cond_type)
{
/* {-for-text-editors */
expand_string_message = string_sprintf("missing } at end of condition "
return NULL;
}
-@@ -2963,11 +2983,11 @@ switch(cond_type)
+@@ -3001,11 +3021,11 @@ switch(cond_type)
if (!eval_condition(sub[1], resetok, &tempcond))
{
expand_string_message = string_sprintf("%s inside \"%s\" condition",
tempcond? "true":"false");
if (yield != NULL) *yield = (tempcond == testfor);
-@@ -3060,19 +3080,20 @@ switch(cond_type)
+@@ -3098,19 +3118,20 @@ switch(cond_type)
/* Unknown condition */
default:
return NULL;
/* A condition requires code that is not compiled */
-@@ -3082,7 +3103,7 @@ return NULL;
+@@ -3120,7 +3141,7 @@ return NULL;
!defined(SUPPORT_CRYPTEQ) || !defined(CYRUS_SASLAUTHD_SOCKET)
COND_FAILED_NOT_COMPILED:
expand_string_message = string_sprintf("support for \"%s\" not compiled",
return NULL;
#endif
}
-@@ -3793,6 +3814,58 @@ return x;
- }
+@@ -3849,6 +3870,56 @@ return x;
+
+/************************************************/
+}
+
+
-+
-+
+ /* Return pointer to dewrapped string, with enclosing specified chars removed.
+ The given string is modified on return. Leading whitespace is skipped while
+ looking for the opening wrap character, then the rest is scanned for the trailing
+@@ -3905,7 +3976,7 @@ The element may itself be an object or a
+ Return NULL when the list is empty.
+ */
- /*************************************************
- * Expand string *
-@@ -5904,9 +5977,10 @@ while (*s != 0)
+-uschar *
++static uschar *
+ json_nextinlist(const uschar ** list)
+ {
+ unsigned array_depth = 0, object_depth = 0;
+@@ -6243,9 +6314,10 @@ while (*s != 0)
case EITEM_SORT:
{
const uschar *dstlist = NULL, *dstkeylist = NULL;
uschar * tmp;
uschar *save_iterate_item = iterate_item;
-@@ -5941,6 +6015,25 @@ while (*s != 0)
+@@ -6280,6 +6352,25 @@ while (*s != 0)
goto EXPAND_FAILED_CURLY;
}
while (isspace(*s)) s++;
if (*s++ != '{')
{
-@@ -5969,10 +6062,9 @@ while (*s != 0)
+@@ -6307,11 +6398,10 @@ while (*s != 0)
+ if (skipping) continue;
while ((srcitem = string_nextinlist(&srclist, &sep, NULL, 0)))
- {
+- {
- uschar * dstitem;
++ {
+ uschar * srcfield, * dstitem;
- uschar * newlist = NULL;
- uschar * newkeylist = NULL;
+ gstring * newlist = NULL;
+ gstring * newkeylist = NULL;
- uschar * srcfield;
DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, srcitem);
-@@ -5993,25 +6085,15 @@ while (*s != 0)
+@@ -6332,25 +6422,15 @@ while (*s != 0)
while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0)))
{
uschar * dstfield;