diff options
author | Phil Pennock <pdp@exim.org> | 2010-06-07 08:23:20 +0000 |
---|---|---|
committer | Phil Pennock <pdp@exim.org> | 2010-06-07 08:23:20 +0000 |
commit | 6a8de8541c16d12eceab2c6610cd209e7641217a (patch) | |
tree | ab3754913669353b7a6292e51cfabedae8fd7ad5 /src | |
parent | 532be4499552dfab0e3173f7d3e85c81e1496147 (diff) |
Added bool_lax{} expansion operator, which uses Router condition logic to
determine whether or not a string is true.
Switch the multiple-condition logic to use bool_lax{}.
Add note where we combine multiple conditions regarding the memory leak.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/expand.c | 32 | ||||
-rw-r--r-- | src/src/readconf.c | 21 |
2 files changed, 43 insertions, 10 deletions
diff --git a/src/src/expand.c b/src/src/expand.c index e5daff1a8..9f9cbb7be 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.106 2010/06/05 23:50:18 pdp Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.107 2010/06/07 08:23:20 pdp Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -247,6 +247,7 @@ static uschar *cond_table[] = { US">=", US"and", US"bool", + US"bool_lax", US"crypteq", US"def", US"eq", @@ -289,6 +290,7 @@ enum { ECOND_NUM_GE, ECOND_AND, ECOND_BOOL, + ECOND_BOOL_LAX, ECOND_CRYPTEQ, ECOND_DEF, ECOND_STR_EQ, @@ -734,6 +736,8 @@ or "false" value. Failure of the expansion yields FALSE; logged unless it was a forced fail or lookup defer. All store used by the function can be released on exit. +The actual false-value tests should be replicated for ECOND_BOOL_LAX. + Arguments: condition the condition string m1 text to be incorporated in panic error @@ -2491,19 +2495,25 @@ switch(cond_type) interpretation, where general data can be used and only a few values map to FALSE. Note that readconf.c boolean matching, for boolean configuration options, - only matches true/yes/false/no. */ + only matches true/yes/false/no. + The bool_lax{} condition matches the Router logic, which is much more + liberal. */ case ECOND_BOOL: + case ECOND_BOOL_LAX: { uschar *sub_arg[1]; uschar *t; + uschar *ourname; size_t len; BOOL boolvalue = FALSE; while (isspace(*s)) s++; if (*s != '{') goto COND_FAILED_CURLY_START; - switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, US"bool")) + ourname = cond_type == ECOND_BOOL_LAX ? US"bool_lax" : US"bool"; + switch(read_subs(sub_arg, 1, 1, &s, yield == NULL, FALSE, ourname)) { - case 1: expand_string_message = US"too few arguments or bracketing " - "error for bool"; + case 1: expand_string_message = string_sprintf( + "too few arguments or bracketing error for %s", + ourname); /*FALLTHROUGH*/ case 2: case 3: return NULL; @@ -2512,15 +2522,25 @@ switch(cond_type) while (isspace(*t)) t++; len = Ustrlen(t); DEBUG(D_expand) - debug_printf("considering bool: %s\n", len ? t : US"<empty>"); + debug_printf("considering %s: %s\n", ourname, len ? t : US"<empty>"); + /* logic for the lax case from expand_check_condition(), which also does + expands, and the logic is both short and stable enough that there should + be no maintenance burden from replicating it. */ if (len == 0) boolvalue = FALSE; else if (Ustrspn(t, "0123456789") == len) + { boolvalue = (Uatoi(t) == 0) ? FALSE : TRUE; + /* expand_check_condition only does a literal string "0" check */ + if ((cond_type == ECOND_BOOL_LAX) && (len > 1)) + boolvalue = TRUE; + } else if (strcmpic(t, US"true") == 0 || strcmpic(t, US"yes") == 0) boolvalue = TRUE; else if (strcmpic(t, US"false") == 0 || strcmpic(t, US"no") == 0) boolvalue = FALSE; + else if (cond_type == ECOND_BOOL_LAX) + boolvalue = TRUE; else { expand_string_message = string_sprintf("unrecognised boolean " diff --git a/src/src/readconf.c b/src/src/readconf.c index 6fd0dd8ea..6b11621e0 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/readconf.c,v 1.42 2010/06/07 07:09:10 pdp Exp $ */ +/* $Cambridge: exim/src/src/readconf.c,v 1.43 2010/06/07 08:23:20 pdp Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1516,12 +1516,25 @@ switch (type) str_target = (uschar **)((uschar *)data_block + (long int)(ol->value)); if (extra_condition) { - /* We already have a condition, we're conducting a crude hack to let multiple - condition rules be chained together, despite storing them in text form. */ + /* We already have a condition, we're conducting a crude hack to let + multiple condition rules be chained together, despite storing them in + text form. */ saved_condition = *str_target; - strtemp = string_sprintf("${if and{{bool{%s}}{bool{%s}}}}", + strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}", saved_condition, sptr); *str_target = string_copy_malloc(strtemp); + /* TODO(pdp): there is a memory leak here when we set 3 or more + conditions; I still don't understand the store mechanism enough + to know what's the safe way to free content from an earlier store. + AFAICT, stores stack, so freeing an early stored item also stores + all data alloc'd after it. If we knew conditions were adjacent, + we could survive that, but we don't. So I *think* we need to take + another bit from opt_type to indicate "malloced"; this seems like + quite a hack, especially for this one case. It also means that + we can't ever reclaim the store from the *first* condition. + + Because we only do this once, near process start-up, I'm prepared to + let this slide for the time being, even though it rankles. */ } else { |