diff --git a/glib/gregex.c b/glib/gregex.c index 5ce034db4..b37a5e04c 100644 --- a/glib/gregex.c +++ b/glib/gregex.c @@ -484,8 +484,6 @@ translate_match_error (gint errcode) /* not used by pcre2_match() */ break; case PCRE2_ERROR_MATCHLIMIT: - case PCRE2_ERROR_JIT_STACKLIMIT: - return _("backtracking limit reached"); case PCRE2_ERROR_CALLOUT: /* callouts are not implemented */ break; @@ -1107,8 +1105,18 @@ g_match_info_next (GMatchInfo *match_info, opts, match_info->match_data, match_info->match_context); + /* if the JIT stack limit was reached, fall back to non-JIT matching in + * the next conditional statement */ + if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT) + { + g_debug ("PCRE2 JIT stack limit reached, falling back to " + "non-optimized matching."); + opts |= PCRE2_NO_JIT; + jit_status = JIT_STATUS_DISABLED; + } } - else + + if (jit_status != JIT_STATUS_ENABLED) { match_info->matches = pcre2_match (match_info->regex->pcre_re, (PCRE2_SPTR8) match_info->string, diff --git a/glib/tests/regex.c b/glib/tests/regex.c index 821fc5960..f18db483c 100644 --- a/glib/tests/regex.c +++ b/glib/tests/regex.c @@ -53,8 +53,9 @@ /* A random value use to mark untouched integer variables. */ #define UNTOUCHED -559038737 -/* A length of the test string in JIT stack test */ +/* Lengths of test strings in JIT stack tests */ #define TEST_STRING_LEN 20000 +#define LARGE_TEST_STRING_LEN 200000 static gint total; @@ -2747,6 +2748,13 @@ G_GNUC_END_IGNORE_DEPRECATIONS test_string[TEST_STRING_LEN - 1] = '\0'; TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); + /* Test that gregex falls back to unoptimized matching when reaching the JIT + * compiler stack limit */ + char large_test_string[LARGE_TEST_STRING_LEN]; + memset (large_test_string, '*', LARGE_TEST_STRING_LEN); + large_test_string[LARGE_TEST_STRING_LEN - 1] = '\0'; + TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", large_test_string, 0, 0, TRUE); + /* TEST_MATCH(pattern, compile_opts, match_opts, string, * string_len, start_position, match_opts2, expected) */ TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE);