X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b72aab7255159ea38ddcd7eef1051da0f07a7b8d..9e949f00f404d3672b1ecd7c1bfd5e8927a3301d:/src/src/expand.c diff --git a/src/src/expand.c b/src/src/expand.c index 287129c2f..fb6d6922b 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,5 +1,3 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.108 2010/06/07 08:42:15 pdp Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ @@ -328,9 +326,9 @@ enum { /* Type for main variable table */ typedef struct { - char *name; - int type; - void *value; + const char *name; + int type; + void *value; } var_entry; /* Type for entries pointing to address/length pairs. Not currently @@ -389,6 +387,9 @@ static var_entry var_table[] = { { "authenticated_id", vtype_stringptr, &authenticated_id }, { "authenticated_sender",vtype_stringptr, &authenticated_sender }, { "authentication_failed",vtype_int, &authentication_failed }, +#ifdef WITH_CONTENT_SCAN + { "av_failed", vtype_int, &av_failed }, +#endif #ifdef EXPERIMENTAL_BRIGHTMAIL { "bmi_alt_location", vtype_stringptr, &bmi_alt_location }, { "bmi_base64_tracker_verdict", vtype_stringptr, &bmi_base64_tracker_verdict }, @@ -632,9 +633,9 @@ static BOOL malformed_header; /* For textual hashes */ -static char *hashcodes = "abcdefghijklmnopqrtsuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"; +static const char *hashcodes = "abcdefghijklmnopqrtsuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; enum { HMAC_MD5, HMAC_SHA1 }; @@ -1587,7 +1588,7 @@ while (last > first) return tod_stamp(tod_zulu); case vtype_todlf: /* Log file datestamp tod */ - return tod_stamp(tod_log_datestamp); + return tod_stamp(tod_log_datestamp_daily); case vtype_reply: /* Get reply address */ s = find_header(US"reply-to:", exists_only, newsize, TRUE, @@ -2558,7 +2559,7 @@ switch(cond_type) "value \"%s\"", t); return NULL; } - if (yield != NULL) *yield = (boolvalue != 0); + if (yield != NULL) *yield = (boolvalue == testfor); return s; } @@ -3106,9 +3107,47 @@ if (*error == NULL) int op = *s++; int y = eval_op_unary(&s, decimal, error); if (*error != NULL) break; - if (op == '*') x *= y; - else if (op == '/') x /= y; - else x %= y; + /* SIGFPE both on div/mod by zero and on INT_MIN / -1, which would give + * a value of INT_MAX+1. Note that INT_MIN * -1 gives INT_MIN for me, which + * is a bug somewhere in [gcc 4.2.1, FreeBSD, amd64]. In fact, -N*-M where + * -N*M is INT_MIN will yielf INT_MIN. + * Since we don't support floating point, this is somewhat simpler. + * Ideally, we'd return an error, but since we overflow for all other + * arithmetic, consistency suggests otherwise, but what's the correct value + * to use? There is none. + * The C standard guarantees overflow for unsigned arithmetic but signed + * overflow invokes undefined behaviour; in practice, this is overflow + * except for converting INT_MIN to INT_MAX+1. We also can't guarantee + * that long/longlong larger than int are available, or we could just work + * with larger types. We should consider whether to guarantee 32bit eval + * and 64-bit working variables, with errors returned. For now ... + * So, the only SIGFPEs occur with a non-shrinking div/mod, thus -1; we + * can just let the other invalid results occur otherwise, as they have + * until now. For this one case, we can coerce. + */ + if (y == -1 && x == INT_MIN && op != '*') + { + DEBUG(D_expand) + debug_printf("Integer exception dodging: %d%c-1 coerced to %d\n", + INT_MIN, op, INT_MAX); + x = INT_MAX; + continue; + } + if (op == '*') + x *= y; + else + { + if (y == 0) + { + *error = (op == '/') ? US"divide by zero" : US"modulo by zero"; + x = 0; + break; + } + if (op == '/') + x /= y; + else + x %= y; + } } } *sptr = s;