• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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