summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/src/expand.c1
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/regex_cache.c13
4 files changed, 13 insertions, 3 deletions
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, &regex_cachesize },/* undocumented; devel observability */
#ifdef WITH_CONTENT_SCAN
{ "regex_match_string", vtype_stringptr, &regex_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;