1From 842a105464f6390a433da8791d7b19b65df16f47 Mon Sep 17 00:00:00 2001 2From: Aleksei Rybalkin <aleksei@rybalkin.org> 3Date: Mon, 14 Aug 2023 20:32:48 +0200 4Subject: [PATCH 1/2] gregex: remove redundant call to 5 enable_jit_with_match_options 6 7There is no point to enable jit in g_regex_new, since JIT will be only 8used when we do a first match, and at that point 9enable_jit_with_match_options will be called again already and will 10update the options set in g_regex_new. Instead just run it at first 11match for the first time, to the same end result. 12 13Conflict:NA 14Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/842a105464f6390a433da8791d7b19b65df16f47 15 16--- 17 glib/gregex.c | 1 - 18 1 file changed, 1 deletion(-) 19 20diff --git a/glib/gregex.c b/glib/gregex.c 21index 39b9edeecd..f6b2b716fc 100644 22--- a/glib/gregex.c 23+++ b/glib/gregex.c 24@@ -1764,7 +1764,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS 25 regex->orig_compile_opts = compile_options; 26 regex->match_opts = pcre_match_options; 27 regex->orig_match_opts = match_options; 28- regex->jit_status = enable_jit_with_match_options (regex, regex->match_opts); 29 30 return regex; 31 } 32-- 33GitLab 34 35 36From c3ff5b8eb39f1ab31383604910ae12f325e5afee Mon Sep 17 00:00:00 2001 37From: Aleksei Rybalkin <aleksei@rybalkin.org> 38Date: Mon, 14 Aug 2023 20:41:40 +0200 39Subject: [PATCH 2/2] gregex: set default max stack size for PCRE2 JIT compiler 40 to 512KiB 41 42Previous default used was 32KiB (the library default) which caused some 43complex patterns to fail, see #2824. The memory will not be allocated 44unless used. 45 46Conflict:Move test_string to fix declaration-after-statement 47Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c3ff5b8eb39f1ab31383604910ae12f325e5afee 48 49--- 50 glib/gregex.c | 22 ++++++++++++++-------- 51 glib/tests/regex.c | 9 +++++++++ 52 2 files changed, 23 insertions(+), 8 deletions(-) 53 54diff --git a/glib/gregex.c b/glib/gregex.c 55index f6b2b716fc..5ce034db41 100644 56--- a/glib/gregex.c 57+++ b/glib/gregex.c 58@@ -232,6 +232,7 @@ struct _GMatchInfo 59 gssize string_len; /* length of string, in bytes */ 60 pcre2_match_context *match_context; 61 pcre2_match_data *match_data; 62+ pcre2_jit_stack *jit_stack; 63 }; 64 65 typedef enum 66@@ -896,22 +897,22 @@ recalc_match_offsets (GMatchInfo *match_info, 67 } 68 69 static JITStatus 70-enable_jit_with_match_options (GRegex *regex, 71+enable_jit_with_match_options (GMatchInfo *match_info, 72 uint32_t match_options) 73 { 74 gint retval; 75 uint32_t old_jit_options, new_jit_options; 76 77- if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE)) 78+ if (!(match_info->regex->orig_compile_opts & G_REGEX_OPTIMIZE)) 79 return JIT_STATUS_DISABLED; 80 81- if (regex->jit_status == JIT_STATUS_DISABLED) 82+ if (match_info->regex->jit_status == JIT_STATUS_DISABLED) 83 return JIT_STATUS_DISABLED; 84 85 if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS) 86 return JIT_STATUS_DISABLED; 87 88- old_jit_options = regex->jit_options; 89+ old_jit_options = match_info->regex->jit_options; 90 new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE; 91 if (match_options & PCRE2_PARTIAL_HARD) 92 new_jit_options |= PCRE2_JIT_PARTIAL_HARD; 93@@ -920,13 +921,16 @@ enable_jit_with_match_options (GRegex *regex, 94 95 /* no new options enabled */ 96 if (new_jit_options == old_jit_options) 97- return regex->jit_status; 98+ return match_info->regex->jit_status; 99 100- retval = pcre2_jit_compile (regex->pcre_re, new_jit_options); 101+ retval = pcre2_jit_compile (match_info->regex->pcre_re, new_jit_options); 102 switch (retval) 103 { 104 case 0: /* JIT enabled successfully */ 105- regex->jit_options = new_jit_options; 106+ match_info->regex->jit_options = new_jit_options; 107+ /* Set min stack size for JIT to 32KiB and max to 512KiB */ 108+ match_info->jit_stack = pcre2_jit_stack_create (1 << 15, 1 << 19, NULL); 109+ pcre2_jit_stack_assign (match_info->match_context, NULL, match_info->jit_stack); 110 return JIT_STATUS_ENABLED; 111 case PCRE2_ERROR_NOMEMORY: 112 g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, " 113@@ -1023,6 +1027,8 @@ g_match_info_unref (GMatchInfo *match_info) 114 g_regex_unref (match_info->regex); 115 if (match_info->match_context) 116 pcre2_match_context_free (match_info->match_context); 117+ if (match_info->jit_stack) 118+ pcre2_jit_stack_free (match_info->jit_stack); 119 if (match_info->match_data) 120 pcre2_match_data_free (match_info->match_data); 121 g_free (match_info->offsets); 122@@ -1091,7 +1097,7 @@ g_match_info_next (GMatchInfo *match_info, 123 124 opts = match_info->regex->match_opts | match_info->match_opts; 125 126- jit_status = enable_jit_with_match_options (match_info->regex, opts); 127+ jit_status = enable_jit_with_match_options (match_info, opts); 128 if (jit_status == JIT_STATUS_ENABLED) 129 { 130 match_info->matches = pcre2_jit_match (match_info->regex->pcre_re, 131diff --git a/glib/tests/regex.c b/glib/tests/regex.c 132index cf2bb8199d..821fc59608 100644 133--- a/glib/tests/regex.c 134+++ b/glib/tests/regex.c 135@@ -51,6 +51,9 @@ 136 /* A random value use to mark untouched integer variables. */ 137 #define UNTOUCHED -559038737 138 139+/* A length of the test string in JIT stack test */ 140+#define TEST_STRING_LEN 20000 141+ 142 static gint total; 143 144 typedef struct { 145@@ -2481,6 +2484,7 @@ test_jit_unsupported_matching_options (void) 146 int 147 main (int argc, char *argv[]) 148 { 149+ char test_string[TEST_STRING_LEN]; 150 setlocale (LC_ALL, ""); 151 152 g_test_init (&argc, &argv, NULL); 153@@ -2702,6 +2706,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS 154 TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE); 155 TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE); 156 157+ /* Test that JIT compiler has enough stack */ 158+ memset (test_string, '*', TEST_STRING_LEN); 159+ test_string[TEST_STRING_LEN - 1] = '\0'; 160+ TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); 161+ 162 /* TEST_MATCH(pattern, compile_opts, match_opts, string, 163 * string_len, start_position, match_opts2, expected) */ 164 TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); 165-- 166GitLab