]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-regex: Separate maximum capture groups and match limit
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 22 Dec 2025 09:04:16 +0000 (11:04 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Mon, 22 Dec 2025 12:53:21 +0000 (12:53 +0000)
These are not related.

src/lib-regex/regex.c

index e402e6a49da1721a69723c9a161470b42c5eff1d..51e7d6c5130656d8d0d624340b1af1d73f469031 100644 (file)
@@ -15,6 +15,7 @@
 
 #define DREGEX_MAX_DEPTH 100
 #define DREGEX_MAX_MATCHES 100
+#define DREGEX_MAX_CAPTURE_GROUPS 100
 #define DREGEX_MAX_CPU_SECONDS 1
 
 struct dregex_code {
@@ -85,7 +86,7 @@ static void dregex_code_init(struct dregex_code *code)
 #endif
 
        /* Set some limits */
-       pcre2_set_match_limit(code->mctx, code->max_capture_groups);
+       pcre2_set_match_limit(code->mctx, DREGEX_MAX_MATCHES);
        pcre2_set_depth_limit(code->mctx, code->max_depth);
 }
 
@@ -104,7 +105,7 @@ struct dregex_code *dregex_code_create_params(const struct dregex_params *params
 static const struct dregex_params default_params = {
        .max_depth = DREGEX_MAX_DEPTH,
        .max_cpu_seconds = DREGEX_MAX_CPU_SECONDS,
-       .max_capture_groups = DREGEX_MAX_MATCHES,
+       .max_capture_groups = DREGEX_MAX_CAPTURE_GROUPS,
 };
 
 struct dregex_code *dregex_code_create(void)
@@ -337,7 +338,10 @@ int dregex_code_match_groups(struct dregex_code *code, const char *subject,
                pcre2_match_data *mdata =
                        pcre2_match_data_create_from_pattern(code->pat, code->gctx);
                ret = dregex_code_match_int(code, subject, mdata, error_r);
-               if (ret > 1) {
+               /* Avoid extracting way too many capture groups */
+               if (ret > (int)code->max_capture_groups + 1)
+                       ret = handle_error(PCRE2_ERROR_TOO_MANY_CAPTURES, error_r);
+               else if (ret > 1) {
                        bool skip_empty = HAS_ALL_BITS(code->flags, DREGEX_NO_EMPTY_SUB);
                        /* ret is number of groups */
                        extract_matches((uint32_t)ret, mdata, skip_empty, groups_r);