diff --git a/src/detect-engine-analyzer.c b/src/detect-engine-analyzer.c index 188424d229..f5ec80e83c 100644 --- a/src/detect-engine-analyzer.c +++ b/src/detect-engine-analyzer.c @@ -781,6 +781,10 @@ static void DumpMatches(RuleAnalyzer *ctx, SCJsonBuilder *js, const SigMatchData AnalyzerNote(ctx, (char *)"'/B' (rawbytes) option is a no-op and is silently ignored"); } + if (cd->flags & DETECT_PCRE_HAS_UNICODE_CLUSTER) { + AnalyzerNote(ctx, (char *)"pcre with \\X (Unicode extended grapheme cluster) " + "may be slow"); + } break; } case DETECT_BYTEJUMP: { diff --git a/src/detect-pcre.c b/src/detect-pcre.c index 4a97d43a88..cafcb37e58 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -366,6 +366,11 @@ static int DetectPcreSetList(int list, int set) return set; } +static bool DetectPcreHasUnicodeCluster(const char *re) +{ + return strstr(re, "\\X") != NULL; +} + static int DetectPcreHasUpperCase(const char *re) { size_t len = strlen(re); @@ -709,21 +714,15 @@ static DetectPcreData *DetectPcreParse (DetectEngineCtx *de_ctx, if (capture_names == NULL || strlen(capture_names) == 0) opts |= PCRE2_NO_AUTO_CAPTURE; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION // forbid use of \X Unicode extended grapheme cluster as slow - bool escape = false; - for (size_t i = 0; i < strlen(re); i++) { - if (escape) { - if (re[i] == 'X') { - goto error; - } - escape = false; - } else if (re[i] == '\\') { - escape = true; - } + if (DetectPcreHasUnicodeCluster(re)) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + goto error; +#else + pd->flags |= DETECT_PCRE_HAS_UNICODE_CLUSTER; +#endif } -#endif pd->parse_regex.regex = pcre2_compile((PCRE2_SPTR8)re, PCRE2_ZERO_TERMINATED, opts, &en, &eo2, NULL); if (pd->parse_regex.regex == NULL && en == 115) { // reference to nonexistent subpattern diff --git a/src/detect-pcre.h b/src/detect-pcre.h index dc20f4194c..740fd3453b 100644 --- a/src/detect-pcre.h +++ b/src/detect-pcre.h @@ -33,6 +33,7 @@ #define DETECT_PCRE_RELATIVE_NEXT 0x00040 #define DETECT_PCRE_NEGATE 0x00080 +#define DETECT_PCRE_HAS_UNICODE_CLUSTER 0x00100 #define DETECT_PCRE_CAPTURE_MAX 8