From: Jeremy Harris Date: Mon, 20 Jun 2022 11:38:20 +0000 (+0100) Subject: Regex cache observability X-Git-Tag: exim-4.97-RC0~282^2 X-Git-Url: https://git.exim.org/exim.git/commitdiff_plain/89318c714454e11217505d2163d807d5d827f50a Regex cache observability --- diff --git a/src/src/expand.c b/src/src/expand.c index 5147c51e7..acde8d516 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -692,6 +692,7 @@ static var_entry var_table[] = { { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, { "recipients", vtype_string_func, (void *) &fn_recipients }, { "recipients_count", vtype_int, &recipients_count }, + { "regex_cachesize", vtype_int, ®ex_cachesize },/* undocumented; devel observability */ #ifdef WITH_CONTENT_SCAN { "regex_match_string", vtype_stringptr, ®ex_match_string }, #endif diff --git a/src/src/globals.c b/src/src/globals.c index 49988a8cc..c95d24b47 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1317,6 +1317,7 @@ const pcre2_code *regex_SIZE = NULL; #ifndef DISABLE_PIPE_CONNECT const pcre2_code *regex_EARLY_PIPE = NULL; #endif +int regex_cachesize = 0; const pcre2_code *regex_ismsgid = NULL; const pcre2_code *regex_smtp_code = NULL; const uschar *regex_vars[REGEX_VARS]; diff --git a/src/src/globals.h b/src/src/globals.h index 3d5584555..c9ef5e484 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -899,6 +899,7 @@ extern const pcre2_code *regex_SIZE; /* For recognizing SIZE settings */ #ifndef DISABLE_PIPE_CONNECT extern const pcre2_code *regex_EARLY_PIPE; /* For recognizing PIPE_CONNCT */ #endif +extern int regex_cachesize; /* number of entries */ extern const pcre2_code *regex_ismsgid; /* Compiled r.e. for message ID */ extern const pcre2_code *regex_smtp_code; /* For recognizing SMTP codes */ extern const uschar *regex_vars[]; /* $regexN variables */ diff --git a/src/src/regex_cache.c b/src/src/regex_cache.c index 6ac134cd8..63cddce1d 100644 --- a/src/src/regex_cache.c +++ b/src/src/regex_cache.c @@ -39,6 +39,8 @@ typedef struct re_req { static tree_node * regex_cache = NULL; static tree_node * regex_caseless_cache = NULL; +#define REGEX_CACHESIZE_LIMIT 1000 + /******************************************************************************/ static void @@ -236,9 +238,14 @@ regex_at_daemon(const uschar * reqbuf) { const re_req * req = (const re_req *)reqbuf; uschar * errstr; -const pcre2_code * cre = regex_compile(req->re, - req->caseless ? MCS_CASELESS | MCS_CACHEABLE : MCS_CACHEABLE, - &errstr, pcre_gen_cmp_ctx); +const pcre2_code * cre; + +if (regex_cachesize >= REGEX_CACHESIZE_LIMIT) + errstr = US"regex cache size limit reached"; +else if ((cre = regex_compile(req->re, + req->caseless ? MCS_CASELESS | MCS_CACHEABLE : MCS_CACHEABLE, + &errstr, pcre_gen_cmp_ctx))) + regex_cachesize++; DEBUG(D_any) if (!cre) debug_printf("%s\n", errstr); return;