summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil Pennock <pdp@exim.org>2010-06-07 08:23:20 +0000
committerPhil Pennock <pdp@exim.org>2010-06-07 08:23:20 +0000
commit6a8de8541c16d12eceab2c6610cd209e7641217a (patch)
treeab3754913669353b7a6292e51cfabedae8fd7ad5 /src
parent532be4499552dfab0e3173f7d3e85c81e1496147 (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.c32
-rw-r--r--src/src/readconf.c21
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
{