!110 backport some patches from community

From: @han_hui_hui 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
This commit is contained in:
openeuler-ci-bot 2022-10-18 08:54:23 +00:00 committed by Gitee
commit 25c84d5f22
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
29 changed files with 3074 additions and 1 deletions

View File

@ -0,0 +1,69 @@
From f43cf341511dd684a58c09e104e28c11987cbff1 Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sat, 25 Jun 2022 18:46:08 +0300
Subject: [PATCH] [PATCH] Add lock in _g_get_unix_mount_points() around
*fsent() functions
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f43cf341511dd684a58c09e104e28c11987cbff1
---
gio/gunixmounts.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index 563bdba3b2..3005aa7af3 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1410,17 +1410,13 @@ _g_get_unix_mount_points (void)
{
struct fstab *fstab = NULL;
GUnixMountPoint *mount_point;
- GList *return_list;
+ GList *return_list = NULL;
+ G_LOCK_DEFINE_STATIC (fsent);
#ifdef HAVE_SYS_SYSCTL_H
int usermnt = 0;
struct stat sb;
#endif
-
- if (!setfsent ())
- return NULL;
- return_list = NULL;
-
#ifdef HAVE_SYS_SYSCTL_H
#if defined(HAVE_SYSCTLBYNAME)
{
@@ -1448,7 +1444,14 @@ _g_get_unix_mount_points (void)
}
#endif
#endif
-
+
+ G_LOCK (fsent);
+ if (!setfsent ())
+ {
+ G_UNLOCK (fsent);
+ return NULL;
+ }
+
while ((fstab = getfsent ()) != NULL)
{
gboolean is_read_only = FALSE;
@@ -1482,9 +1485,10 @@ _g_get_unix_mount_points (void)
return_list = g_list_prepend (return_list, mount_point);
}
-
+
endfsent ();
-
+ G_UNLOCK (fsent);
+
return g_list_reverse (return_list);
}
/* Interix {{{2 */
--
GitLab

View File

@ -0,0 +1,68 @@
From d9ba6150909818beb05573f54f26232063492c5b Mon Sep 17 00:00:00 2001
From: Emmanuel Fleury <emmanuel.fleury@gmail.com>
Date: Mon, 1 Aug 2022 19:05:14 +0200
Subject: [PATCH] Handling collision between standard i/o file descriptors and
newly created ones
Though unlikely to happen, it may happen that newly created file
descriptor take the value 0 (stdin), 1 (stdout) or 2 (stderr) if one
of the standard ones have been dismissed in between. So, it may
confuse the program if it is unaware of this change.
The point of this patch is to avoid a reasign of standard file
descriptors on newly created ones.
Closes issue #16
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d9ba6150909818beb05573f54f26232063492c5b
---
glib/glib-unix.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/glib/glib-unix.c b/glib/glib-unix.c
index d2dea10ef0..d67b8a357a 100644
--- a/glib/glib-unix.c
+++ b/glib/glib-unix.c
@@ -108,6 +108,17 @@ g_unix_open_pipe (int *fds,
ecode = pipe2 (fds, pipe2_flags);
if (ecode == -1 && errno != ENOSYS)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+ }
else if (ecode == 0)
return TRUE;
/* Fall through on -ENOSYS, we must be running on an old kernel */
@@ -116,6 +127,19 @@ g_unix_open_pipe (int *fds,
ecode = pipe (fds);
if (ecode == -1)
return g_unix_set_error_from_errno (error, errno);
+ /* Don't reassign pipes to stdin, stdout, stderr if closed meanwhile */
+ else if (fds[0] < 3 || fds[1] < 3)
+ {
+ int old_fds[2] = { fds[0], fds[1] };
+ gboolean result = g_unix_open_pipe (fds, flags, error);
+ close (old_fds[0]);
+ close (old_fds[1]);
+
+ if (!result)
+ g_unix_set_error_from_errno (error, errno);
+
+ return result;
+ }
if (flags == 0)
return TRUE;
--
GitLab

View File

@ -0,0 +1,52 @@
From a9394bd68e222377f0156bf9c213b3f3a1e340d0 Mon Sep 17 00:00:00 2001
From: Emmanuele Bassi <ebassi@gnome.org>
Date: Sat, 30 Jul 2022 20:03:42 +0100
Subject: [PATCH] Implement GFileIface.set_display_name() for resource files
Resource files cannot be renamed, and GFileIface.set_display_name() is
mandatory.
Fixes: #2705
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a9394bd68e222377f0156bf9c213b3f3a1e340d0
---
gio/gresourcefile.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/gio/gresourcefile.c b/gio/gresourcefile.c
index 340d3378b3..24f20f2903 100644
--- a/gio/gresourcefile.c
+++ b/gio/gresourcefile.c
@@ -646,6 +646,19 @@ g_resource_file_monitor_file (GFile *file,
return g_object_new (g_resource_file_monitor_get_type (), NULL);
}
+static GFile *
+g_resource_file_set_display_name (GFile *file,
+ const char *display_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_set_error_literal (error,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("Resource files cannot be renamed"));
+ return NULL;
+}
+
static void
g_resource_file_file_iface_init (GFileIface *iface)
{
@@ -664,6 +677,7 @@ g_resource_file_file_iface_init (GFileIface *iface)
iface->get_relative_path = g_resource_file_get_relative_path;
iface->resolve_relative_path = g_resource_file_resolve_relative_path;
iface->get_child_for_display_name = g_resource_file_get_child_for_display_name;
+ iface->set_display_name = g_resource_file_set_display_name;
iface->enumerate_children = g_resource_file_enumerate_children;
iface->query_info = g_resource_file_query_info;
iface->query_filesystem_info = g_resource_file_query_filesystem_info;
--
GitLab

View File

@ -0,0 +1,34 @@
From 27203e48c91ab8b55033dcf1773cb60c0aaed3fa Mon Sep 17 00:00:00 2001
From: Sebastian Keller <skeller@gnome.org>
Date: Tue, 30 Aug 2022 21:39:36 +0200
Subject: [PATCH] documentportal: Fix small leak in add_documents with empty
URI list
When called with an empty URI list (or only inaccessible files),
g_document_portal_add_documents would not call g_variant_builder_end,
leaking the memory allocated by the variant builder.
Closes: https://gitlab.gnome.org/GNOME/glib/-/issues/2733
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/27203e48c91ab8b55033dcf1773cb60c0aaed3fa
---
gio/gdocumentportal.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/gdocumentportal.c b/gio/gdocumentportal.c
index c08c36c581..382e2aab6e 100644
--- a/gio/gdocumentportal.c
+++ b/gio/gdocumentportal.c
@@ -203,6 +203,7 @@ g_document_portal_add_documents (GList *uris,
else
{
ruris = g_list_copy_deep (uris, (GCopyFunc)g_strdup, NULL);
+ g_variant_builder_clear (&builder);
}
out:
--
GitLab

View File

@ -0,0 +1,46 @@
From 02d0d6497b92d05d1145d1077654ad2453938b6c Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
Date: Sat, 25 Jun 2022 19:01:30 +0300
Subject: [PATCH] [PATCH] _g_get_unix_mount_points(): reduce syscalls inside
loop
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/02d0d6497b92d05d1145d1077654ad2453938b6c
---
gio/gunixmounts.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index ba08245..92ab163 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -1414,6 +1414,7 @@ _g_get_unix_mount_points (void)
GList *return_list = NULL;
G_LOCK_DEFINE_STATIC (fsent);
#ifdef HAVE_SYS_SYSCTL_H
+ uid_t uid = getuid ();
int usermnt = 0;
struct stat sb;
#endif
@@ -1466,14 +1467,13 @@ _g_get_unix_mount_points (void)
#ifdef HAVE_SYS_SYSCTL_H
if (usermnt != 0)
- {
- uid_t uid = getuid ();
- if (stat (fstab->fs_file, &sb) == 0)
- {
- if (uid == 0 || sb.st_uid == uid)
- is_user_mountable = TRUE;
- }
- }
+ {
+ if (uid == 0 ||
+ (stat (fstab->fs_file, &sb) == 0 && sb.st_uid == uid))
+ {
+ is_user_mountable = TRUE;
+ }
+ }
#endif
mount_point = create_unix_mount_point (fstab->fs_spec,

View File

@ -0,0 +1,48 @@
From 221f22b6e18fdd306e676e28a79afd3697bddd03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 20:38:46 +0200
Subject: [PATCH] gdesktopappinfo: Unref the GDBus call results
On our GDBus call callback wrapper we were completing the gdbus call but
ignoring the returned value, that was always leaked.
Fix this.
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/221f22b6e18fdd306e676e28a79afd3697bddd03
---
gio/gdesktopappinfo.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index af2311ca52..52d308f540 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -3283,15 +3283,19 @@ launch_uris_with_dbus_cb (GObject *object,
{
GTask *task = G_TASK (user_data);
GError *error = NULL;
+ GVariant *ret;
- g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
if (error != NULL)
{
g_dbus_error_strip_remote_error (error);
g_task_return_error (task, g_steal_pointer (&error));
}
else
- g_task_return_boolean (task, TRUE);
+ {
+ g_task_return_boolean (task, TRUE);
+ g_variant_unref (ret);
+ }
g_object_unref (task);
}
--
GitLab

View File

@ -0,0 +1,29 @@
From e268ff39b648e7b100d2aa50f472b4ff8ff5313a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 21:10:05 +0200
Subject: [PATCH] gio/tests/gdbus-peer: Unref cached property GVariant value
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/e268ff39b648e7b100d2aa50f472b4ff8ff5313a
---
gio/tests/gdbus-peer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 7179d089df..763689a4fd 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -843,6 +843,7 @@ do_test_peer (void)
error = NULL;
value = g_dbus_proxy_get_cached_property (proxy, "PeerProperty");
g_assert_cmpstr (g_variant_get_string (value, NULL), ==, "ThePropertyValue");
+ g_clear_pointer (&value, g_variant_unref);
/* try invoking a method */
error = NULL;
--
GitLab

View File

@ -0,0 +1,67 @@
From 1da208cddc19cad05ccf4b798a99f7045e41ffc4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 20:26:06 +0200
Subject: [PATCH] gio/tests/gdbus-proxy-threads: Unref GVariant's that we own
This test is leaking various GVariant's that we are supposed to unref,
leading the valgrind CI job to complain about.
Helps with: https://gitlab.gnome.org/GNOME/glib/-/issues/333
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/1da208cddc19cad05ccf4b798a99f7045e41ffc4
---
gio/tests/gdbus-proxy-threads.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/gio/tests/gdbus-proxy-threads.c b/gio/tests/gdbus-proxy-threads.c
index 76b857e731..a0a38d07cd 100644
--- a/gio/tests/gdbus-proxy-threads.c
+++ b/gio/tests/gdbus-proxy-threads.c
@@ -119,13 +119,17 @@ request_name_cb (GObject *source,
GDBusConnection *connection = G_DBUS_CONNECTION (source);
GError *error = NULL;
GVariant *var;
+ GVariant *child;
var = g_dbus_connection_call_finish (connection, res, &error);
g_assert_no_error (error);
- g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)),
+ child = g_variant_get_child_value (var, 0);
+ g_assert_cmpuint (g_variant_get_uint32 (child),
==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
release_name (connection, TRUE);
+ g_variant_unref (child);
+ g_variant_unref (var);
}
static void
@@ -154,11 +158,13 @@ release_name_cb (GObject *source,
GDBusConnection *connection = G_DBUS_CONNECTION (source);
GError *error = NULL;
GVariant *var;
+ GVariant *child;
int i;
var = g_dbus_connection_call_finish (connection, res, &error);
g_assert_no_error (error);
- g_assert_cmpuint (g_variant_get_uint32 (g_variant_get_child_value (var, 0)),
+ child = g_variant_get_child_value (var, 0);
+ g_assert_cmpuint (g_variant_get_uint32 (child),
==, DBUS_RELEASE_NAME_REPLY_RELEASED);
/* generate some rapid NameOwnerChanged signals to try to trigger crashes */
@@ -170,6 +176,8 @@ release_name_cb (GObject *source,
/* wait for dbus-daemon to catch up */
request_name (connection, TRUE);
+ g_variant_unref (child);
+ g_variant_unref (var);
}
static void
--
GitLab

View File

@ -0,0 +1,33 @@
From 2401e1a090dcaac7614a8984cd3e3832a2a476ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 16 Sep 2022 15:11:47 +0200
Subject: [PATCH] glocalfileoutputstream: Do not double-close an fd on unlink
error
In case we fail unlinking a file we could close again an FD that has
been already just closed. So avoid this by unsetting it when closing.
Coverity CID: #1474462
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/2401e1a090dcaac7614a8984cd3e3832a2a476ab
---
gio/glocalfileoutputstream.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/gio/glocalfileoutputstream.c b/gio/glocalfileoutputstream.c
index 78d3e85..a61d5b5 100644
--- a/gio/glocalfileoutputstream.c
+++ b/gio/glocalfileoutputstream.c
@@ -1163,6 +1163,7 @@ handle_overwrite_open (const char *filename,
if (replace_destination_set)
{
g_close (fd, NULL);
+ fd = -1;
if (g_unlink (filename) != 0)
{
--
2.33.0

View File

@ -0,0 +1,47 @@
From aee84cb45caf42e336dee5183d561b89eb44f8f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 18:56:39 +0200
Subject: [PATCH] gregex: Avoid re-allocating if we have no size change
This is handled by the syscall underneath, but we can just avoid a call
cheaply.
---
glib/gregex.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 84c4245753..cf86f0fe0d 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -832,6 +832,7 @@ recalc_match_offsets (GMatchInfo *match_info,
GError **error)
{
PCRE2_SIZE *ovector;
+ uint32_t pre_n_offset;
uint32_t i;
if (pcre2_get_ovector_count (match_info->match_data) > G_MAXUINT32 / 2)
@@ -842,11 +843,17 @@ recalc_match_offsets (GMatchInfo *match_info,
return FALSE;
}
+ pre_n_offset = match_info->n_offsets;
match_info->n_offsets = pcre2_get_ovector_count (match_info->match_data) * 2;
ovector = pcre2_get_ovector_pointer (match_info->match_data);
- match_info->offsets = g_realloc_n (match_info->offsets,
- match_info->n_offsets,
- sizeof (gint));
+
+ if (match_info->n_offsets != pre_n_offset)
+ {
+ match_info->offsets = g_realloc_n (match_info->offsets,
+ match_info->n_offsets,
+ sizeof (gint));
+ }
+
for (i = 0; i < match_info->n_offsets; i++)
{
match_info->offsets[i] = (int) ovector[i];
--
GitLab

View File

@ -0,0 +1,56 @@
From 1f88976610d5bcc15ad58c9345848d736d64fd55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 17:16:07 +0200
Subject: [PATCH] gregex: Do not try access the undefined match offsets if we
have no match
In case we're getting NO-MATCH "errors", we were still recomputing the
match offsets and taking decisions based on that, that might lead to
undefined behavior.
Avoid this by just returning early a FALSE result (but with no error) in
case there's no result to proceed on.
Fixes: #2741
---
glib/gregex.c | 6 ++++++
glib/tests/regex.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/glib/gregex.c b/glib/gregex.c
index 219d9cee34..f2a5b5fd1c 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -1073,6 +1073,12 @@ g_match_info_next (GMatchInfo *match_info,
match_info->regex->pattern, match_error (match_info->matches));
return FALSE;
}
+ else if (match_info->matches == PCRE2_ERROR_NOMATCH)
+ {
+ /* We're done with this match info */
+ match_info->pos = -1;
+ return FALSE;
+ }
else
if (!recalc_match_offsets (match_info, error))
return FALSE;
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 10daa7814a..291c21b4c7 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -1669,6 +1669,12 @@ test_class (void)
res = g_match_info_next (match, NULL);
g_assert (!res);
+ /* Accessing match again should not crash */
+ g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
+ "*match_info->pos >= 0*");
+ g_assert_false (g_match_info_next (match, NULL));
+ g_test_assert_expected_messages ();
+
g_match_info_free (match);
g_regex_unref (regex);
}
--
GitLab

View File

@ -0,0 +1,50 @@
From 13ad4296ea8ba66f5620288b2fd06315852e73ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 17:20:45 +0200
Subject: [PATCH] gregex: Fix a potential PCRE2 code leak on reallocation
failures
In case recalc_match_offsets() failed we were just returning, but in
such case, per the documentation we should still set the match_info (if
provided) and free the pcre2 code instance.
So let's just break the loop we're in it, as if we we've no matches set.
This also avoids re-allocating the offsets array and potentially
accessing to unset data.
---
glib/gregex.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index f2a5b5fd1c..6f3ee88122 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -2337,13 +2337,6 @@ g_regex_match_all_full (const GRegex *regex,
info->match_data,
info->match_context,
info->workspace, info->n_workspace);
-
- if (!recalc_match_offsets (info, error))
- {
- g_match_info_free (info);
- return FALSE;
- }
-
if (info->matches == PCRE2_ERROR_DFA_WSSIZE)
{
/* info->workspace is too small. */
@@ -2370,6 +2363,11 @@ g_regex_match_all_full (const GRegex *regex,
_("Error while matching regular expression %s: %s"),
regex->pattern, match_error (info->matches));
}
+ else if (info->matches > 0)
+ {
+ if (!recalc_match_offsets (info, error))
+ info->matches = PCRE2_ERROR_NOMATCH;
+ }
}
pcre2_code_free (pcre_re);
--
GitLab

View File

@ -0,0 +1,51 @@
From 11521972f4d345d9a3f68df719f5980085197e47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 18:26:12 +0200
Subject: [PATCH] gregex: Handle the case we need to re-allocate the match data
In case PCRE2 returns an empty match
This can be easily tested by initializing the initial match data to a
value that is less than the expected match values (e.g. by calling
pcre2_match_data_create (1, NULL)), but we can't do it in our tests
without bigger changes.
---
glib/gregex.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index b886b24e2a..84c4245753 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -1027,7 +1027,7 @@ g_match_info_next (GMatchInfo *match_info,
{
gint prev_match_start;
gint prev_match_end;
- gint opts;
+ uint32_t opts;
g_return_val_if_fail (match_info != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -1075,6 +1075,19 @@ g_match_info_next (GMatchInfo *match_info,
match_info->regex->pattern, match_error (match_info->matches));
return FALSE;
}
+ else if (match_info->matches == 0)
+ {
+ /* info->offsets is too small. */
+ match_info->n_offsets *= 2;
+ match_info->offsets = g_realloc_n (match_info->offsets,
+ match_info->n_offsets,
+ sizeof (gint));
+
+ pcre2_match_data_free (match_info->match_data);
+ match_info->match_data = pcre2_match_data_create (match_info->n_offsets, NULL);
+
+ return g_match_info_next (match_info, error);
+ }
else if (match_info->matches == PCRE2_ERROR_NOMATCH)
{
/* We're done with this match info */
--
GitLab

View File

@ -0,0 +1,27 @@
From 1185a1304a88319b58359105f2c1038ae4d7edce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 16:46:13 +0200
Subject: [PATCH] gregex: Mark g_match_info_get_regex as transfer none
Since it had no explicit annotation, g-i was defaulting to transfer-full
while in this case the GRegex is owned by the GMatchInfo.
---
glib/gregex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 2eb9b858ea..219d9cee34 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -912,7 +912,7 @@ enable_jit_with_match_options (GRegex *regex,
* and must not be freed. Use g_regex_ref() if you need to keep it
* after you free @match_info object.
*
- * Returns: #GRegex object used in @match_info
+ * Returns: (transfer none): #GRegex object used in @match_info
*
* Since: 2.14
*/
--
GitLab

View File

@ -0,0 +1,117 @@
From 56d371942e43c52bc6131067e2dc2a35f6cd5a3d Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Mon, 13 Jun 2022 13:06:06 +0100
Subject: [PATCH] gsocketclient: Fix still-reachable references to cancellables
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`GSocketClient` chains its internal `GCancellable` objects to ones
provided by the caller in two places using `g_cancellable_connect()`.
However, it never calls `g_cancellable_disconnect()`, instead relying
(incorrectly) on the `GCancellable` provided by the caller being
short-lived.
In the (valid) situation where a caller reuses one `GCancellable` for
multiple socket client calls, or for calls across multiple socket
clients, this will cause the internal `GCancellable` objects from those
`GSocketClient`s to accumulate, with one reference left each (which is
the reference from the `g_cancellable_connect()` closure).
These `GCancellable` instances aren't technically leaked, as they will
all be freed when the caller's `GCancellable` is disposed, but they are
no longer useful and there is no bound on the number of them which will
hang around.
For a program doing a lot of socket operations, this still-reachable
memory usage can become significant.
Fix the problem by adding paired `g_cancellable_disconnect()` calls.
It's not possible to add a unit test as we can't measure still-reachable
memory growth before the end of a unit test when everything has to be
freed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2670
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/56d371942e43c52bc6131067e2dc2a35f6cd5a3d
---
gio/gsocketclient.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c
index ae80f5203c..127915b722 100644
--- a/gio/gsocketclient.c
+++ b/gio/gsocketclient.c
@@ -1466,6 +1466,8 @@ typedef struct
GSocketConnectable *connectable;
GSocketAddressEnumerator *enumerator;
GCancellable *enumeration_cancellable;
+ GCancellable *enumeration_parent_cancellable; /* (nullable) (owned) */
+ gulong enumeration_cancelled_id;
GSList *connection_attempts;
GSList *successful_connections;
@@ -1485,7 +1487,12 @@ g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data)
data->task = NULL;
g_clear_object (&data->connectable);
g_clear_object (&data->enumerator);
+
+ g_cancellable_disconnect (data->enumeration_parent_cancellable, data->enumeration_cancelled_id);
+ g_clear_object (&data->enumeration_parent_cancellable);
+ data->enumeration_cancelled_id = 0;
g_clear_object (&data->enumeration_cancellable);
+
g_slist_free_full (data->connection_attempts, connection_attempt_unref);
g_slist_free_full (data->successful_connections, connection_attempt_unref);
@@ -1503,6 +1510,7 @@ typedef struct
GSocketClientAsyncConnectData *data; /* unowned */
GSource *timeout_source;
GCancellable *cancellable;
+ gulong cancelled_id;
grefcount ref;
} ConnectionAttempt;
@@ -1530,6 +1538,8 @@ connection_attempt_unref (gpointer pointer)
g_clear_object (&attempt->address);
g_clear_object (&attempt->socket);
g_clear_object (&attempt->connection);
+ g_cancellable_disconnect (g_task_get_cancellable (attempt->data->task), attempt->cancelled_id);
+ attempt->cancelled_id = 0;
g_clear_object (&attempt->cancellable);
g_clear_object (&attempt->proxy_addr);
if (attempt->timeout_source)
@@ -2023,8 +2033,9 @@ g_socket_client_enumerator_callback (GObject *object,
data->connection_attempts = g_slist_append (data->connection_attempts, attempt);
if (g_task_get_cancellable (data->task))
- g_cancellable_connect (g_task_get_cancellable (data->task), G_CALLBACK (on_connection_cancelled),
- g_object_ref (attempt->cancellable), g_object_unref);
+ attempt->cancelled_id =
+ g_cancellable_connect (g_task_get_cancellable (data->task), G_CALLBACK (on_connection_cancelled),
+ g_object_ref (attempt->cancellable), g_object_unref);
g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address);
g_debug ("GSocketClient: Starting TCP connection attempt");
@@ -2129,8 +2140,12 @@ g_socket_client_connect_async (GSocketClient *client,
data->enumeration_cancellable = g_cancellable_new ();
if (cancellable)
- g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
- g_object_ref (data->enumeration_cancellable), g_object_unref);
+ {
+ data->enumeration_parent_cancellable = g_object_ref (cancellable);
+ data->enumeration_cancelled_id =
+ g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled),
+ g_object_ref (data->enumeration_cancellable), g_object_unref);
+ }
enumerator_next_async (data, FALSE);
}
--
GitLab

View File

@ -0,0 +1,25 @@
From d4966911e6b35d8923bc6cd58e7cb8a1b0e09d4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 21:44:12 +0200
Subject: [PATCH] tests/regex: Actually check for match options changes
---
glib/tests/regex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 567b6e2202..abf27e619e 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -105,7 +105,7 @@ test_new (gconstpointer d)
data = g_new0 (TestNewData, 1); \
data->pattern = _pattern; \
data->compile_opts = _compile_opts; \
- data->match_opts = 0; \
+ data->match_opts = _match_opts; \
data->expected_error = 0; \
data->check_flags = TRUE; \
data->real_compile_opts = _real_compile_opts; \
--
GitLab

View File

@ -0,0 +1,193 @@
From 23c1b401d8c78c2c66d55b94d7d833210d518853 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 14:21:27 +0200
Subject: [PATCH] tests/regex: Add debug strings for compile and match option
flags
In case of failures they give a better info.
---
glib/tests/regex.c | 132 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 122 insertions(+), 10 deletions(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index acb082b704..567b6e2202 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -184,6 +184,108 @@ test_match_simple (gconstpointer d)
#define TEST_MATCH_NOTEMPTY_ATSTART(_pattern, _string, _expected) \
TEST_MATCH_SIMPLE_NAMED("notempty-atstart", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY_ATSTART, _expected)
+static char *
+compile_options_to_string (GRegexCompileFlags compile_flags)
+{
+ GStrvBuilder *builder = g_strv_builder_new();
+ GStrv strv;
+ char *ret;
+
+ if (compile_flags & G_REGEX_DEFAULT)
+ g_strv_builder_add (builder, "default");
+ if (compile_flags & G_REGEX_CASELESS)
+ g_strv_builder_add (builder, "caseless");
+ if (compile_flags & G_REGEX_MULTILINE)
+ g_strv_builder_add (builder, "multiline");
+ if (compile_flags & G_REGEX_DOTALL)
+ g_strv_builder_add (builder, "dotall");
+ if (compile_flags & G_REGEX_EXTENDED)
+ g_strv_builder_add (builder, "extended");
+ if (compile_flags & G_REGEX_ANCHORED)
+ g_strv_builder_add (builder, "anchored");
+ if (compile_flags & G_REGEX_DOLLAR_ENDONLY)
+ g_strv_builder_add (builder, "dollar-endonly");
+ if (compile_flags & G_REGEX_UNGREEDY)
+ g_strv_builder_add (builder, "ungreedy");
+ if (compile_flags & G_REGEX_RAW)
+ g_strv_builder_add (builder, "raw");
+ if (compile_flags & G_REGEX_NO_AUTO_CAPTURE)
+ g_strv_builder_add (builder, "no-auto-capture");
+ if (compile_flags & G_REGEX_OPTIMIZE)
+ g_strv_builder_add (builder, "optimize");
+ if (compile_flags & G_REGEX_FIRSTLINE)
+ g_strv_builder_add (builder, "firstline");
+ if (compile_flags & G_REGEX_DUPNAMES)
+ g_strv_builder_add (builder, "dupnames");
+ if (compile_flags & G_REGEX_NEWLINE_CR)
+ g_strv_builder_add (builder, "newline-cr");
+ if (compile_flags & G_REGEX_NEWLINE_LF)
+ g_strv_builder_add (builder, "newline-lf");
+ if (compile_flags & G_REGEX_NEWLINE_CRLF)
+ g_strv_builder_add (builder, "newline-crlf");
+ if (compile_flags & G_REGEX_NEWLINE_ANYCRLF)
+ g_strv_builder_add (builder, "newline-anycrlf");
+ if (compile_flags & G_REGEX_BSR_ANYCRLF)
+ g_strv_builder_add (builder, "bsr-anycrlf");
+
+ strv = g_strv_builder_end (builder);
+ ret = g_strjoinv ("|", strv);
+
+ g_strfreev (strv);
+ g_strv_builder_unref (builder);
+
+ return ret;
+}
+
+static char *
+match_options_to_string (GRegexMatchFlags match_flags)
+{
+ GStrvBuilder *builder = g_strv_builder_new();
+ GStrv strv;
+ char *ret;
+
+ if (match_flags & G_REGEX_MATCH_DEFAULT)
+ g_strv_builder_add (builder, "default");
+ if (match_flags & G_REGEX_MATCH_ANCHORED)
+ g_strv_builder_add (builder, "anchored");
+ if (match_flags & G_REGEX_MATCH_NOTBOL)
+ g_strv_builder_add (builder, "notbol");
+ if (match_flags & G_REGEX_MATCH_NOTEOL)
+ g_strv_builder_add (builder, "noteol");
+ if (match_flags & G_REGEX_MATCH_NOTEMPTY)
+ g_strv_builder_add (builder, "notempty");
+ if (match_flags & G_REGEX_MATCH_PARTIAL)
+ g_strv_builder_add (builder, "partial");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_CR)
+ g_strv_builder_add (builder, "newline-cr");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_LF)
+ g_strv_builder_add (builder, "newline-lf");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_CRLF)
+ g_strv_builder_add (builder, "newline-crlf");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_ANY)
+ g_strv_builder_add (builder, "newline-any");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_ANYCRLF)
+ g_strv_builder_add (builder, "newline-anycrlf");
+ if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF)
+ g_strv_builder_add (builder, "bsr-anycrlf");
+ if (match_flags & G_REGEX_MATCH_BSR_ANY)
+ g_strv_builder_add (builder, "bsr-any");
+ if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT)
+ g_strv_builder_add (builder, "partial-soft");
+ if (match_flags & G_REGEX_MATCH_PARTIAL_HARD)
+ g_strv_builder_add (builder, "partial-hard");
+ if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART)
+ g_strv_builder_add (builder, "notempty-atstart");
+
+ strv = g_strv_builder_end (builder);
+ ret = g_strjoinv ("|", strv);
+
+ g_strfreev (strv);
+ g_strv_builder_unref (builder);
+
+ return ret;
+}
+
static void
test_match (gconstpointer d)
{
@@ -191,6 +293,9 @@ test_match (gconstpointer d)
GRegex *regex;
gboolean match;
GError *error = NULL;
+ gchar *compile_opts_str;
+ gchar *match_opts_str;
+ gchar *match_opts2_str;
regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error);
g_assert (regex != NULL);
@@ -199,31 +304,35 @@ test_match (gconstpointer d)
match = g_regex_match_full (regex, data->string, data->string_len,
data->start_position, data->match_opts2, NULL, NULL);
+ compile_opts_str = compile_options_to_string (data->compile_opts);
+ match_opts_str = match_options_to_string (data->match_opts);
+ match_opts2_str = match_options_to_string (data->match_opts2);
+
if (data->expected)
{
if (!match)
- g_error ("Regex '%s' (with compile options %u and "
- "match options %u) should have matched '%.*s' "
- "(of length %d, at position %d, with match options %u) but did not",
- data->pattern, data->compile_opts, data->match_opts,
+ g_error ("Regex '%s' (with compile options '%s' and "
+ "match options '%s') should have matched '%.*s' "
+ "(of length %d, at position %d, with match options '%s') but did not",
+ data->pattern, compile_opts_str, match_opts_str,
data->string_len == -1 ? (int) strlen (data->string) :
(int) data->string_len,
data->string, (int) data->string_len,
- data->start_position, data->match_opts2);
+ data->start_position, match_opts2_str);
g_assert_cmpint (match, ==, TRUE);
}
else
{
if (match)
- g_error ("Regex '%s' (with compile options %u and "
- "match options %u) should not have matched '%.*s' "
- "(of length %d, at position %d, with match options %u) but did",
- data->pattern, data->compile_opts, data->match_opts,
+ g_error ("Regex '%s' (with compile options '%s' and "
+ "match options '%s') should not have matched '%.*s' "
+ "(of length %d, at position %d, with match options '%s') but did",
+ data->pattern, compile_opts_str, match_opts_str,
data->string_len == -1 ? (int) strlen (data->string) :
(int) data->string_len,
data->string, (int) data->string_len,
- data->start_position, data->match_opts2);
+ data->start_position, match_opts2_str);
}
if (data->string_len == -1 && data->start_position == 0)
@@ -232,6 +341,9 @@ test_match (gconstpointer d)
g_assert_cmpint (match, ==, data->expected);
}
+ g_free (compile_opts_str);
+ g_free (match_opts_str);
+ g_free (match_opts2_str);
g_regex_unref (regex);
}
--
GitLab

View File

@ -0,0 +1,33 @@
From df66951b96fdb800c0b6bd11292bb23fbcd6ed85 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
Date: Thu, 1 Sep 2022 18:19:11 +0200
Subject: [PATCH] tests/regex: Add test for gtksourceview regression
---
glib/tests/regex.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index ce946d0592..10daa7814a 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -2434,6 +2434,16 @@ main (int argc, char *argv[])
TEST_NEW_FAIL ("\\k", 0, G_REGEX_ERROR_MISSING_NAME);
TEST_NEW_FAIL ("a[\\NB]c", 0, G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS);
TEST_NEW_FAIL ("(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEFG)XX", 0, G_REGEX_ERROR_NAME_TOO_LONG);
+ /* See https://gitlab.gnome.org/GNOME/gtksourceview/-/issues/278 */
+ TEST_NEW_FAIL ("(?i-x)((?:(?i-x)[^\\x00\\t\\n\\f\\r \"'/<=>\\x{007F}-\\x{009F}" \
+ "\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}" \
+ "\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}" \
+ "\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}" \
+ "\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}" \
+ "\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}" \
+ "\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)" \
+ "\\s*=\\s*)(\\\")",
+ G_REGEX_RAW, G_REGEX_ERROR_HEX_CODE_TOO_LARGE);
/* These errors can't really be tested easily:
* G_REGEX_ERROR_EXPRESSION_TOO_LARGE
--
GitLab

View File

@ -0,0 +1,38 @@
From fe1c2628d52ca67ffe59420a0b4d371893795e62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 19:19:03 +0200
Subject: [PATCH] regex: Avoid allocating offsets until we've a match
There's no much point of pre-allocating offsets given that we're doing
this when needed if only have matches to store.
So let's just allocate the spaces for the dummy offset we depend on,
while allocate the others on demand.
---
glib/gregex.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 8a3be9076b..7d403ad53d 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -806,15 +806,11 @@ match_info_new (const GRegex *regex,
{
/* These values should be enough for most cases, if they are not
* enough g_regex_match_all_full() will expand them. */
- match_info->n_offsets = 24;
match_info->n_workspace = 100;
match_info->workspace = g_new (gint, match_info->n_workspace);
}
- else
- {
- match_info->n_offsets = (match_info->n_subpatterns + 1) * 3;
- }
+ match_info->n_offsets = 2;
match_info->offsets = g_new0 (gint, match_info->n_offsets);
/* Set an invalid position for the previous match. */
match_info->offsets[0] = -1;
--
GitLab

View File

@ -0,0 +1,59 @@
From e8628a7ed59e54b5a5e498de0375f101a4e76e64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 19:05:24 +0200
Subject: [PATCH] regex: Compute the offsets size based on match results
While the ovector count would include all the allocated space, we only
care about the actual match values, so avoid wasting allocations and
just use the ones we need to hold the offsets.
---
glib/gregex.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index cf86f0fe0d..8a3be9076b 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -832,10 +832,20 @@ recalc_match_offsets (GMatchInfo *match_info,
GError **error)
{
PCRE2_SIZE *ovector;
+ uint32_t ovector_size = 0;
uint32_t pre_n_offset;
uint32_t i;
- if (pcre2_get_ovector_count (match_info->match_data) > G_MAXUINT32 / 2)
+ g_assert (!IS_PCRE2_ERROR (match_info->matches));
+
+ if (match_info->matches == PCRE2_ERROR_PARTIAL)
+ ovector_size = 1;
+ else if (match_info->matches > 0)
+ ovector_size = match_info->matches;
+
+ g_assert (ovector_size != 0);
+
+ if (pcre2_get_ovector_count (match_info->match_data) < ovector_size)
{
g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
_("Error while matching regular expression %s: %s"),
@@ -844,7 +854,7 @@ recalc_match_offsets (GMatchInfo *match_info,
}
pre_n_offset = match_info->n_offsets;
- match_info->n_offsets = pcre2_get_ovector_count (match_info->match_data) * 2;
+ match_info->n_offsets = ovector_size * 2;
ovector = pcre2_get_ovector_pointer (match_info->match_data);
if (match_info->n_offsets != pre_n_offset)
@@ -2387,7 +2397,7 @@ g_regex_match_all_full (const GRegex *regex,
_("Error while matching regular expression %s: %s"),
regex->pattern, match_error (info->matches));
}
- else if (info->matches > 0)
+ else if (info->matches != PCRE2_ERROR_NOMATCH)
{
if (!recalc_match_offsets (info, error))
info->matches = PCRE2_ERROR_NOMATCH;
--
GitLab

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,241 @@
From bec68b2d74853de5e23ee40c890433fa336ffbc5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 9 Sep 2022 18:30:15 +0200
Subject: [PATCH] glib/regex: Do not use JIT when using unsupported match
options
Do not store jit status for regex unless during initial compilation.
After that, decide whether to use it depending on matching options.
In fact there are some matching options that are incompatible with JIT,
as the PCRE2 docs states:
Setting PCRE2_ANCHORED or PCRE2_ENDANCHORED at match time is not
supported by the just-in-time (JIT) compiler. If it is set, JIT
matching is disabled and the interpretive code in pcre2_match() is
run. Apart from PCRE2_NO_JIT (obviously), the remaining options are
supported for JIT matching.
Fixes: GNOME/gtksourceview#283
---
glib/gregex.c | 38 ++++++++++++++++---------
glib/tests/regex.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 13 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index fe7473e628..220a1a11ac 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -201,6 +201,13 @@
PCRE2_NEWLINE_CRLF | \
PCRE2_NEWLINE_ANYCRLF)
+/* Some match options are not supported when using JIT as stated in the
+ * pcre2jit man page under the 芦UNSUPPORTED OPTIONS AND PATTERN ITEMS禄 section:
+ * https://www.pcre.org/current/doc/html/pcre2jit.html#SEC5
+ */
+#define G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS (PCRE2_ANCHORED | \
+ PCRE2_ENDANCHORED)
+
#define G_REGEX_COMPILE_NEWLINE_MASK (G_REGEX_NEWLINE_CR | \
G_REGEX_NEWLINE_LF | \
G_REGEX_NEWLINE_CRLF | \
@@ -869,7 +876,7 @@ recalc_match_offsets (GMatchInfo *match_info,
return TRUE;
}
-static void
+static JITStatus
enable_jit_with_match_options (GRegex *regex,
uint32_t match_options)
{
@@ -877,9 +884,13 @@ enable_jit_with_match_options (GRegex *regex,
uint32_t old_jit_options, new_jit_options;
if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE))
- return;
+ return JIT_STATUS_DISABLED;
+
if (regex->jit_status == JIT_STATUS_DISABLED)
- return;
+ return JIT_STATUS_DISABLED;
+
+ if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS)
+ return JIT_STATUS_DISABLED;
old_jit_options = regex->jit_options;
new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE;
@@ -890,34 +901,34 @@ enable_jit_with_match_options (GRegex *regex,
/* no new options enabled */
if (new_jit_options == old_jit_options)
- return;
+ return regex->jit_status;
retval = pcre2_jit_compile (regex->pcre_re, new_jit_options);
switch (retval)
{
case 0: /* JIT enabled successfully */
- regex->jit_status = JIT_STATUS_ENABLED;
regex->jit_options = new_jit_options;
- break;
+ return JIT_STATUS_ENABLED;
case PCRE2_ERROR_NOMEMORY:
g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
"but JIT was unable to allocate executable memory for the "
"compiler. Falling back to interpretive code.");
- regex->jit_status = JIT_STATUS_DISABLED;
- break;
+ return JIT_STATUS_DISABLED;
case PCRE2_ERROR_JIT_BADOPTION:
g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
"but JIT support is not available. Falling back to "
"interpretive code.");
- regex->jit_status = JIT_STATUS_DISABLED;
+ return JIT_STATUS_DISABLED;
break;
default:
g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
"but request for JIT support had unexpectedly failed (error %d). "
"Falling back to interpretive code.", retval);
- regex->jit_status = JIT_STATUS_DISABLED;
+ return JIT_STATUS_DISABLED;
break;
}
+
+ return regex->jit_status;
}
/**
@@ -1039,6 +1050,7 @@ gboolean
g_match_info_next (GMatchInfo *match_info,
GError **error)
{
+ JITStatus jit_status;
gint prev_match_start;
gint prev_match_end;
uint32_t opts;
@@ -1060,8 +1072,8 @@ g_match_info_next (GMatchInfo *match_info,
opts = match_info->regex->match_opts | match_info->match_opts;
- enable_jit_with_match_options (match_info->regex, opts);
- if (match_info->regex->jit_status == JIT_STATUS_ENABLED)
+ jit_status = enable_jit_with_match_options (match_info->regex, opts);
+ if (jit_status == JIT_STATUS_ENABLED)
{
match_info->matches = pcre2_jit_match (match_info->regex->pcre_re,
(PCRE2_SPTR8) match_info->string,
@@ -1727,7 +1739,7 @@ g_regex_new (const gchar *pattern,
regex->orig_compile_opts = compile_options;
regex->match_opts = pcre_match_options;
regex->orig_match_opts = match_options;
- enable_jit_with_match_options (regex, regex->match_opts);
+ regex->jit_status = enable_jit_with_match_options (regex, regex->match_opts);
return regex;
}
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 26844d63a7..2052ba0204 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -2334,6 +2334,67 @@ test_compile_errors (void)
g_clear_error (&error);
}
+static void
+test_jit_unsupported_matching_options (void)
+{
+ GRegex *regex;
+ GMatchInfo *info;
+ gchar *substring;
+
+ regex = g_regex_new ("(\\w+)#(\\w+)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, NULL);
+
+ g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_DEFAULT, &info));
+ g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
+ substring = g_match_info_fetch (info, 1);
+ g_assert_cmpstr (substring, ==, "aa");
+ g_clear_pointer (&substring, g_free);
+ substring = g_match_info_fetch (info, 2);
+ g_assert_cmpstr (substring, ==, "bb");
+ g_clear_pointer (&substring, g_free);
+ g_assert_true (g_match_info_next (info, NULL));
+ g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
+ substring = g_match_info_fetch (info, 1);
+ g_assert_cmpstr (substring, ==, "cc");
+ g_clear_pointer (&substring, g_free);
+ substring = g_match_info_fetch (info, 2);
+ g_assert_cmpstr (substring, ==, "dd");
+ g_clear_pointer (&substring, g_free);
+ g_assert_false (g_match_info_next (info, NULL));
+ g_match_info_free (info);
+
+ g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_ANCHORED, &info));
+ g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
+ substring = g_match_info_fetch (info, 1);
+ g_assert_cmpstr (substring, ==, "aa");
+ g_clear_pointer (&substring, g_free);
+ substring = g_match_info_fetch (info, 2);
+ g_assert_cmpstr (substring, ==, "bb");
+ g_clear_pointer (&substring, g_free);
+ g_assert_false (g_match_info_next (info, NULL));
+ g_match_info_free (info);
+
+ g_assert_true (g_regex_match (regex, "aa#bb cc#dd", G_REGEX_MATCH_DEFAULT, &info));
+ g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
+ substring = g_match_info_fetch (info, 1);
+ g_assert_cmpstr (substring, ==, "aa");
+ g_clear_pointer (&substring, g_free);
+ substring = g_match_info_fetch (info, 2);
+ g_assert_cmpstr (substring, ==, "bb");
+ g_clear_pointer (&substring, g_free);
+ g_assert_true (g_match_info_next (info, NULL));
+ g_assert_cmpint (g_match_info_get_match_count (info), ==, 3);
+ substring = g_match_info_fetch (info, 1);
+ g_assert_cmpstr (substring, ==, "cc");
+ g_clear_pointer (&substring, g_free);
+ substring = g_match_info_fetch (info, 2);
+ g_assert_cmpstr (substring, ==, "dd");
+ g_clear_pointer (&substring, g_free);
+ g_assert_false (g_match_info_next (info, NULL));
+ g_match_info_free (info);
+
+ g_regex_unref (regex);
+}
+
int
main (int argc, char *argv[])
{
@@ -2352,6 +2413,7 @@ main (int argc, char *argv[])
g_test_add_func ("/regex/explicit-crlf", test_explicit_crlf);
g_test_add_func ("/regex/max-lookbehind", test_max_lookbehind);
g_test_add_func ("/regex/compile-errors", test_compile_errors);
+ g_test_add_func ("/regex/jit-unsupported-matching", test_jit_unsupported_matching_options);
/* TEST_NEW(pattern, compile_opts, match_opts) */
TEST_NEW("[A-Z]+", G_REGEX_CASELESS | G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTBOL | G_REGEX_MATCH_PARTIAL);
@@ -2488,6 +2550,7 @@ main (int argc, char *argv[])
TEST_MATCH_SIMPLE("a", "ab", 0, G_REGEX_MATCH_ANCHORED, TRUE);
TEST_MATCH_SIMPLE("a", "a", G_REGEX_CASELESS, 0, TRUE);
TEST_MATCH_SIMPLE("a", "A", G_REGEX_CASELESS, 0, TRUE);
+ TEST_MATCH_SIMPLE("\\C\\C", "ab", G_REGEX_OPTIMIZE | G_REGEX_RAW, 0, TRUE);
/* These are needed to test extended properties. */
TEST_MATCH_SIMPLE(AGRAVE, AGRAVE, G_REGEX_CASELESS, 0, TRUE);
TEST_MATCH_SIMPLE(AGRAVE, AGRAVE_UPPER, G_REGEX_CASELESS, 0, TRUE);
@@ -2947,6 +3010,12 @@ main (int argc, char *argv[])
TEST_REPLACE("\\S+", "hello world", 0, "\\U-\\0-", "-HELLO- -WORLD-");
TEST_REPLACE(".", "a", 0, "\\A", NULL);
TEST_REPLACE(".", "a", 0, "\\g", NULL);
+ TEST_REPLACE_OPTIONS("(\\w+)#(\\w+)", "aa#bb cc#dd", 0, "\\2#\\1", "bb#aa dd#cc",
+ G_REGEX_OPTIMIZE|G_REGEX_MULTILINE|G_REGEX_CASELESS,
+ 0);
+ TEST_REPLACE_OPTIONS("(\\w+)#(\\w+)", "aa#bb cc#dd", 0, "\\2#\\1", "bb#aa cc#dd",
+ G_REGEX_OPTIMIZE|G_REGEX_MULTILINE|G_REGEX_CASELESS,
+ G_REGEX_MATCH_ANCHORED);
/* TEST_REPLACE_LIT(pattern, string, start_position, replacement, expected) */
TEST_REPLACE_LIT("a", "ababa", 0, "A", "AbAbA");
--
GitLab

View File

@ -0,0 +1,35 @@
From 5e76cde5ffeac79b939cf84202024859cda5e753 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 7 Sep 2022 14:18:14 +0200
Subject: [PATCH] regex: Handle JIT errors more explicitly
---
glib/gregex.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 7d403ad53d..fe7473e628 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -471,6 +471,7 @@ 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 */
@@ -912,8 +913,8 @@ enable_jit_with_match_options (GRegex *regex,
break;
default:
g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, "
- "but request for JIT support had unexpectedly failed. "
- "Falling back to interpretive code.");
+ "but request for JIT support had unexpectedly failed (error %d). "
+ "Falling back to interpretive code.", retval);
regex->jit_status = JIT_STATUS_DISABLED;
break;
}
--
GitLab

View File

@ -0,0 +1,71 @@
From 0831393dd08d5f9dcf2e0517dbb4ea546ff7156b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Wed, 7 Sep 2022 15:21:52 +0200
Subject: [PATCH] tests/regex: Make possible to test replacements with options
---
glib/tests/regex.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 291c21b4c7..26844d63a7 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -1207,6 +1207,8 @@ typedef struct {
gint start_position;
const gchar *replacement;
const gchar *expected;
+ GRegexCompileFlags compile_flags;
+ GRegexMatchFlags match_flags;
} TestReplaceData;
static void
@@ -1215,17 +1217,25 @@ test_replace (gconstpointer d)
const TestReplaceData *data = d;
GRegex *regex;
gchar *res;
+ GError *error = NULL;
- regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
- res = g_regex_replace (regex, data->string, -1, data->start_position, data->replacement, 0, NULL);
+ regex = g_regex_new (data->pattern, data->compile_flags, G_REGEX_MATCH_DEFAULT, &error);
+ g_assert_no_error (error);
+
+ res = g_regex_replace (regex, data->string, -1, data->start_position,
+ data->replacement, data->match_flags, &error);
g_assert_cmpstr (res, ==, data->expected);
+ if (data->expected)
+ g_assert_no_error (error);
+
g_free (res);
g_regex_unref (regex);
+ g_clear_error (&error);
}
-#define TEST_REPLACE(_pattern, _string, _start_position, _replacement, _expected) { \
+#define TEST_REPLACE_OPTIONS(_pattern, _string, _start_position, _replacement, _expected, _compile_flags, _match_flags) { \
TestReplaceData *data; \
gchar *path; \
data = g_new0 (TestReplaceData, 1); \
@@ -1234,11 +1244,16 @@ test_replace (gconstpointer d)
data->start_position = _start_position; \
data->replacement = _replacement; \
data->expected = _expected; \
+ data->compile_flags = _compile_flags; \
+ data->match_flags = _match_flags; \
path = g_strdup_printf ("/regex/replace/%d", ++total); \
g_test_add_data_func_full (path, data, test_replace, g_free); \
g_free (path); \
}
+#define TEST_REPLACE(_pattern, _string, _start_position, _replacement, _expected) \
+ TEST_REPLACE_OPTIONS (_pattern, _string, _start_position, _replacement, _expected, 0, 0)
+
static void
test_replace_lit (gconstpointer d)
{
--
GitLab

View File

@ -0,0 +1,188 @@
From 653f8eb0203485c7ffb0eeae81e6e30437d18529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 9 Sep 2022 18:43:47 +0200
Subject: [PATCH] tests/regex: Perform more tests both with and without
optimizations
---
glib/tests/regex.c | 101 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 93 insertions(+), 8 deletions(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 2052ba0204..9803d49659 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -173,7 +173,24 @@ test_match_simple (gconstpointer d)
data->compile_opts = _compile_opts; \
data->match_opts = _match_opts; \
data->expected = _expected; \
- path = g_strdup_printf ("/regex/match-%s/%d", _name, ++total); \
+ total++; \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ path = g_strdup_printf ("/regex/match-%s-optimized/%d", _name, total); \
+ else \
+ path = g_strdup_printf ("/regex/match-%s/%d", _name, total); \
+ g_test_add_data_func_full (path, data, test_match_simple, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestMatchData)); \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ { \
+ data->compile_opts &= ~G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match-%s/%d", _name, total); \
+ } \
+ else \
+ { \
+ data->compile_opts |= G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match-%s-optimized/%d", _name, total); \
+ } \
g_test_add_data_func_full (path, data, test_match_simple, g_free); \
g_free (path); \
}
@@ -361,7 +378,24 @@ test_match (gconstpointer d)
data->start_position = _start_position; \
data->match_opts2 = _match_opts2; \
data->expected = _expected; \
- path = g_strdup_printf ("/regex/match/%d", ++total); \
+ total++; \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ path = g_strdup_printf ("/regex/match-optimized/%d", total); \
+ else \
+ path = g_strdup_printf ("/regex/match/%d", total); \
+ g_test_add_data_func_full (path, data, test_match, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestMatchData)); \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ { \
+ data->compile_opts &= ~G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match/%d", total); \
+ } \
+ else \
+ { \
+ data->compile_opts |= G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match-optimized/%d", total); \
+ } \
g_test_add_data_func_full (path, data, test_match, g_free); \
g_free (path); \
}
@@ -580,6 +614,7 @@ typedef struct {
const gchar *pattern;
const gchar *string;
gint start_position;
+ GRegexCompileFlags compile_flags;
GRegexMatchFlags match_opts;
gint expected_count;
} TestMatchCountData;
@@ -592,7 +627,8 @@ test_match_count (gconstpointer d)
GMatchInfo *match_info;
gint count;
- regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
+ regex = g_regex_new (data->pattern, data->compile_flags,
+ G_REGEX_MATCH_DEFAULT, NULL);
g_assert (regex != NULL);
@@ -617,7 +653,14 @@ test_match_count (gconstpointer d)
data->start_position = _start_position; \
data->match_opts = _match_opts; \
data->expected_count = _expected_count; \
- path = g_strdup_printf ("/regex/match/count/%d", ++total); \
+ data->compile_flags = G_REGEX_DEFAULT; \
+ total++; \
+ path = g_strdup_printf ("/regex/match/count/%d", total); \
+ g_test_add_data_func_full (path, data, test_match_count, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestMatchCountData)); \
+ data->compile_flags |= G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match/count-optimized/%d", total); \
g_test_add_data_func_full (path, data, test_match_count, g_free); \
g_free (path); \
}
@@ -656,7 +699,24 @@ test_partial (gconstpointer d)
data->compile_opts = _compile_opts; \
data->match_opts = _match_opts; \
data->expected = _expected; \
- path = g_strdup_printf ("/regex/match/partial/%d", ++total); \
+ total++; \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ path = g_strdup_printf ("/regex/match/partial-optimized/%d", total); \
+ else \
+ path = g_strdup_printf ("/regex/match/partial%d", total); \
+ g_test_add_data_func_full (path, data, test_partial, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestMatchData)); \
+ if (data->compile_opts & G_REGEX_OPTIMIZE) \
+ { \
+ data->compile_opts &= ~G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match/partial%d", total); \
+ } \
+ else \
+ { \
+ data->compile_opts |= G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match/partial-optimized/%d", total); \
+ } \
g_test_add_data_func_full (path, data, test_partial, g_free); \
g_free (path); \
}
@@ -666,6 +726,7 @@ test_partial (gconstpointer d)
typedef struct {
const gchar *pattern;
const gchar *string;
+ GRegexCompileFlags compile_flags;
gint start_position;
gint sub_n;
const gchar *expected_sub;
@@ -682,7 +743,7 @@ test_sub_pattern (gconstpointer d)
gchar *sub_expr;
gint start = UNTOUCHED, end = UNTOUCHED;
- regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL);
+ regex = g_regex_new (data->pattern, data->compile_flags, G_REGEX_MATCH_DEFAULT, NULL);
g_assert (regex != NULL);
@@ -712,7 +773,14 @@ test_sub_pattern (gconstpointer d)
data->expected_sub = _expected_sub; \
data->expected_start = _expected_start; \
data->expected_end = _expected_end; \
- path = g_strdup_printf ("/regex/match/subpattern/%d", ++total); \
+ data->compile_flags = G_REGEX_DEFAULT; \
+ total++; \
+ path = g_strdup_printf ("/regex/match/subpattern/%d", total); \
+ g_test_add_data_func_full (path, data, test_sub_pattern, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestSubData)); \
+ data->compile_flags = G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/match/subpattern-optimized/%d", total); \
g_test_add_data_func_full (path, data, test_sub_pattern, g_free); \
g_free (path); \
}
@@ -1246,7 +1314,24 @@ test_replace (gconstpointer d)
data->expected = _expected; \
data->compile_flags = _compile_flags; \
data->match_flags = _match_flags; \
- path = g_strdup_printf ("/regex/replace/%d", ++total); \
+ total++; \
+ if (data->compile_flags & G_REGEX_OPTIMIZE) \
+ path = g_strdup_printf ("/regex/replace-optimized/%d", total); \
+ else \
+ path = g_strdup_printf ("/regex/replace/%d", total); \
+ g_test_add_data_func_full (path, data, test_replace, g_free); \
+ g_free (path); \
+ data = g_memdup2 (data, sizeof (TestReplaceData)); \
+ if (data->compile_flags & G_REGEX_OPTIMIZE) \
+ { \
+ data->compile_flags &= ~G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/replace/%d", total); \
+ } \
+ else \
+ { \
+ data->compile_flags |= G_REGEX_OPTIMIZE; \
+ path = g_strdup_printf ("/regex/replace-optimized/%d", total); \
+ } \
g_test_add_data_func_full (path, data, test_replace, g_free); \
g_free (path); \
}
--
GitLab

View File

@ -0,0 +1,148 @@
From 1d628dac92283d75f7c751ddad72c28f4a7afe39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 18:21:52 +0200
Subject: [PATCH] regex: Use size types more in line with PCRE2 returned values
We're using int for every size value while PCRE uses uint_32t or
PCRE2_SIZE (size_t in most platforms), let's use the same types to avoid
using different signs.
---
glib/gregex.c | 34 +++++++++++++++++++---------------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 6f3ee88122..b886b24e2a 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -23,6 +23,7 @@
#include "config.h"
+#include <stdint.h>
#include <string.h>
#define PCRE2_CODE_UNIT_WIDTH 8
@@ -226,12 +227,12 @@ struct _GMatchInfo
GRegex *regex; /* the regex */
uint32_t match_opts; /* pcre match options used at match time on the regex */
gint matches; /* number of matching sub patterns, guaranteed to be <= (n_subpatterns + 1) if doing a single match (rather than matching all) */
- gint n_subpatterns; /* total number of sub patterns in the regex */
+ uint32_t n_subpatterns; /* total number of sub patterns in the regex */
gint pos; /* position in the string where last match left off */
- gint n_offsets; /* number of offsets */
+ uint32_t n_offsets; /* number of offsets */
gint *offsets; /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
gint *workspace; /* workspace for pcre2_dfa_match() */
- gint n_workspace; /* number of workspace elements */
+ PCRE2_SIZE n_workspace; /* number of workspace elements */
const gchar *string; /* string passed to the match function */
gssize string_len; /* length of string, in bytes */
pcre2_match_context *match_context;
@@ -254,7 +255,7 @@ struct _GRegex
GRegexCompileFlags orig_compile_opts; /* options used at compile time on the pattern, gregex values */
uint32_t match_opts; /* pcre2 options used at match time on the regex */
GRegexMatchFlags orig_match_opts; /* options used as default match options, gregex values */
- gint jit_options; /* options which were enabled for jit compiler */
+ uint32_t jit_options; /* options which were enabled for jit compiler */
JITStatus jit_status; /* indicates the status of jit compiler for this compiled regex */
};
@@ -831,9 +832,9 @@ recalc_match_offsets (GMatchInfo *match_info,
GError **error)
{
PCRE2_SIZE *ovector;
- gint i;
+ uint32_t i;
- if (pcre2_get_ovector_count (match_info->match_data) > G_MAXINT / 2)
+ if (pcre2_get_ovector_count (match_info->match_data) > G_MAXUINT32 / 2)
{
g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
_("Error while matching regular expression %s: %s"),
@@ -858,7 +859,8 @@ static void
enable_jit_with_match_options (GRegex *regex,
uint32_t match_options)
{
- gint old_jit_options, new_jit_options, retval;
+ gint retval;
+ uint32_t old_jit_options, new_jit_options;
if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE))
return;
@@ -1104,7 +1106,8 @@ g_match_info_next (GMatchInfo *match_info,
match_info->pos = match_info->offsets[1];
}
- g_assert (match_info->matches <= match_info->n_subpatterns + 1);
+ g_assert (match_info->matches < 0 ||
+ (uint32_t) match_info->matches <= match_info->n_subpatterns + 1);
/* it's possible to get two identical matches when we are matching
* empty strings, for instance if the pattern is "(?=[A-Z0-9])" and
@@ -1387,7 +1390,7 @@ g_match_info_fetch_pos (const GMatchInfo *match_info,
/* make sure the sub expression number they're requesting is less than
* the total number of sub expressions in the regex. When matching all
* (g_regex_match_all()), also compare against the number of matches */
- if (match_num >= MAX (match_info->n_subpatterns + 1, match_info->matches))
+ if ((uint32_t) match_num >= MAX (match_info->n_subpatterns + 1, (uint32_t) match_info->matches))
return FALSE;
if (start_pos != NULL)
@@ -1797,7 +1800,7 @@ get_pcre2_inline_compile_options (pcre2_code *re,
if (!(compile_options & PCRE2_DUPNAMES))
{
- gboolean jchanged = FALSE;
+ uint32_t jchanged = 0;
pcre2_pattern_info (re, PCRE2_INFO_JCHANGED, &jchanged);
if (jchanged)
compile_options |= PCRE2_DUPNAMES;
@@ -1840,7 +1843,7 @@ g_regex_get_pattern (const GRegex *regex)
gint
g_regex_get_max_backref (const GRegex *regex)
{
- gint value;
+ uint32_t value;
pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BACKREFMAX, &value);
@@ -1860,7 +1863,7 @@ g_regex_get_max_backref (const GRegex *regex)
gint
g_regex_get_capture_count (const GRegex *regex)
{
- gint value;
+ uint32_t value;
pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, &value);
@@ -1880,7 +1883,7 @@ g_regex_get_capture_count (const GRegex *regex)
gboolean
g_regex_get_has_cr_or_lf (const GRegex *regex)
{
- gint value;
+ uint32_t value;
pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_HASCRORLF, &value);
@@ -1902,7 +1905,7 @@ g_regex_get_has_cr_or_lf (const GRegex *regex)
gint
g_regex_get_max_lookbehind (const GRegex *regex)
{
- gint max_lookbehind;
+ uint32_t max_lookbehind;
pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_MAXLOOKBEHIND,
&max_lookbehind);
@@ -1927,7 +1930,8 @@ g_regex_get_max_lookbehind (const GRegex *regex)
GRegexCompileFlags
g_regex_get_compile_flags (const GRegex *regex)
{
- gint extra_flags, info_value;
+ GRegexCompileFlags extra_flags;
+ uint32_t info_value;
g_return_val_if_fail (regex != NULL, 0);
--
GitLab

View File

@ -0,0 +1,119 @@
From 511627b7356af527c85c049e2020a36694d7de54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Fri, 2 Sep 2022 18:56:35 +0200
Subject: [PATCH] tests/dbus-appinfo: Add test case for flatpak opening an
invalid file
We were testing the case in which we were opening an actual file, and so
potentially using a fd-list, however we were missing the case in which a file
was not existent.
And in such case we are incidentally hitting a leak now.
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/511627b7356af527c85c049e2020a36694d7de54
---
gio/tests/dbus-appinfo.c | 79 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/gio/tests/dbus-appinfo.c b/gio/tests/dbus-appinfo.c
index 2017e02df2..91e76403c6 100644
--- a/gio/tests/dbus-appinfo.c
+++ b/gio/tests/dbus-appinfo.c
@@ -360,6 +360,84 @@ test_flatpak_doc_export (void)
g_object_unref (flatpak_appinfo);
}
+static void
+on_flatpak_launch_invalid_uri_finish (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GApplication *app = user_data;
+ GError *error = NULL;
+
+ g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error);
+ g_assert_no_error (error);
+
+ g_application_release (app);
+}
+
+static void
+on_flatpak_activate_invalid_uri (GApplication *app,
+ gpointer user_data)
+{
+ GDesktopAppInfo *flatpak_appinfo = user_data;
+ GList *uris;
+
+ /* The app will be released in on_flatpak_launch_uris_finish */
+ g_application_hold (app);
+
+ uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop");
+ g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL,
+ NULL, on_flatpak_launch_invalid_uri_finish, app);
+ g_list_free (uris);
+}
+
+static void
+on_flatpak_open_invalid_uri (GApplication *app,
+ GFile **files,
+ gint n_files,
+ const char *hint)
+{
+ GFile *f;
+
+ g_assert_cmpint (n_files, ==, 1);
+ g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
+
+ /* The file has been exported via the document portal */
+ f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop");
+ g_assert_true (g_file_equal (files[0], f));
+ g_object_unref (f);
+}
+
+static void
+test_flatpak_missing_doc_export (void)
+{
+ const gchar *argv[] = { "myapp", NULL };
+ gchar *desktop_file = NULL;
+ GDesktopAppInfo *flatpak_appinfo;
+ GApplication *app;
+ int status;
+
+ g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
+
+ desktop_file = g_test_build_filename (G_TEST_DIST,
+ "org.gtk.test.dbusappinfo.flatpak.desktop",
+ NULL);
+ flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
+ g_assert_nonnull (flatpak_appinfo);
+
+ app = g_application_new ("org.gtk.test.dbusappinfo.flatpak",
+ G_APPLICATION_HANDLES_OPEN);
+ g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri),
+ flatpak_appinfo);
+ g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL);
+
+ status = g_application_run (app, 1, (gchar **) argv);
+ g_assert_cmpint (status, ==, 0);
+
+ g_object_unref (app);
+ g_object_unref (flatpak_appinfo);
+ g_free (desktop_file);
+}
+
int
main (int argc, char **argv)
{
@@ -367,6 +445,7 @@ main (int argc, char **argv)
g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export);
+ g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export);
return session_bus_run ();
}
--
GitLab

View File

@ -0,0 +1,36 @@
From f95ca6cb713383548f16f9a8ba2f6c51a4d25e25 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@redhat.com>
Date: Fri, 17 Jun 2022 08:48:10 -0500
Subject: [PATCH] xdgmime: fix double free
We free xdg_dirs[i] twice, but fail to free xdg_dirs itself.
Also, since free() is NULL-safe, there is no need for the second check
here.
Discovered in: https://gitlab.freedesktop.org/xdg/xdgmime/-/merge_requests/16#note_1432025
Conflict:NA
Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f95ca6cb713383548f16f9a8ba2f6c51a4d25e25
---
gio/xdgmime/xdgmime.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
index 9ab6760486..c3c11625e8 100644
--- a/gio/xdgmime/xdgmime.c
+++ b/gio/xdgmime/xdgmime.c
@@ -350,8 +350,7 @@ xdg_mime_set_dirs (const char * const *dirs)
for (i = 0; xdg_dirs != NULL && xdg_dirs[i] != NULL; i++)
free (xdg_dirs[i]);
- if (xdg_dirs != NULL)
- free (xdg_dirs[i]);
+ free (xdg_dirs);
xdg_dirs = NULL;
if (dirs != NULL)
--
GitLab

View File

@ -1,6 +1,6 @@
Name: glib2 Name: glib2
Version: 2.72.2 Version: 2.72.2
Release: 3 Release: 4
Summary: The core library that forms the basis for projects such as GTK+ and GNOME Summary: The core library that forms the basis for projects such as GTK+ and GNOME
License: LGPLv2+ License: LGPLv2+
URL: http://www.gtk.org URL: http://www.gtk.org
@ -24,6 +24,34 @@ Patch6014: backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-
Patch6015: backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch Patch6015: backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch
Patch6016: backport-gregex-add-original-test-case.patch Patch6016: backport-gregex-add-original-test-case.patch
Patch6017: backport-gregex-use-correct-size-for-pcre2_pattern_info.patch Patch6017: backport-gregex-use-correct-size-for-pcre2_pattern_info.patch
Patch6018: backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch
Patch6019: backport-regex-Actually-check-for-match-options-changes.patch
Patch6020: backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch
Patch6021: backport-regex-Add-test-for-gtksourceview-regression.patch
Patch6022: backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch
Patch6023: backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch
Patch6024: backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch
Patch6025: backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch
Patch6026: backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch
Patch6027: backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch
Patch6028: backport-regex-Compute-the-offsets-size-based-on-match-results.patch
Patch6029: backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch
Patch6030: backport-regex-Handle-JIT-errors-more-explicitly.patch
Patch6031: backport-regex-Make-possible-to-test-replacements-with-options.patch
Patch6032: backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch
Patch6033: backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch
Patch6034: backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch
Patch6035: backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch
Patch6036: backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch
Patch6037: backport-xdgmime-fix-double-free.patch
Patch6038: backport-Implement-GFileIface.set_display_name-for-resource-files.patch
Patch6039: backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch
Patch6040: backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch
Patch6041: backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch
Patch6042: backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch
Patch6043: backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch
Patch6044: backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch
Patch6045: backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch
BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter
BUildRequires: glibc-devel libattr-devel libselinux-devel meson BUildRequires: glibc-devel libattr-devel libselinux-devel meson
@ -197,6 +225,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%endif %endif
%changelog %changelog
* Sat Oct 15 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-4
- backport some patches from community
* Mon Sep 5 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-3 * Mon Sep 5 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-3
- replace pcre1 with pcre2 - replace pcre1 with pcre2