summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2023-08-21 10:39:29 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2023-08-21 10:39:29 +0000
commit8673c3f757d2c64decfd448a405546107b703a20 (patch)
tree6436871f2791bc2defb1111bcee51677db73ab0e
parent0c1e719bdbcffde21258545867418db7717d9f53 (diff)
parent5921ea112d7308b8a5eacf3f58a0666eff420367 (diff)
downloadglib-8673c3f757d2c64decfd448a405546107b703a20.tar.gz
Merge branch 'rybalkin-gregex-jit-stack-overflow-fallback' into 'main'
gregex: if JIT stack limit is reached, fall back to interpretive matching See merge request GNOME/glib!3545
-rw-r--r--glib/gregex.c14
-rw-r--r--glib/tests/regex.c10
2 files changed, 20 insertions, 4 deletions
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);