From: Jeremy Harris Date: Sun, 16 Jul 2017 17:02:57 +0000 (+0100) Subject: Optimise scanning config for macros X-Git-Tag: exim-4_90_RC1~109 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/b8f899cf1da8ce1587f32c438a0def6d7332bc1e Optimise scanning config for macros --- diff --git a/src/src/exim.c b/src/src/exim.c index 42cb710eb..0285e162a 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1443,10 +1443,9 @@ for (m = macros; m; m = m->next) if (m->command_line) } if (!found) return FALSE; - if (m->replacement == NULL) + if (!m->replacement) continue; - len = Ustrlen(m->replacement); - if (len == 0) + if ((len = m->replen) == 0) continue; n = pcre_exec(regex_whitelisted_macro, NULL, CS m->replacement, len, 0, PCRE_EOPT, NULL, 0); diff --git a/src/src/macro_predef.c b/src/src/macro_predef.c index 5ba237929..59579a373 100644 --- a/src/src/macro_predef.c +++ b/src/src/macro_predef.c @@ -29,7 +29,7 @@ if (mp_index == 0) else printf("&p%d,", mp_index-1); -printf(" FALSE, %d, \"%s\", \"y\" };\n", Ustrlen(name), CS name); +printf(" FALSE, %d, 1, \"%s\", \"y\" };\n", Ustrlen(name), CS name); mp_index++; } diff --git a/src/src/readconf.c b/src/src/readconf.c index 53f815d53..df3fe823c 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -604,13 +604,13 @@ Args: macro_item * macro_create(const uschar * name, const uschar * val, BOOL command_line) { -unsigned namelen = Ustrlen(name); macro_item * m = store_get(sizeof(macro_item)); /* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */ m->next = NULL; m->command_line = command_line; -m->namelen = namelen; +m->namelen = Ustrlen(name); +m->replen = Ustrlen(val); m->name = name; m->replacement = val; mlast->next = m; @@ -701,7 +701,10 @@ if (m && m->command_line) return; if (redef) if (m) + { + m->replen = Ustrlen(s); m->replacement = string_copy(s); + } else log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro " "\"%s\"", name); @@ -825,24 +828,28 @@ for (;;) if (*s != '=') s = ss; /* Not a macro definition */ } + /* Skip leading chars which cannot start a macro name, to avoid multiple + pointless rescans in Ustrstr calls. */ + + while (*s && !isupper(*s) && *s != '_') s++; + /* For each defined macro, scan the line (from after XXX= if present), replacing all occurrences of the macro. */ macro_found = FALSE; for (m = macros; m; m = m->next) { - uschar *p, *pp; - uschar *t = s; + uschar * p, *pp; + uschar * t = s; while ((p = Ustrstr(t, m->name)) != NULL) { int moveby; - int replen = Ustrlen(m->replacement); -/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t); */ +/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */ /* Expand the buffer if necessary */ - while (newlen - m->namelen + replen + 1 > big_buffer_size) + while (newlen - m->namelen + m->replen + 1 > big_buffer_size) { int newsize = big_buffer_size + BIG_BUFFER_SIZE; uschar *newbuffer = store_malloc(newsize); @@ -861,13 +868,14 @@ for (;;) same macro. */ pp = p + m->namelen; - if ((moveby = replen - m->namelen) != 0) + if ((moveby = m->replen - m->namelen) != 0) { - memmove(p + replen, pp, (big_buffer + newlen) - pp + 1); + memmove(p + m->replen, pp, (big_buffer + newlen) - pp + 1); newlen += moveby; } - Ustrncpy(p, m->replacement, replen); - t = p + replen; + Ustrncpy(p, m->replacement, m->replen); + t = p + m->replen; + while (*t && !isupper(*t) && *t != '_') t++; macro_found = TRUE; } } diff --git a/src/src/structs.h b/src/src/structs.h index 14d109869..885c1b500 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -31,6 +31,7 @@ typedef struct macro_item { struct macro_item * next; BOOL command_line; unsigned namelen; + unsigned replen; const uschar * name; const uschar * replacement; } macro_item;