diff --git a/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch b/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c52f54fe15388d87f73b11a207c8655a2448fc2 --- /dev/null +++ b/backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch @@ -0,0 +1,69 @@ +From f43cf341511dd684a58c09e104e28c11987cbff1 Mon Sep 17 00:00:00 2001 +From: Rozhuk Ivan +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 + diff --git a/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch b/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch new file mode 100644 index 0000000000000000000000000000000000000000..0dd94f7baf2c0a7e800ec7eb34ca3b99a807b368 --- /dev/null +++ b/backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch @@ -0,0 +1,68 @@ +From d9ba6150909818beb05573f54f26232063492c5b Mon Sep 17 00:00:00 2001 +From: Emmanuel Fleury +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 + diff --git a/backport-Implement-GFileIface.set_display_name-for-resource-files.patch b/backport-Implement-GFileIface.set_display_name-for-resource-files.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca4f5577656f2d42571476749a50ba5a3811439b --- /dev/null +++ b/backport-Implement-GFileIface.set_display_name-for-resource-files.patch @@ -0,0 +1,52 @@ +From a9394bd68e222377f0156bf9c213b3f3a1e340d0 Mon Sep 17 00:00:00 2001 +From: Emmanuele Bassi +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 + diff --git a/backport-add-OOM-handling-in-mimemagic.patch b/backport-add-OOM-handling-in-mimemagic.patch deleted file mode 100644 index 3b69c4eaf39d14f385313d5cd383b8932db004da..0000000000000000000000000000000000000000 --- a/backport-add-OOM-handling-in-mimemagic.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 9f1c59eef2e21b5a80c22d44deec2cba884cdfce Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 15:31:01 +0300 -Subject: [PATCH] add OOM handling in mimemagic - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9f1c59eef2e21b5a80c22d44deec2cba884cdfce - ---- - gio/xdgmime/xdgmimemagic.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/gio/xdgmime/xdgmimemagic.c b/gio/xdgmime/xdgmimemagic.c -index c68e27bedb..08b2c6da4f 100644 ---- a/gio/xdgmime/xdgmimemagic.c -+++ b/gio/xdgmime/xdgmimemagic.c -@@ -103,6 +103,8 @@ _xdg_mime_magic_matchlet_new (void) - XdgMimeMagicMatchlet *matchlet; - - matchlet = malloc (sizeof (XdgMimeMagicMatchlet)); -+ if (matchlet == NULL) -+ return NULL; - - matchlet->indent = 0; - matchlet->offset = 0; -@@ -355,6 +357,11 @@ _xdg_mime_magic_parse_magic_line (FILE *magic_file, - return XDG_MIME_MAGIC_ERROR; - - matchlet = _xdg_mime_magic_matchlet_new (); -+ -+ /* OOM */ -+ if (matchlet == NULL) -+ return XDG_MIME_MAGIC_ERROR; -+ - matchlet->indent = indent; - matchlet->offset = _xdg_mime_magic_read_a_number (magic_file, &end_of_file); - if (end_of_file) -@@ -767,6 +774,11 @@ _xdg_mime_magic_read_magic_file (XdgMimeMagic *mime_magic, - { - case XDG_MIME_MAGIC_SECTION: - match = _xdg_mime_magic_match_new (); -+ -+ /* OOM */ -+ if (match == NULL) -+ return; -+ - state = _xdg_mime_magic_parse_header (magic_file, match); - if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR) - _xdg_mime_magic_match_free (match); --- -GitLab - diff --git a/backport-add-version-macros-for-GLib-2.74.patch b/backport-add-version-macros-for-GLib-2.74.patch new file mode 100644 index 0000000000000000000000000000000000000000..1445a34ecee9163cfc95482e1ec7acc9f0736bf0 --- /dev/null +++ b/backport-add-version-macros-for-GLib-2.74.patch @@ -0,0 +1,228 @@ +From 4f79f0712cd5c67301e60e758a2f6c60b44e7a0e Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 28 Mar 2022 12:55:20 +0100 +Subject: [PATCH] gversionmacros: Add version macros for GLib 2.74 + +Signed-off-by: Philip Withnall + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/4f79f0712cd5c67301e60e758a2f6c60b44e7a0e + +--- + docs/reference/gio/gio-docs.xml | 4 +++ + docs/reference/glib/glib-docs.xml | 4 +++ + docs/reference/glib/glib-sections.txt | 14 ++++++++ + docs/reference/gobject/gobject-docs.xml | 4 +++ + docs/reference/meson.build | 2 +- + glib/gversionmacros.h | 44 +++++++++++++++++++++++++ + 6 files changed, 71 insertions(+), 1 deletion(-) + +diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml +index 76057e8978..bee46875ff 100644 +--- a/docs/reference/gio/gio-docs.xml ++++ b/docs/reference/gio/gio-docs.xml +@@ -400,6 +400,10 @@ + Index of new symbols in 2.72 + + ++ ++ Index of new symbols in 2.74 ++ ++ + + + +diff --git a/docs/reference/glib/glib-docs.xml b/docs/reference/glib/glib-docs.xml +index e642f4e930..b3928257e4 100644 +--- a/docs/reference/glib/glib-docs.xml ++++ b/docs/reference/glib/glib-docs.xml +@@ -296,6 +296,10 @@ + Index of new symbols in 2.72 + + ++ ++ Index of new symbols in 2.74 ++ ++ + + + +diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt +index 97dcf1f701..3532d28cb0 100644 +--- a/docs/reference/glib/glib-sections.txt ++++ b/docs/reference/glib/glib-sections.txt +@@ -140,6 +140,7 @@ GLIB_VERSION_2_66 + GLIB_VERSION_2_68 + GLIB_VERSION_2_70 + GLIB_VERSION_2_72 ++GLIB_VERSION_2_74 + GLIB_VERSION_CUR_STABLE + GLIB_VERSION_PREV_STABLE + GLIB_VERSION_MIN_REQUIRED +@@ -172,6 +173,7 @@ GLIB_AVAILABLE_ENUMERATOR_IN_2_66 + GLIB_AVAILABLE_ENUMERATOR_IN_2_68 + GLIB_AVAILABLE_ENUMERATOR_IN_2_70 + GLIB_AVAILABLE_ENUMERATOR_IN_2_72 ++GLIB_AVAILABLE_ENUMERATOR_IN_2_74 + GLIB_AVAILABLE_IN_ALL + GLIB_AVAILABLE_IN_2_26 + GLIB_AVAILABLE_IN_2_28 +@@ -197,6 +199,7 @@ GLIB_AVAILABLE_IN_2_66 + GLIB_AVAILABLE_IN_2_68 + GLIB_AVAILABLE_IN_2_70 + GLIB_AVAILABLE_IN_2_72 ++GLIB_AVAILABLE_IN_2_74 + GLIB_AVAILABLE_MACRO_IN_2_26 + GLIB_AVAILABLE_MACRO_IN_2_28 + GLIB_AVAILABLE_MACRO_IN_2_30 +@@ -221,6 +224,7 @@ GLIB_AVAILABLE_MACRO_IN_2_66 + GLIB_AVAILABLE_MACRO_IN_2_68 + GLIB_AVAILABLE_MACRO_IN_2_70 + GLIB_AVAILABLE_MACRO_IN_2_72 ++GLIB_AVAILABLE_MACRO_IN_2_74 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_44 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_60 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_62 +@@ -229,6 +233,7 @@ GLIB_AVAILABLE_STATIC_INLINE_IN_2_66 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_68 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_70 + GLIB_AVAILABLE_STATIC_INLINE_IN_2_72 ++GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 + GLIB_AVAILABLE_TYPE_IN_2_26 + GLIB_AVAILABLE_TYPE_IN_2_28 + GLIB_AVAILABLE_TYPE_IN_2_30 +@@ -253,6 +258,7 @@ GLIB_AVAILABLE_TYPE_IN_2_66 + GLIB_AVAILABLE_TYPE_IN_2_68 + GLIB_AVAILABLE_TYPE_IN_2_70 + GLIB_AVAILABLE_TYPE_IN_2_72 ++GLIB_AVAILABLE_TYPE_IN_2_74 + GLIB_DEPRECATED_ENUMERATOR + GLIB_DEPRECATED_ENUMERATOR_FOR + GLIB_DEPRECATED_ENUMERATOR_IN_2_26 +@@ -303,6 +309,8 @@ GLIB_DEPRECATED_ENUMERATOR_IN_2_70 + GLIB_DEPRECATED_ENUMERATOR_IN_2_70_FOR + GLIB_DEPRECATED_ENUMERATOR_IN_2_72 + GLIB_DEPRECATED_ENUMERATOR_IN_2_72_FOR ++GLIB_DEPRECATED_ENUMERATOR_IN_2_74 ++GLIB_DEPRECATED_ENUMERATOR_IN_2_74_FOR + GLIB_DEPRECATED_IN_2_26 + GLIB_DEPRECATED_IN_2_26_FOR + GLIB_DEPRECATED_IN_2_28 +@@ -351,6 +359,8 @@ GLIB_DEPRECATED_IN_2_70 + GLIB_DEPRECATED_IN_2_70_FOR + GLIB_DEPRECATED_IN_2_72 + GLIB_DEPRECATED_IN_2_72_FOR ++GLIB_DEPRECATED_IN_2_74 ++GLIB_DEPRECATED_IN_2_74_FOR + GLIB_DEPRECATED_MACRO + GLIB_DEPRECATED_MACRO_FOR + GLIB_DEPRECATED_MACRO_IN_2_26 +@@ -401,6 +411,8 @@ GLIB_DEPRECATED_MACRO_IN_2_70 + GLIB_DEPRECATED_MACRO_IN_2_70_FOR + GLIB_DEPRECATED_MACRO_IN_2_72 + GLIB_DEPRECATED_MACRO_IN_2_72_FOR ++GLIB_DEPRECATED_MACRO_IN_2_74 ++GLIB_DEPRECATED_MACRO_IN_2_74_FOR + GLIB_DEPRECATED_TYPE + GLIB_DEPRECATED_TYPE_FOR + GLIB_DEPRECATED_TYPE_IN_2_26 +@@ -451,6 +463,8 @@ GLIB_DEPRECATED_TYPE_IN_2_70 + GLIB_DEPRECATED_TYPE_IN_2_70_FOR + GLIB_DEPRECATED_TYPE_IN_2_72 + GLIB_DEPRECATED_TYPE_IN_2_72_FOR ++GLIB_DEPRECATED_TYPE_IN_2_74 ++GLIB_DEPRECATED_TYPE_IN_2_74_FOR + GLIB_VERSION_CUR_STABLE + GLIB_VERSION_PREV_STABLE + +diff --git a/docs/reference/gobject/gobject-docs.xml b/docs/reference/gobject/gobject-docs.xml +index aa5a9c7220..bfab048372 100644 +--- a/docs/reference/gobject/gobject-docs.xml ++++ b/docs/reference/gobject/gobject-docs.xml +@@ -218,6 +218,10 @@ + Index of new symbols in 2.72 + + ++ ++ Index of new symbols in 2.74 ++ ++ + + + +diff --git a/docs/reference/meson.build b/docs/reference/meson.build +index 8128e21bf2..1bc97a2f6e 100644 +--- a/docs/reference/meson.build ++++ b/docs/reference/meson.build +@@ -7,7 +7,7 @@ + stable_2_series_versions = [ + '26', '28', '30', '32', '34', '36', '38', + '40', '42', '44', '46', '48', '50', '52', '54', '56', '58', +- '60', '62', '64', '66', '68', '70', '72', ++ '60', '62', '64', '66', '68', '70', '72', '74', + ] + + ignore_decorators = [ +diff --git a/glib/gversionmacros.h b/glib/gversionmacros.h +index e08c809019..143e048241 100644 +--- a/glib/gversionmacros.h ++++ b/glib/gversionmacros.h +@@ -275,6 +275,16 @@ + */ + #define GLIB_VERSION_2_72 (G_ENCODE_VERSION (2, 72)) + ++/** ++ * GLIB_VERSION_2_74: ++ * ++ * A macro that evaluates to the 2.74 version of GLib, in a format ++ * that can be used by the C pre-processor. ++ * ++ * Since: 2.74 ++ */ ++#define GLIB_VERSION_2_74 (G_ENCODE_VERSION (2, 74)) ++ + /** + * GLIB_VERSION_CUR_STABLE: + * +@@ -1164,4 +1174,38 @@ + # define GLIB_AVAILABLE_TYPE_IN_2_72 + #endif + ++#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_74 ++# define GLIB_DEPRECATED_IN_2_74 GLIB_DEPRECATED ++# define GLIB_DEPRECATED_IN_2_74_FOR(f) GLIB_DEPRECATED_FOR(f) ++# define GLIB_DEPRECATED_MACRO_IN_2_74 GLIB_DEPRECATED_MACRO ++# define GLIB_DEPRECATED_MACRO_IN_2_74_FOR(f) GLIB_DEPRECATED_MACRO_FOR(f) ++# define GLIB_DEPRECATED_ENUMERATOR_IN_2_74 GLIB_DEPRECATED_ENUMERATOR ++# define GLIB_DEPRECATED_ENUMERATOR_IN_2_74_FOR(f) GLIB_DEPRECATED_ENUMERATOR_FOR(f) ++# define GLIB_DEPRECATED_TYPE_IN_2_74 GLIB_DEPRECATED_TYPE ++# define GLIB_DEPRECATED_TYPE_IN_2_74_FOR(f) GLIB_DEPRECATED_TYPE_FOR(f) ++#else ++# define GLIB_DEPRECATED_IN_2_74 _GLIB_EXTERN ++# define GLIB_DEPRECATED_IN_2_74_FOR(f) _GLIB_EXTERN ++# define GLIB_DEPRECATED_MACRO_IN_2_74 ++# define GLIB_DEPRECATED_MACRO_IN_2_74_FOR(f) ++# define GLIB_DEPRECATED_ENUMERATOR_IN_2_74 ++# define GLIB_DEPRECATED_ENUMERATOR_IN_2_74_FOR(f) ++# define GLIB_DEPRECATED_TYPE_IN_2_74 ++# define GLIB_DEPRECATED_TYPE_IN_2_74_FOR(f) ++#endif ++ ++#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_74 ++# define GLIB_AVAILABLE_IN_2_74 GLIB_UNAVAILABLE(2, 74) ++# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 GLIB_UNAVAILABLE_STATIC_INLINE(2, 74) ++# define GLIB_AVAILABLE_MACRO_IN_2_74 GLIB_UNAVAILABLE_MACRO(2, 74) ++# define GLIB_AVAILABLE_ENUMERATOR_IN_2_74 GLIB_UNAVAILABLE_ENUMERATOR(2, 74) ++# define GLIB_AVAILABLE_TYPE_IN_2_74 GLIB_UNAVAILABLE_TYPE(2, 74) ++#else ++# define GLIB_AVAILABLE_IN_2_74 _GLIB_EXTERN ++# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 ++# define GLIB_AVAILABLE_MACRO_IN_2_74 ++# define GLIB_AVAILABLE_ENUMERATOR_IN_2_74 ++# define GLIB_AVAILABLE_TYPE_IN_2_74 ++#endif ++ + #endif /* __G_VERSION_MACROS_H__ */ +-- +GitLab + diff --git a/backport-application-Unset-the-registered-state-after-shutting-down.patch b/backport-application-Unset-the-registered-state-after-shutting-down.patch deleted file mode 100644 index 7101ea9ea3a92b0a6a016e9e674a37f9c378b9cf..0000000000000000000000000000000000000000 --- a/backport-application-Unset-the-registered-state-after-shutting-down.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 63873c0eb114faf6696874fe577912af687d67cf Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Wed, 21 Apr 2021 06:17:36 +0200 -Subject: [PATCH] application: Unset the registered state after shutting down - -An application that has been shut down is still marked as registered -even if its implementation has been already destroyed. - -This may lead to unguarded crashes when calling functions that have -assumptions for being used with registered applications. - -So, when an application is registered, mark it as unregistered just -before destroying its implementation and after being shut down, so that -we follow the registration process in reversed order. - -Added tests - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/63873c0eb114faf6696874fe577912af687d67cf - ---- - gio/gapplication.c | 7 ++++ - gio/tests/gapplication.c | 76 ++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 83 insertions(+) - -diff --git a/gio/gapplication.c b/gio/gapplication.c -index 8e65176354..bf4a4cb650 100644 ---- a/gio/gapplication.c -+++ b/gio/gapplication.c -@@ -2578,6 +2578,13 @@ g_application_run (GApplication *application, - - if (application->priv->impl) - { -+ if (application->priv->is_registered) -+ { -+ application->priv->is_registered = FALSE; -+ -+ g_object_notify (G_OBJECT (application), "is-registered"); -+ } -+ - g_application_impl_flush (application->priv->impl); - g_application_impl_destroy (application->priv->impl); - application->priv->impl = NULL; -diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c -index 900e7ac977..6f1a27e0f3 100644 ---- a/gio/tests/gapplication.c -+++ b/gio/tests/gapplication.c -@@ -576,6 +576,81 @@ test_quit (void) - g_free (binpath); - } - -+typedef struct -+{ -+ gboolean shutdown; -+ GParamSpec *notify_spec; /* (owned) (nullable) */ -+} RegisteredData; -+ -+static void -+on_registered_shutdown (GApplication *app, -+ gpointer user_data) -+{ -+ RegisteredData *registered_data = user_data; -+ -+ registered_data->shutdown = TRUE; -+} -+ -+static void -+on_registered_notify (GApplication *app, -+ GParamSpec *spec, -+ gpointer user_data) -+{ -+ RegisteredData *registered_data = user_data; -+ registered_data->notify_spec = g_param_spec_ref (spec); -+ -+ if (g_application_get_is_registered (app)) -+ g_assert_false (registered_data->shutdown); -+ else -+ g_assert_true (registered_data->shutdown); -+} -+ -+static void -+test_registered (void) -+{ -+ char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL); -+ gchar *argv[] = { binpath, NULL }; -+ RegisteredData registered_data = { FALSE, NULL }; -+ GApplication *app; -+ -+ app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE); -+ g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL); -+ g_signal_connect (app, "shutdown", G_CALLBACK (on_registered_shutdown), ®istered_data); -+ g_signal_connect (app, "notify::is-registered", G_CALLBACK (on_registered_notify), ®istered_data); -+ -+ g_assert_null (registered_data.notify_spec); -+ -+ g_assert_true (g_application_register (app, NULL, NULL)); -+ g_assert_true (g_application_get_is_registered (app)); -+ -+ g_assert_nonnull (registered_data.notify_spec); -+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); -+ g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); -+ -+ g_assert_false (registered_data.shutdown); -+ -+ g_application_run (app, 1, argv); -+ -+ g_assert_true (registered_data.shutdown); -+ g_assert_false (g_application_get_is_registered (app)); -+ g_assert_nonnull (registered_data.notify_spec); -+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); -+ g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); -+ -+ /* Register it again */ -+ registered_data.shutdown = FALSE; -+ g_assert_true (g_application_register (app, NULL, NULL)); -+ g_assert_true (g_application_get_is_registered (app)); -+ g_assert_nonnull (registered_data.notify_spec); -+ g_assert_cmpstr (registered_data.notify_spec->name, ==, "is-registered"); -+ g_clear_pointer (®istered_data.notify_spec, g_param_spec_unref); -+ g_assert_false (registered_data.shutdown); -+ -+ g_object_unref (app); -+ -+ g_free (binpath); -+} -+ - static void - on_activate (GApplication *app) - { -@@ -1136,6 +1211,7 @@ main (int argc, char **argv) - g_test_add_func ("/gapplication/properties", properties); - g_test_add_func ("/gapplication/app-id", appid); - g_test_add_func ("/gapplication/quit", test_quit); -+ g_test_add_func ("/gapplication/registered", test_registered); - g_test_add_func ("/gapplication/local-actions", test_local_actions); - /* g_test_add_func ("/gapplication/remote-actions", test_remote_actions); */ - g_test_add_func ("/gapplication/local-command-line", test_local_command_line); --- -GitLab - diff --git a/backport-correctly-use-3-parameters-for-clise-range.patch b/backport-correctly-use-3-parameters-for-clise-range.patch deleted file mode 100644 index d9f366c275465eb8e341b3762e83b04cd1b856b6..0000000000000000000000000000000000000000 --- a/backport-correctly-use-3-parameters-for-clise-range.patch +++ /dev/null @@ -1,28 +0,0 @@ -From b71117d89434db83d34bc1b981ca03d4be299576 Mon Sep 17 00:00:00 2001 -From: Khem Raj -Date: Thu, 8 Jul 2021 17:26:43 -0700 -Subject: [PATCH] correctly use 3 parameters for close_range - -libc implementation has 3 parameter e.g. -https://www.freebsd.org/cgi/man.cgi?query=close_range&sektion=2&format=html - -Signed-off-by: Khem Raj ---- - glib/gspawn.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/glib/gspawn.c b/glib/gspawn.c -index 899647c2f..3073a10a4 100644 ---- a/glib/gspawn.c -+++ b/glib/gspawn.c -@@ -1520,7 +1520,7 @@ safe_closefrom (int lowfd) - * - * Handle ENOSYS in case it’s supported in libc but not the kernel; if so, - * fall back to safe_fdwalk(). */ -- if (close_range (lowfd, G_MAXUINT) != 0 && errno == ENOSYS) -+ if (close_range (lowfd, G_MAXUINT, 0) != 0 && errno == ENOSYS) - #endif /* HAVE_CLOSE_RANGE */ - (void) safe_fdwalk (close_func, GINT_TO_POINTER (lowfd)); - #endif --- -GitLab diff --git a/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch b/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0f8a1d1685df31bd7238123064efa021b90601b --- /dev/null +++ b/backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch @@ -0,0 +1,34 @@ +From 27203e48c91ab8b55033dcf1773cb60c0aaed3fa Mon Sep 17 00:00:00 2001 +From: Sebastian Keller +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 + diff --git a/backport-fix-a-memory-leak.patch b/backport-fix-a-memory-leak.patch deleted file mode 100644 index e303568f5c2b06d0bf5c0a448d459305c2ca15d1..0000000000000000000000000000000000000000 --- a/backport-fix-a-memory-leak.patch +++ /dev/null @@ -1,27 +0,0 @@ -From df500c68a4d0741d1d6cf8ec3f8039a0d1f4b174 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= -Date: Tue, 1 Jun 2021 17:43:45 +0200 -Subject: [PATCH] inotify: Fix a memory leak - -Fixes: #2311 -Conflict:NA -Reference:https://github.com/GNOME/glib/commit/df500c68a4d0741d1d6cf8ec3f8039a0d1f4b174 ---- - gio/inotify/inotify-path.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gio/inotify/inotify-path.c b/gio/inotify/inotify-path.c -index f0528f4..e1129cd 100644 ---- a/gio/inotify/inotify-path.c -+++ b/gio/inotify/inotify-path.c -@@ -208,6 +208,7 @@ ip_watched_file_free (ip_watched_file_t *file) - g_assert (file->subs == NULL); - g_free (file->filename); - g_free (file->path); -+ g_free (file); - } - - static void --- -2.27.0 - diff --git a/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch b/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch new file mode 100644 index 0000000000000000000000000000000000000000..2c8c7f3a3a33362c1900d72f2d9412f86c4d3af5 --- /dev/null +++ b/backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch @@ -0,0 +1,46 @@ +From 02d0d6497b92d05d1145d1077654ad2453938b6c Mon Sep 17 00:00:00 2001 +From: Rozhuk Ivan +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, diff --git a/backport-gapplication-fix-arguments-leak-in-error-path.patch b/backport-gapplication-fix-arguments-leak-in-error-path.patch deleted file mode 100644 index 6d833df6f6567d37162770176d4b5f05b3fae1c7..0000000000000000000000000000000000000000 --- a/backport-gapplication-fix-arguments-leak-in-error-path.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 65b4bc30eb38b1484533a2ee08f7229a9e961af8 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 31 Mar 2021 11:44:23 -0500 -Subject: [PATCH] gapplication: fix arguments leak in error path - -If this g_return_val_if_fail() is ever hit, then we leak arguments. -This is not very important because if your code hits -g_return_val_if_fail() you are invoking undefined behavior, a rather -more serious problem, but let's replace it with g_critical() to be -robust. - -This includes a small behavior change: it returns 1 rather than 0 in -this error case. - -Found by Coverity. - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/65b4bc30eb38b1484533a2ee08f7229a9e961af8 - ---- - gio/gapplication.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/gio/gapplication.c b/gio/gapplication.c -index 5a43202a5d..8e65176354 100644 ---- a/gio/gapplication.c -+++ b/gio/gapplication.c -@@ -2524,7 +2524,12 @@ g_application_run (GApplication *application, - - context = g_main_context_default (); - acquired_context = g_main_context_acquire (context); -- g_return_val_if_fail (acquired_context, 0); -+ if (!acquired_context) -+ { -+ g_critical ("g_application_run() cannot acquire the default main context because it is already acquired by another thread!"); -+ g_strfreev (arguments); -+ return 1; -+ } - - if (!G_APPLICATION_GET_CLASS (application) - ->local_command_line (application, &arguments, &status)) --- -GitLab - diff --git a/backport-gdbusauth-fix-error-leak.patch b/backport-gdbusauth-fix-error-leak.patch deleted file mode 100644 index 709b71e1bc3783f365bc016a8b015d56f11c35b2..0000000000000000000000000000000000000000 --- a/backport-gdbusauth-fix-error-leak.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 2b29495bcb59ba00bec808c509112dae6e019fd7 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 31 Mar 2021 14:12:39 -0500 -Subject: [PATCH] gdbusauth: fix error leak - -local_error is leaked in the G_IO_ERROR_NOT_SUPPORTED case. Found by -Coverity. - -Conflict:NA -Reference:https://github.com/GNOME/glib/commit/2b29495bcb59ba00bec808c509112dae6e019fd7 - ---- - gio/gdbusauth.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c -index c430f0cf03..534dca2d19 100644 ---- a/gio/gdbusauth.c -+++ b/gio/gdbusauth.c -@@ -1007,6 +1007,7 @@ _g_dbus_auth_run_server (GDBusAuth *auth, - g_propagate_error (error, local_error); - goto out; - } -+ g_clear_error (&local_error); - } - else - { diff --git a/backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch b/backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch deleted file mode 100644 index 79cf015c01479a7944d18693ff34ac82d2689ea0..0000000000000000000000000000000000000000 --- a/backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 719484a5754cca036d123ae4c2ae3d150bacef32 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Wed, 31 Mar 2021 14:23:13 -0500 -Subject: [PATCH] gdbusobjectmanagerservice: fix leak in error path - -If the third g_return_val_if_fail() is hit, then we leak -orig_object_path. There is no reason we need to strdup it here. - -Found by Coverity. - -Conflict:NA -Reference:https://github.com/GNOME/glib/commit/719484a5754cca036d123ae4c2ae3d150bacef32 ---- - gio/gdbusobjectmanagerserver.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - -diff --git a/gio/gdbusobjectmanagerserver.c b/gio/gdbusobjectmanagerserver.c -index 39f4ed5006..0a0cea84ab 100644 ---- a/gio/gdbusobjectmanagerserver.c -+++ b/gio/gdbusobjectmanagerserver.c -@@ -565,12 +565,12 @@ void - g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager, - GDBusObjectSkeleton *object) - { -- gchar *orig_object_path; -+ const gchar *orig_object_path; - gchar *object_path; - guint count; - gboolean modified; - -- orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object))); -+ orig_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object)); - - g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager)); - g_return_if_fail (G_IS_DBUS_OBJECT (object)); -@@ -602,7 +602,6 @@ g_dbus_object_manager_server_export_uniquely (GDBusObjectManagerServer *manager, - g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (object), object_path); - - g_free (object_path); -- g_free (orig_object_path); - - } - diff --git a/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch b/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d5d1d3324901d6f92ad611861e8ba7939a0442e --- /dev/null +++ b/backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch @@ -0,0 +1,48 @@ +From 221f22b6e18fdd306e676e28a79afd3697bddd03 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch b/backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch deleted file mode 100644 index 99ba4614c46ed047a5bb1a9bafa73c915c39f426..0000000000000000000000000000000000000000 --- a/backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch +++ /dev/null @@ -1,32 +0,0 @@ -From be57c5d14c771361482917f4cb35851a07d19a8e Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 29 Apr 2021 13:17:05 +0100 -Subject: [PATCH] gdtlsconnection: Fix a check for a vfunc being implemented - -It was checking the wrong vfunc; likely a copy/paste error. - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/be57c5d14c771361482917f4cb35851a07d19a8e - ---- - gio/gdtlsconnection.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gio/gdtlsconnection.c b/gio/gdtlsconnection.c -index 4bbc88d7a7..136e317b13 100644 ---- a/gio/gdtlsconnection.c -+++ b/gio/gdtlsconnection.c -@@ -1069,7 +1069,7 @@ g_dtls_connection_get_negotiated_protocol (GDtlsConnection *conn) - GDtlsConnectionInterface *iface; - - iface = G_DTLS_CONNECTION_GET_INTERFACE (conn); -- if (iface->set_advertised_protocols == NULL) -+ if (iface->get_negotiated_protocol == NULL) - return NULL; - - return iface->get_negotiated_protocol (conn); --- -GitLab - diff --git a/backport-gfileenumerator-fix-leak-in-error-path.patch b/backport-gfileenumerator-fix-leak-in-error-path.patch deleted file mode 100644 index ddfe7fcaf76bc7c794f4600c130a158d20a45a99..0000000000000000000000000000000000000000 --- a/backport-gfileenumerator-fix-leak-in-error-path.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 8bfc2998135ee9c4460520febb3af720c61438a5 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 1 Apr 2021 14:13:19 -0500 -Subject: [PATCH] gfileenumerator: fix leak in error path - -Found by Coverity. - -Conflict:NA -Reference:https://github.com/GNOME/glib/commit/8bfc2998135ee9c4460520febb3af720c61438a5 ---- - gio/gfileenumerator.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gio/gfileenumerator.c b/gio/gfileenumerator.c -index ac2e4eb980..1f9bc24ebe 100644 ---- a/gio/gfileenumerator.c -+++ b/gio/gfileenumerator.c -@@ -787,7 +787,10 @@ next_files_thread (GTask *task, - } - - if (error) -- g_task_return_error (task, error); -+ { -+ g_list_free_full (files, g_object_unref); -+ g_task_return_error (task, error); -+ } - else - g_task_return_pointer (task, files, (GDestroyNotify)next_async_op_free); - } diff --git a/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch b/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch new file mode 100644 index 0000000000000000000000000000000000000000..9a62b5b1cd67aef3ab8b1e96295cd368e6d1317d --- /dev/null +++ b/backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch @@ -0,0 +1,29 @@ +From e268ff39b648e7b100d2aa50f472b4ff8ff5313a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch b/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch new file mode 100644 index 0000000000000000000000000000000000000000..ce5f46b5fbd4d662c5f1d2212d0152a5109e6595 --- /dev/null +++ b/backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch @@ -0,0 +1,67 @@ +From 1da208cddc19cad05ccf4b798a99f7045e41ffc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-giochannel-Add-G_IO_FLAG_NONE.patch b/backport-giochannel-Add-G_IO_FLAG_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f671e050baf98c5d45460305022d15a29a24b32 --- /dev/null +++ b/backport-giochannel-Add-G_IO_FLAG_NONE.patch @@ -0,0 +1,58 @@ +From cef780e9ef86b1d9545db892c6b8340488da21d9 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 23 Jun 2022 10:12:44 +0100 +Subject: [PATCH] giochannel: Add G_IO_FLAG_NONE + +This makes the state where no flags are set a bit more self-documenting. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/cef780e9ef86b1d9545db892c6b8340488da21d9 + +--- + glib/giochannel.c | 1 + + glib/giochannel.h | 1 + + glib/giounix.c | 2 +- + 3 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/glib/giochannel.c b/glib/giochannel.c +index 6fec45f66d..25baf42c9a 100644 +--- a/glib/giochannel.c ++++ b/glib/giochannel.c +@@ -946,6 +946,7 @@ g_io_channel_get_line_term (GIOChannel *channel, + **/ + /** + * GIOFlags: ++ * @G_IO_FLAG_NONE: no special flags set. Since: 2.74 + * @G_IO_FLAG_APPEND: turns on append mode, corresponds to %O_APPEND + * (see the documentation of the UNIX open() syscall) + * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to +diff --git a/glib/giochannel.h b/glib/giochannel.h +index 5a13449d58..dee3d7d055 100644 +--- a/glib/giochannel.h ++++ b/glib/giochannel.h +@@ -85,6 +85,7 @@ typedef enum + + typedef enum + { ++ G_IO_FLAG_NONE GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_IO_FLAG_APPEND = 1 << 0, + G_IO_FLAG_NONBLOCK = 1 << 1, + G_IO_FLAG_IS_READABLE = 1 << 2, /* Read only flag */ +diff --git a/glib/giounix.c b/glib/giounix.c +index b6345b6c68..067cecf9ac 100644 +--- a/glib/giounix.c ++++ b/glib/giounix.c +@@ -400,7 +400,7 @@ g_io_unix_set_flags (GIOChannel *channel, + static GIOFlags + g_io_unix_get_flags (GIOChannel *channel) + { +- GIOFlags flags = 0; ++ GIOFlags flags = G_IO_FLAG_NONE; + glong fcntl_flags; + GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel; + +-- +GitLab + diff --git a/backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch b/backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..9603aeca1794cab6b65c6a1f365df1412f342ba3 --- /dev/null +++ b/backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch @@ -0,0 +1,82 @@ +From f59e02a1439c70616547d51abf0a6da33e095e80 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 31 Mar 2022 14:28:56 +0100 +Subject: [PATCH] gioenums: Add G_TLS_CERTIFICATE_FLAGS_NONE + +This makes the absence of flags (in other words, a valid certificate) +more self-documenting. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f59e02a1439c70616547d51abf0a6da33e095e80 + +--- + gio/gdtlsclientconnection.c | 2 +- + gio/gioenums.h | 2 ++ + gio/gtlscertificate.c | 2 ++ + gio/gtlsclientconnection.c | 2 +- + 4 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/gio/gdtlsclientconnection.c b/gio/gdtlsclientconnection.c +index 74cce7572f..403c8b74d0 100644 +--- a/gio/gdtlsclientconnection.c ++++ b/gio/gdtlsclientconnection.c +@@ -191,7 +191,7 @@ g_dtls_client_connection_new (GDatagramBased *base_socket, + GTlsCertificateFlags + g_dtls_client_connection_get_validation_flags (GDtlsClientConnection *conn) + { +- GTlsCertificateFlags flags = 0; ++ GTlsCertificateFlags flags = G_TLS_CERTIFICATE_FLAGS_NONE; + + g_return_val_if_fail (G_IS_DTLS_CLIENT_CONNECTION (conn), 0); + +diff --git a/gio/gioenums.h b/gio/gioenums.h +index 0d27c15a2b..deacd62206 100644 +--- a/gio/gioenums.h ++++ b/gio/gioenums.h +@@ -1578,6 +1578,7 @@ typedef enum { + + /** + * GTlsCertificateFlags: ++ * @G_TLS_CERTIFICATE_FLAGS_NONE: No flags. Since: 2.74 + * @G_TLS_CERTIFICATE_UNKNOWN_CA: The signing certificate authority is + * not known. + * @G_TLS_CERTIFICATE_BAD_IDENTITY: The certificate does not match the +@@ -1609,6 +1610,7 @@ typedef enum { + * Since: 2.28 + */ + typedef enum { ++ G_TLS_CERTIFICATE_FLAGS_NONE GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_TLS_CERTIFICATE_UNKNOWN_CA = (1 << 0), + G_TLS_CERTIFICATE_BAD_IDENTITY = (1 << 1), + G_TLS_CERTIFICATE_NOT_ACTIVATED = (1 << 2), +diff --git a/gio/gtlscertificate.c b/gio/gtlscertificate.c +index ca09b180ae..e97b8ac144 100644 +--- a/gio/gtlscertificate.c ++++ b/gio/gtlscertificate.c +@@ -1121,6 +1121,8 @@ g_tls_certificate_get_issuer (GTlsCertificate *cert) + * check a certificate against a CA that is not part of the system + * CA database. + * ++ * If @cert is valid, %G_TLS_CERTIFICATE_FLAGS_NONE is returned. ++ * + * If @identity is not %NULL, @cert's name(s) will be compared against + * it, and %G_TLS_CERTIFICATE_BAD_IDENTITY will be set in the return + * value if it does not match. If @identity is %NULL, that bit will +diff --git a/gio/gtlsclientconnection.c b/gio/gtlsclientconnection.c +index a6dc897f9f..e6c77b681d 100644 +--- a/gio/gtlsclientconnection.c ++++ b/gio/gtlsclientconnection.c +@@ -213,7 +213,7 @@ g_tls_client_connection_new (GIOStream *base_io_stream, + GTlsCertificateFlags + g_tls_client_connection_get_validation_flags (GTlsClientConnection *conn) + { +- GTlsCertificateFlags flags = 0; ++ GTlsCertificateFlags flags = G_TLS_CERTIFICATE_FLAGS_NONE; + + g_return_val_if_fail (G_IS_TLS_CLIENT_CONNECTION (conn), 0); + +-- +GitLab + diff --git a/backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch b/backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch new file mode 100644 index 0000000000000000000000000000000000000000..d52ad634a65b7bf6d53c78379291b08d61664821 --- /dev/null +++ b/backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch @@ -0,0 +1,53 @@ +From cc528f6c2e336a3484c920fe2d11337388829dbe Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 23 Jun 2022 10:09:15 +0100 +Subject: [PATCH] giomodule test: Don't pass a magic number to + g_test_trap_subprocess() + +This worked, but seems like bad style. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/cc528f6c2e336a3484c920fe2d11337388829dbe + +--- + gio/tests/giomodule.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/gio/tests/giomodule.c b/gio/tests/giomodule.c +index b4923eeefd..4ea6efebd1 100644 +--- a/gio/tests/giomodule.c ++++ b/gio/tests/giomodule.c +@@ -80,6 +80,10 @@ test_extension_point (void) + g_assert (g_io_extension_get_priority (ext) == 10); + } + ++#define INHERIT_ALL (G_TEST_SUBPROCESS_INHERIT_STDIN | \ ++ G_TEST_SUBPROCESS_INHERIT_STDOUT | \ ++ G_TEST_SUBPROCESS_INHERIT_STDERR) ++ + static void + test_module_scan_all (void) + { +@@ -105,7 +109,7 @@ test_module_scan_all (void) + g_assert_cmpstr (g_io_extension_get_name (ext), ==, "test-a"); + return; + } +- g_test_trap_subprocess (NULL, 0, 7); ++ g_test_trap_subprocess (NULL, 0, INHERIT_ALL); + g_test_trap_assert_passed (); + } + +@@ -136,7 +140,7 @@ test_module_scan_all_with_scope (void) + g_io_module_scope_free (scope); + return; + } +- g_test_trap_subprocess (NULL, 0, 7); ++ g_test_trap_subprocess (NULL, 0, INHERIT_ALL); + g_test_trap_assert_passed (); + } + +-- +GitLab + diff --git a/backport-glocalfileinfo-Fix-atime-mtime-mix.patch b/backport-glocalfileinfo-Fix-atime-mtime-mix.patch deleted file mode 100644 index 8badc4c4027d786c22182f14fd1997c76de074b3..0000000000000000000000000000000000000000 --- a/backport-glocalfileinfo-Fix-atime-mtime-mix.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 5a032f32ea77d81c012841dde88b070f55037f25 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 13:56:43 +0300 -Subject: [PATCH] glocalfileinfo: Fix atime/mtime mix due to bad copy/paste - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5a032f32ea77d81c012841dde88b070f55037f25 - ---- - gio/glocalfileinfo.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c -index 3867ca684a..d3b327a19c 100644 ---- a/gio/glocalfileinfo.c -+++ b/gio/glocalfileinfo.c -@@ -2650,7 +2650,7 @@ set_mtime_atime (char *filename, - { - if (lazy_stat (filename, &statbuf, &got_stat) == 0) - { -- times[0].tv_sec = statbuf.st_mtime; -+ times[0].tv_sec = statbuf.st_atime; - #if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC) - times[0].tv_usec = statbuf.st_atimensec / 1000; - #elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC) --- -GitLab - diff --git a/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch b/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..39228fc64c27b1a0811d5b3bf44ef3a85a51bf8b --- /dev/null +++ b/backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch @@ -0,0 +1,33 @@ +From 2401e1a090dcaac7614a8984cd3e3832a2a476ab Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch b/backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..063fc0165312c1ff97569df26b5dddb3c92e7d52 --- /dev/null +++ b/backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch @@ -0,0 +1,157 @@ +From 0d4e401ede234a3ce25e6098776ef5e966ad080b Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 23 Jun 2022 10:18:08 +0100 +Subject: [PATCH] gmarkup: Add G_MARKUP_PARSE_FLAGS_NONE + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/0d4e401ede234a3ce25e6098776ef5e966ad080b + +--- + gio/gcontenttype.c | 3 ++- + glib/gbookmarkfile.c | 2 +- + glib/gmarkup.h | 2 ++ + glib/tests/autoptr.c | 4 +++- + glib/tests/markup-collect.c | 4 +++- + glib/tests/markup-parse.c | 2 +- + glib/tests/markup-subparser.c | 3 ++- + glib/tests/markup.c | 3 ++- + gobject/tests/boxed.c | 3 ++- + 9 files changed, 18 insertions(+), 8 deletions(-) + +diff --git a/gio/gcontenttype.c b/gio/gcontenttype.c +index 190c5d7bf8..170bb43419 100644 +--- a/gio/gcontenttype.c ++++ b/gio/gcontenttype.c +@@ -435,7 +435,8 @@ load_comment_for_mime_helper (const char *dir, + if (!res) + return NULL; + +- context = g_markup_parse_context_new (&parser, 0, &parse_data, NULL); ++ context = g_markup_parse_context_new (&parser, G_MARKUP_PARSE_FLAGS_NONE, ++ &parse_data, NULL); + res = g_markup_parse_context_parse (context, data, len, NULL); + g_free (data); + g_markup_parse_context_free (context); +diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c +index 5ae1ad6642..a45f939b0f 100644 +--- a/glib/gbookmarkfile.c ++++ b/glib/gbookmarkfile.c +@@ -1510,7 +1510,7 @@ g_bookmark_file_parse (GBookmarkFile *bookmark, + parse_data->bookmark_file = bookmark; + + context = g_markup_parse_context_new (&markup_parser, +- 0, ++ G_MARKUP_PARSE_FLAGS_NONE, + parse_data, + (GDestroyNotify) parse_data_free); + +diff --git a/glib/gmarkup.h b/glib/gmarkup.h +index ae6976b154..6224d13431 100644 +--- a/glib/gmarkup.h ++++ b/glib/gmarkup.h +@@ -76,6 +76,7 @@ GQuark g_markup_error_quark (void); + + /** + * GMarkupParseFlags: ++ * @G_MARKUP_PARSE_FLAGS_NONE: No special behaviour. Since: 2.74 + * @G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG: flag you should not use + * @G_MARKUP_TREAT_CDATA_AS_TEXT: When this flag is set, CDATA marked + * sections are not passed literally to the @passthrough function of +@@ -96,6 +97,7 @@ GQuark g_markup_error_quark (void); + */ + typedef enum + { ++ G_MARKUP_PARSE_FLAGS_NONE GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, /*< nick=none >*/ + G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0, + G_MARKUP_TREAT_CDATA_AS_TEXT = 1 << 1, + G_MARKUP_PREFIX_ERROR_POSITION = 1 << 2, +diff --git a/glib/tests/autoptr.c b/glib/tests/autoptr.c +index 1b2dd7b094..035d3f6133 100644 +--- a/glib/tests/autoptr.c ++++ b/glib/tests/autoptr.c +@@ -243,7 +243,9 @@ static GMarkupParser parser = { + static void + test_g_markup_parse_context (void) + { +- g_autoptr(GMarkupParseContext) val = g_markup_parse_context_new (&parser, 0, NULL, NULL); ++ g_autoptr(GMarkupParseContext) val = g_markup_parse_context_new (&parser, ++ G_MARKUP_PARSE_FLAGS_NONE, ++ NULL, NULL); + g_assert_nonnull (val); + } + +diff --git a/glib/tests/markup-collect.c b/glib/tests/markup-collect.c +index 04b814b6cc..fa89b0ca61 100644 +--- a/glib/tests/markup-collect.c ++++ b/glib/tests/markup-collect.c +@@ -206,7 +206,9 @@ test_cleanup (void) + if (!g_test_undefined ()) + return; + +- context = g_markup_parse_context_new (&cleanup_parser, 0, NULL, NULL); ++ context = g_markup_parse_context_new (&cleanup_parser, ++ G_MARKUP_PARSE_FLAGS_NONE, NULL, ++ NULL); + g_markup_parse_context_parse (context, XML, -1, NULL); + + g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, +diff --git a/glib/tests/markup-parse.c b/glib/tests/markup-parse.c +index 00742d7459..1945bc39bd 100644 +--- a/glib/tests/markup-parse.c ++++ b/glib/tests/markup-parse.c +@@ -314,7 +314,7 @@ main (int argc, char *argv[]) + if (argc > 1) + { + gint arg = 1; +- GMarkupParseFlags flags = 0; ++ GMarkupParseFlags flags = G_MARKUP_PARSE_FLAGS_NONE; + + if (strcmp (argv[1], "--cdata-as-text") == 0) + { +diff --git a/glib/tests/markup-subparser.c b/glib/tests/markup-subparser.c +index 71b9ac6af5..4b1bc50185 100644 +--- a/glib/tests/markup-subparser.c ++++ b/glib/tests/markup-subparser.c +@@ -289,7 +289,8 @@ test (gconstpointer user_data) + + error = NULL; + string = g_string_new (NULL); +- ctx = g_markup_parse_context_new (&parser, 0, string, NULL); ++ ctx = g_markup_parse_context_new (&parser, G_MARKUP_PARSE_FLAGS_NONE, ++ string, NULL); + result = g_markup_parse_context_parse (ctx, tc->markup, + strlen (tc->markup), &error); + if (result) +diff --git a/glib/tests/markup.c b/glib/tests/markup.c +index 71f9ff16c3..6fced87d49 100644 +--- a/glib/tests/markup.c ++++ b/glib/tests/markup.c +@@ -80,7 +80,8 @@ test_markup_stack (void) + gboolean res; + GError *error = NULL; + +- context = g_markup_parse_context_new (&parser, 0, &data, NULL); ++ context = g_markup_parse_context_new (&parser, G_MARKUP_PARSE_FLAGS_NONE, ++ &data, NULL); + res = g_markup_parse_context_parse (context, content, -1, &error); + g_assert (res); + g_assert_no_error (error); +diff --git a/gobject/tests/boxed.c b/gobject/tests/boxed.c +index f961a2f87b..c2d091c54a 100644 +--- a/gobject/tests/boxed.c ++++ b/gobject/tests/boxed.c +@@ -560,7 +560,8 @@ test_boxed_markup (void) + g_value_init (&value, G_TYPE_MARKUP_PARSE_CONTEXT); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + +- c = g_markup_parse_context_new (&parser, 0, NULL, NULL); ++ c = g_markup_parse_context_new (&parser, G_MARKUP_PARSE_FLAGS_NONE, ++ NULL, NULL); + g_value_take_boxed (&value, c); + + c2 = g_value_get_boxed (&value); +-- +GitLab + diff --git a/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch b/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch deleted file mode 100644 index 097ab8bb8cded6caf9a7a2940f388bc42189f30a..0000000000000000000000000000000000000000 --- a/backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9dc7475f93c5c63fff66999d228407e13a47d5d3 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:00:03 +0300 -Subject: [PATCH] gopenuriportal: Fix GVariantBuilder and string leakage on - g_open failure - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9dc7475f93c5c63fff66999d228407e13a47d5d3 - ---- - gio/gopenuriportal.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c -index be68569ed8..6ef8f037c3 100644 ---- a/gio/gopenuriportal.c -+++ b/gio/gopenuriportal.c -@@ -108,6 +108,8 @@ g_openuri_portal_open_uri (const char *uri, - errsv = errno; - if (fd == -1) - { -+ g_free (path); -+ g_variant_builder_clear (&opt_builder); - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), - "Failed to open '%s'", path); - return FALSE; --- -GitLab - diff --git a/backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch b/backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch deleted file mode 100644 index 8652e45edb88ba559bf257121c3d3eb7e081fb41..0000000000000000000000000000000000000000 --- a/backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch +++ /dev/null @@ -1,47 +0,0 @@ -From a50e605d52534f604776e56fd181ace98b6a0166 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:02:33 +0300 -Subject: [PATCH] gproxyaddressenumerator: Fix string leakage on an invalid - input - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a50e605d52534f604776e56fd181ace98b6a0166 - ---- - gio/gproxyaddressenumerator.c | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/gio/gproxyaddressenumerator.c b/gio/gproxyaddressenumerator.c -index d3de4940c9..654baade57 100644 ---- a/gio/gproxyaddressenumerator.c -+++ b/gio/gproxyaddressenumerator.c -@@ -262,8 +262,12 @@ g_proxy_address_enumerator_next (GSocketAddressEnumerator *enumerator, - } - dest_protocol = g_uri_parse_scheme (priv->dest_uri); - -- g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), -- NULL); -+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)) -+ { -+ g_free (dest_hostname); -+ g_free (dest_protocol); -+ } -+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL); - - inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address); - inetaddr = g_inet_socket_address_get_address (inetsaddr); -@@ -352,6 +356,11 @@ return_result (GTask *task) - } - dest_protocol = g_uri_parse_scheme (priv->dest_uri); - -+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)) -+ { -+ g_free (dest_hostname); -+ g_free (dest_protocol); -+ } - g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address)); - - inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address); --- -GitLab - diff --git a/backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch b/backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..59103df320b95ab016717d9aa1fa48c97525ac1f --- /dev/null +++ b/backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch @@ -0,0 +1,679 @@ +From 879b9cd669f03ecd69f0c6913f06275d9c1973c6 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 23 Jun 2022 10:34:15 +0100 +Subject: [PATCH] gregex: Add G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/879b9cd669f03ecd69f0c6913f06275d9c1973c6 + +--- + gio/gsettingsschema.c | 12 ++-- + glib/gregex.c | 8 +-- + glib/gregex.h | 4 ++ + glib/tests/autoptr.c | 6 +- + glib/tests/regex.c | 143 +++++++++++++++++++++--------------------- + gobject/tests/boxed.c | 4 +- + 6 files changed, 94 insertions(+), 83 deletions(-) + +diff --git a/gio/gsettingsschema.c b/gio/gsettingsschema.c +index 6ac1dfffa0..fb3bb70122 100644 +--- a/gio/gsettingsschema.c ++++ b/gio/gsettingsschema.c +@@ -579,10 +579,14 @@ normalise_whitespace (const gchar *orig) + { + GRegex *s; + +- cleanup[0] = g_regex_new ("^\\s+", 0, 0, 0); +- cleanup[1] = g_regex_new ("\\s+$", 0, 0, 0); +- cleanup[2] = g_regex_new ("\\s+", 0, 0, 0); +- s = g_regex_new ("\\n\\s*\\n+", 0, 0, 0); ++ cleanup[0] = g_regex_new ("^\\s+", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); ++ cleanup[1] = g_regex_new ("\\s+$", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); ++ cleanup[2] = g_regex_new ("\\s+", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); ++ s = g_regex_new ("\\n\\s*\\n+", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); + + g_once_init_leave (&splitter, s); + } +diff --git a/glib/gregex.c b/glib/gregex.c +index 2fa0698911..5254d8d282 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1653,7 +1653,7 @@ g_regex_match_simple (const gchar *pattern, + GRegex *regex; + gboolean result; + +- regex = g_regex_new (pattern, compile_options, 0, NULL); ++ regex = g_regex_new (pattern, compile_options, G_REGEX_MATCH_DEFAULT, NULL); + if (!regex) + return FALSE; + result = g_regex_match_full (regex, string, -1, 0, match_options, NULL, NULL); +@@ -1692,7 +1692,7 @@ g_regex_match_simple (const gchar *pattern, + * GRegex *regex; + * GMatchInfo *match_info; + * +- * regex = g_regex_new ("[A-Z]+", 0, 0, NULL); ++ * regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + * g_regex_match (regex, string, 0, &match_info); + * while (g_match_info_matches (match_info)) + * { +@@ -1768,7 +1768,7 @@ g_regex_match (const GRegex *regex, + * GMatchInfo *match_info; + * GError *error = NULL; + * +- * regex = g_regex_new ("[A-Z]+", 0, 0, NULL); ++ * regex = g_regex_new ("[A-Z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + * g_regex_match_full (regex, string, -1, 0, 0, &match_info, &error); + * while (g_match_info_matches (match_info)) + * { +@@ -2949,7 +2949,7 @@ g_regex_replace_literal (const GRegex *regex, + * g_hash_table_insert (h, "3", "THREE"); + * g_hash_table_insert (h, "4", "FOUR"); + * +- * reg = g_regex_new ("1|2|3|4", 0, 0, NULL); ++ * reg = g_regex_new ("1|2|3|4", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + * res = g_regex_replace_eval (reg, text, -1, 0, 0, eval_cb, h, NULL); + * g_hash_table_destroy (h); + * +diff --git a/glib/gregex.h b/glib/gregex.h +index 89c8485471..3fd61806f7 100644 +--- a/glib/gregex.h ++++ b/glib/gregex.h +@@ -218,6 +218,7 @@ GQuark g_regex_error_quark (void); + + /** + * GRegexCompileFlags: ++ * @G_REGEX_DEFAULT: No special options set. Since: 2.74 + * @G_REGEX_CASELESS: Letters in the pattern match both upper- and + * lowercase letters. This option can be changed within a pattern + * by a "(?i)" option setting. +@@ -297,6 +298,7 @@ GQuark g_regex_error_quark (void); + */ + typedef enum + { ++ G_REGEX_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_REGEX_CASELESS = 1 << 0, + G_REGEX_MULTILINE = 1 << 1, + G_REGEX_DOTALL = 1 << 2, +@@ -319,6 +321,7 @@ typedef enum + + /** + * GRegexMatchFlags: ++ * @G_REGEX_MATCH_DEFAULT: No special options set. Since: 2.74 + * @G_REGEX_MATCH_ANCHORED: The pattern is forced to be "anchored", that is, + * it is constrained to match only at the first matching point in the + * string that is being searched. This effect can also be achieved by +@@ -387,6 +390,7 @@ typedef enum + * adding a new flag. */ + typedef enum + { ++ G_REGEX_MATCH_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_REGEX_MATCH_ANCHORED = 1 << 4, + G_REGEX_MATCH_NOTBOL = 1 << 7, + G_REGEX_MATCH_NOTEOL = 1 << 8, +diff --git a/glib/tests/autoptr.c b/glib/tests/autoptr.c +index 035d3f6133..c5d9877bbe 100644 +--- a/glib/tests/autoptr.c ++++ b/glib/tests/autoptr.c +@@ -296,14 +296,16 @@ test_g_rand (void) + static void + test_g_regex (void) + { +- g_autoptr(GRegex) val = g_regex_new (".*", 0, 0, NULL); ++ g_autoptr(GRegex) val = g_regex_new (".*", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); + g_assert_nonnull (val); + } + + static void + test_g_match_info (void) + { +- g_autoptr(GRegex) regex = g_regex_new (".*", 0, 0, NULL); ++ g_autoptr(GRegex) regex = g_regex_new (".*", G_REGEX_DEFAULT, ++ G_REGEX_MATCH_DEFAULT, NULL); + g_autoptr(GMatchInfo) match = NULL; + + if (!g_regex_match (regex, "hello", 0, &match)) +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index e19f975875..c39d640fa2 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -286,7 +286,7 @@ test_match_next (gconstpointer d) + GSList *matches; + GSList *l_exp, *l_match; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -478,7 +478,7 @@ test_match_count (gconstpointer d) + GMatchInfo *match_info; + gint count; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -515,7 +515,7 @@ test_partial (gconstpointer d) + GRegex *regex; + GMatchInfo *match_info; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -567,7 +567,7 @@ test_sub_pattern (gconstpointer d) + gchar *sub_expr; + gint start = UNTOUCHED, end = UNTOUCHED; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -622,7 +622,7 @@ test_named_sub_pattern (gconstpointer d) + gint start = UNTOUCHED, end = UNTOUCHED; + gchar *sub_expr; + +- regex = g_regex_new (data->pattern, data->flags, 0, NULL); ++ regex = g_regex_new (data->pattern, data->flags, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -694,7 +694,7 @@ test_fetch_all (gconstpointer d) + gint match_count; + gint i; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -788,7 +788,8 @@ test_split_simple (gconstpointer d) + gint token_count; + gint i; + +- tokens = g_regex_split_simple (data->pattern, data->string, 0, 0); ++ tokens = g_regex_split_simple (data->pattern, data->string, ++ G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + if (tokens) + token_count = g_strv_length (tokens); + else +@@ -867,7 +868,7 @@ test_split_full (gconstpointer d) + gint token_count; + gint i; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -901,7 +902,7 @@ test_split (gconstpointer d) + gint token_count; + gint i; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -1057,8 +1058,8 @@ test_expand (gconstpointer d) + + if (data->pattern) + { +- regex = g_regex_new (data->pattern, data->raw ? G_REGEX_RAW : 0, 0, +- &error); ++ regex = g_regex_new (data->pattern, data->raw ? G_REGEX_RAW : 0, ++ G_REGEX_MATCH_DEFAULT, &error); + g_assert_no_error (error); + g_regex_match (regex, data->string, 0, &match_info); + } +@@ -1100,7 +1101,7 @@ test_replace (gconstpointer d) + GRegex *regex; + gchar *res; + +- regex = g_regex_new (data->pattern, 0, 0, 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); + + g_assert_cmpstr (res, ==, data->expected); +@@ -1130,7 +1131,7 @@ test_replace_lit (gconstpointer d) + GRegex *regex; + gchar *res; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + res = g_regex_replace_literal (regex, data->string, -1, data->start_position, + data->replacement, 0, NULL); + g_assert_cmpstr (res, ==, data->expected); +@@ -1166,7 +1167,7 @@ test_get_string_number (gconstpointer d) + GRegex *regex; + gint num; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + num = g_regex_get_string_number (regex, data->name); + + g_assert_cmpint (num, ==, data->expected_num); +@@ -1260,7 +1261,7 @@ test_match_all_full (gconstpointer d) + gint match_count; + gint i; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + match_ok = g_regex_match_all_full (regex, data->string, data->string_len, data->start_position, + 0, &match_info, NULL); + +@@ -1305,7 +1306,7 @@ test_match_all (gconstpointer d) + gboolean match_ok; + guint i, match_count; + +- regex = g_regex_new (data->pattern, 0, 0, NULL); ++ regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + match_ok = g_regex_match_all (regex, data->string, 0, &match_info); + + if (g_slist_length (data->expected) == 0) +@@ -1502,7 +1503,7 @@ test_properties (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "ppPP01", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1523,7 +1524,7 @@ test_class (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "a:b:\340\254\236:\333\253:\316\240", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1569,7 +1570,7 @@ test_lookahead (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "word1 word2: word3;", 0, &match); +@@ -1583,7 +1584,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1598,7 +1599,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1631,7 +1632,7 @@ test_lookbehind (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, 0, &error); ++ regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "Mon Tuesday Wed Saturday", 0, &match); +@@ -1895,7 +1896,7 @@ test_subpattern (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, 0, &error); ++ regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "aaaaaaaaaaaaaaaa", 0, &match); +@@ -1919,7 +1920,7 @@ test_condition (void) + gboolean res; + + error = NULL; +- regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1933,7 +1934,7 @@ test_condition (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1946,7 +1947,7 @@ test_condition (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a[zzzzzz]b", 0, &match); +@@ -2013,7 +2014,7 @@ test_recursion (void) + gint start; + + error = NULL; +- regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "(middle)", 0, &match); +@@ -2030,7 +2031,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match); +@@ -2043,7 +2044,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + g_regex_match (regex, "(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()", 0, &match); +@@ -2052,7 +2053,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, ">>>", 0, &match); +@@ -2071,7 +2072,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2084,7 +2085,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, 0, &error); ++ regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2097,7 +2098,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, 0, &error); ++ regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2124,7 +2125,7 @@ test_multiline (void) + + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=640489"); + +- regex = g_regex_new ("^a$", G_REGEX_MULTILINE|G_REGEX_DOTALL, 0, NULL); ++ regex = g_regex_new ("^a$", G_REGEX_MULTILINE|G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT, NULL); + + count = 0; + g_regex_match (regex, "a\nb\na", 0, &info); +@@ -2144,7 +2145,7 @@ test_explicit_crlf (void) + { + GRegex *regex; + +- regex = g_regex_new ("[\r\n]a", 0, 0, NULL); ++ regex = g_regex_new ("[\r\n]a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + g_assert_cmpint (g_regex_get_has_cr_or_lf (regex), ==, TRUE); + g_regex_unref (regex); + } +@@ -2154,15 +2155,15 @@ test_max_lookbehind (void) + { + GRegex *regex; + +- regex = g_regex_new ("abc", 0, 0, NULL); ++ regex = g_regex_new ("abc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 0); + g_regex_unref (regex); + +- regex = g_regex_new ("\\babc", 0, 0, NULL); ++ regex = g_regex_new ("\\babc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 1); + g_regex_unref (regex); + +- regex = g_regex_new ("(?<=123)abc", 0, 0, NULL); ++ regex = g_regex_new ("(?<=123)abc", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + g_assert_cmpint (g_regex_get_max_lookbehind (regex), ==, 3); + g_regex_unref (regex); + } +@@ -2205,25 +2206,25 @@ main (int argc, char *argv[]) + + /* 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); +- TEST_NEW("", 0, 0); +- TEST_NEW(".*", 0, 0); +- TEST_NEW(".*", G_REGEX_OPTIMIZE, 0); +- TEST_NEW(".*", G_REGEX_MULTILINE, 0); +- TEST_NEW(".*", G_REGEX_DOTALL, 0); ++ TEST_NEW("", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW(".*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW(".*", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW(".*", G_REGEX_MULTILINE, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL); +- TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", 0, 0); +- TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, 0); +- TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0); +- TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, 0); +- TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, 0); ++ TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); + /* This gives "internal error: code overflow" with pcre 6.0 */ +- TEST_NEW("(?i)(?-i)", 0, 0); +- TEST_NEW ("(?i)a", 0, 0); +- TEST_NEW ("(?m)a", 0, 0); +- TEST_NEW ("(?s)a", 0, 0); +- TEST_NEW ("(?x)a", 0, 0); +- TEST_NEW ("(?J)a", 0, 0); +- TEST_NEW ("(?U)[a-z]+", 0, 0); ++ TEST_NEW("(?i)(?-i)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?i)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?m)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?s)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?x)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?J)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++ TEST_NEW ("(?U)[a-z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + + /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */ + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0); +diff --git a/gobject/tests/boxed.c b/gobject/tests/boxed.c +index c2d091c54a..dd45a80a34 100644 +--- a/gobject/tests/boxed.c ++++ b/gobject/tests/boxed.c +@@ -281,7 +281,7 @@ test_boxed_regex (void) + g_value_init (&value, G_TYPE_REGEX); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + +- v = g_regex_new ("a+b+", 0, 0, NULL); ++ v = g_regex_new ("a+b+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + g_value_take_boxed (&value, v); + + v2 = g_value_get_boxed (&value); +@@ -305,7 +305,7 @@ test_boxed_matchinfo (void) + g_value_init (&value, G_TYPE_MATCH_INFO); + g_assert (G_VALUE_HOLDS_BOXED (&value)); + +- r = g_regex_new ("ab", 0, 0, NULL); ++ r = g_regex_new ("ab", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); + ret = g_regex_match (r, "blabla abab bla", 0, &info); + g_assert (ret); + g_value_take_boxed (&value, info); +-- +GitLab + diff --git a/backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch b/backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch new file mode 100644 index 0000000000000000000000000000000000000000..0164d75b8ee401d039d05161d323d1963f59e784 --- /dev/null +++ b/backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch @@ -0,0 +1,47 @@ +From aee84cb45caf42e336dee5183d561b89eb44f8f3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch b/backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbc510f6a83ababeea00fe1ba6747fa39b7fb58b --- /dev/null +++ b/backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch @@ -0,0 +1,56 @@ +From 1f88976610d5bcc15ad58c9345848d736d64fd55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch b/backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1dd7801acf3ae30ae6998eb6708d31ef8a3d5b0 --- /dev/null +++ b/backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch @@ -0,0 +1,50 @@ +From 13ad4296ea8ba66f5620288b2fd06315852e73ae Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch b/backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch new file mode 100644 index 0000000000000000000000000000000000000000..d194bf1f1d0c6826ef353ab89078c6bad1bb6257 --- /dev/null +++ b/backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch @@ -0,0 +1,36 @@ +From 6c93ac876f71d7221a172e430ca450b6c0b8b699 Mon Sep 17 00:00:00 2001 +From: Marco Trevisan +Date: Wed, 20 Jul 2022 06:32:30 +0200 +Subject: [PATCH] gregex: Free match info if offset matching recalc failed + +It's not probably ever happening in practice, but coverity found it and +it's easy enough to fix it. + +Coverity CID: #1490730 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6c93ac876f71d7221a172e430ca450b6c0b8b699 + +--- + glib/gregex.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 5fc7b16bc8..be03f0e094 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -2237,7 +2237,10 @@ g_regex_match_all_full (const GRegex *regex, + info->workspace, info->n_workspace); + + if (!recalc_match_offsets (info, error)) +- return FALSE; ++ { ++ g_match_info_free (info); ++ return FALSE; ++ } + + if (info->matches == PCRE2_ERROR_DFA_WSSIZE) + { +-- +GitLab + diff --git a/backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch b/backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch new file mode 100644 index 0000000000000000000000000000000000000000..f9d340ea8d6b3d842aa734b2b835641d6be0eb1f --- /dev/null +++ b/backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch @@ -0,0 +1,51 @@ +From 11521972f4d345d9a3f68df719f5980085197e47 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch b/backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch new file mode 100644 index 0000000000000000000000000000000000000000..f0e86e93b19f1e3aebe36e348220f68a0a25dd3d --- /dev/null +++ b/backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch @@ -0,0 +1,27 @@ +From 1185a1304a88319b58359105f2c1038ae4d7edce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-gregex-add-original-test-case.patch b/backport-gregex-add-original-test-case.patch new file mode 100644 index 0000000000000000000000000000000000000000..52028482596c50e1de4f537b19afa400ac11cbd6 --- /dev/null +++ b/backport-gregex-add-original-test-case.patch @@ -0,0 +1,27 @@ +From a2b5b9e906256f43b0bac702424613ea0e7ddcb0 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 25 Jul 2022 16:57:06 +0200 +Subject: [PATCH] gregex: add original test case for issue #2700 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a2b5b9e906256f43b0bac702424613ea0e7ddcb0 + +--- + glib/tests/regex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 5839465fae..acb082b704 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -2495,6 +2495,7 @@ main (int argc, char *argv[]) + + /* see https://gitlab.gnome.org/GNOME/glib/-/issues/2700 */ + TEST_MATCH("(\n.+)+", G_REGEX_DEFAULT, 0, "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", -1, 0, 0, TRUE); ++ TEST_MATCH("\n([\\-\\.a-zA-Z]+[\\-\\.0-9]*) +connected ([^(\n ]*)[^\n]*((\n +[0-9]+x[0-9]+[^\n]+)+)", G_REGEX_DEFAULT, 0, "Screen 0: minimum 1 x 1, current 3840 x 1080, maximum 8192 x 8192\nVirtual1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual2 connected 1920x1080+1920+0 (normal left inverted right x axis y axis) 0mm x 0mm\n 1920x1080 60.00*+ 59.96 \n 3840x2400 59.97 \n 3840x2160 59.97 \n 2880x1800 59.95 \n 2560x1600 59.99 \n 2560x1440 59.95 \n 1920x1440 60.00 \n 1856x1392 60.00 \n 1792x1344 60.00 \n 1920x1200 59.88 \n 1600x1200 60.00 \n 1680x1050 59.95 \n 1400x1050 59.98 \n 1280x1024 60.02 \n 1440x900 59.89 \n 1280x960 60.00 \n 1360x768 60.02 \n 1280x800 59.81 \n 1152x864 75.00 \n 1280x768 59.87 \n 1280x720 59.86 \n 1024x768 60.00 \n 800x600 60.32 \n 640x480 59.94 \nVirtual3 disconnected (normal left inverted right x axis y axis)\nVirtual4 disconnected (normal left inverted right x axis y axis)\nVirtual5 disconnected (normal left inverted right x axis y axis)\nVirtual6 disconnected (normal left inverted right x axis y axis)\nVirtual7 disconnected (normal left inverted right x axis y axis)\nVirtual8 disconnected (normal left inverted right x axis y axis)\n", -1, 0, 0, TRUE); + + /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */ + TEST_MATCH_NEXT0("a", "x", -1, 0); +-- +GitLab + diff --git a/backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch b/backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch new file mode 100644 index 0000000000000000000000000000000000000000..b5ac211e4ddc36538d34dc20b6031ecfb358d120 --- /dev/null +++ b/backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch @@ -0,0 +1,49 @@ +From 6535c77b00a444750148d9d658e4d47214bb4562 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 25 Jul 2022 16:48:03 +0200 +Subject: [PATCH] gregex: do not set match and recursion limits on match + context + +These are not really necessary, and cause breakages (e.g. #2700). +pcre2_set_recursion_limit is also deprecated. + +Fixes: #2700 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6535c77b00a444750148d9d658e4d47214bb4562 + +--- + glib/gregex.c | 2 -- + glib/tests/regex.c | 3 +++ + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 6741d2479f..dd61dc4813 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -769,8 +769,6 @@ match_info_new (const GRegex *regex, + &match_info->n_subpatterns); + + match_info->match_context = pcre2_match_context_create (NULL); +- pcre2_set_match_limit (match_info->match_context, 65536); /* should be plenty */ +- pcre2_set_recursion_limit (match_info->match_context, 64); /* should be plenty */ + + if (is_dfa) + { +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index bb1a5ff762..5839465fae 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -2493,6 +2493,9 @@ main (int argc, char *argv[]) + TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "dž", -1, 0, 0, TRUE); + TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "Dž", -1, 0, 0, TRUE); + ++ /* see https://gitlab.gnome.org/GNOME/glib/-/issues/2700 */ ++ TEST_MATCH("(\n.+)+", G_REGEX_DEFAULT, 0, "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", -1, 0, 0, TRUE); ++ + /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */ + TEST_MATCH_NEXT0("a", "x", -1, 0); + TEST_MATCH_NEXT0("a", "ax", -1, 1); +-- +GitLab + diff --git a/backport-gregex-ensure-we-translate-the-errcode.patch b/backport-gregex-ensure-we-translate-the-errcode.patch new file mode 100644 index 0000000000000000000000000000000000000000..530cdb3d82d96422afc628750b758cfaf77a7473 --- /dev/null +++ b/backport-gregex-ensure-we-translate-the-errcode.patch @@ -0,0 +1,85 @@ +From c05d09044fb71bdea599c81bf0ae896a5503e76a Mon Sep 17 00:00:00 2001 +From: Marco Trevisan +Date: Fri, 15 Jul 2022 01:27:33 +0200 +Subject: [PATCH] gregex: Ensure we translate the errcode without asserting on + G_REGEX_ERROR_COMPILE + +Since commit 8d5a44dc in order to ensure that we were setting the errcode in +translate_compile_error(), we did an assert checking whether it was a +valid value, but we assumed that 0 was not a valid error, while it is as +it's the generic G_REGEX_ERROR_COMPILE. + +So, set errcode and errmsg to invalid values before translating and +ensure we've change them. + +Fixes: #2694 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c05d09044fb71bdea599c81bf0ae896a5503e76a + +--- + glib/gregex.c | 8 ++++++-- + glib/tests/regex.c | 13 +++++++++++++ + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 5fc7b16bc8..2a54929bf4 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -476,8 +476,12 @@ translate_compile_error (gint *errcode, const gchar **errmsg) + * Note that there can be more PCRE errors with the same GRegexError + * and that some PCRE errors are useless for us. + */ ++ gint original_errcode = *errcode; + +- switch (*errcode) ++ *errcode = -1; ++ *errmsg = NULL; ++ ++ switch (original_errcode) + { + case PCRE2_ERROR_END_BACKSLASH: + *errcode = G_REGEX_ERROR_STRAY_BACKSLASH; +@@ -725,7 +729,7 @@ translate_compile_error (gint *errcode, const gchar **errmsg) + break; + } + +- g_assert (*errcode != 0); ++ g_assert (*errcode != -1); + g_assert (*errmsg != NULL); + } + +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 3355f64e54..9a1977b248 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -2187,6 +2187,18 @@ pcre2_ge (guint64 major, guint64 minor) + return (pcre2_major > major) || (pcre2_major == major && pcre2_minor >= minor); + } + ++static void ++test_compile_errors (void) ++{ ++ GRegex *regex; ++ GError *error = NULL; ++ ++ regex = g_regex_new ("\\o{999}", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ g_assert_null (regex); ++ g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE); ++ g_clear_error (&error); ++} ++ + int + main (int argc, char *argv[]) + { +@@ -2204,6 +2216,7 @@ main (int argc, char *argv[]) + g_test_add_func ("/regex/multiline", test_multiline); + 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); + + /* TEST_NEW(pattern, compile_opts, match_opts) */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS +-- +GitLab + diff --git a/backport-gregex-format-specifier-for-localized-error-message.patch b/backport-gregex-format-specifier-for-localized-error-message.patch new file mode 100644 index 0000000000000000000000000000000000000000..02ce7a72d5e4adfb98ece8a94079121f11195c96 --- /dev/null +++ b/backport-gregex-format-specifier-for-localized-error-message.patch @@ -0,0 +1,44 @@ +From 5cd94a0982e4a910ee33ec58f7678429ec067b6f Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Thu, 14 Jul 2022 13:14:31 +0000 +Subject: [PATCH] gregex: use %s format specifier for localized error message + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5cd94a0982e4a910ee33ec58f7678429ec067b6f + +--- + glib/gregex.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 55672249cb..5fc7b16bc8 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1661,6 +1661,7 @@ regex_compile (const gchar *pattern, + if (re == NULL) + { + GError *tmp_error; ++ gchar *offset_str; + + /* Translate the PCRE error code to GRegexError and use a translated + * error message if possible */ +@@ -1669,11 +1670,13 @@ regex_compile (const gchar *pattern, + /* PCRE uses byte offsets but we want to show character offsets */ + erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]); + ++ offset_str = g_strdup_printf ("%" G_GSIZE_FORMAT, erroffset); + tmp_error = g_error_new (G_REGEX_ERROR, errcode, +- _("Error while compiling regular " +- "expression %s at char %" G_GSIZE_FORMAT ": %s"), +- pattern, erroffset, errmsg); ++ _("Error while compiling regular expression ‘%s’ " ++ "at char %s: %s"), ++ pattern, offset_str, errmsg); + g_propagate_error (error, tmp_error); ++ g_free (offset_str); + + return NULL; + } +-- +GitLab + diff --git a/backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch b/backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch new file mode 100644 index 0000000000000000000000000000000000000000..54bb85216eeddc0569450b160cebb2ee9e3a5611 --- /dev/null +++ b/backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch @@ -0,0 +1,678 @@ +From bcd8cb3e142bf7f1c92583aa81c34fe8ff8521c0 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Wed, 20 Jul 2022 20:48:17 +0000 +Subject: [PATCH] gregex: use G_REGEX_OPTIMIZE flag to enable JIT compilation + +Since we ported gregex to pcre2, the JIT compiler is now available to be +used. Let's undeprecate G_REGEX_OPTIMIZE flag to control whether the JIT +compilation is requested, since using JIT is itself an optimization. +See [1] for details on its implementation in pcre2. + +[1] http://pcre.org/current/doc/html/pcre2jit.html + +Fixes: #566 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/bcd8cb3e142bf7f1c92583aa81c34fe8ff8521c0 + +--- + glib/gregex.c | 104 ++++++++++++++++++++++++++++++------ + glib/gregex.h | 14 ++--- + glib/tests/regex.c | 128 ++++++++++++++++++++++++--------------------- + 3 files changed, 164 insertions(+), 82 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index b0edacc0d3..cf9ce23e8d 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -144,7 +144,6 @@ + PCRE2_NOTBOL | \ + PCRE2_NOTEOL | \ + PCRE2_NOTEMPTY | \ +- PCRE2_PARTIAL_SOFT | \ + PCRE2_NEWLINE_CR | \ + PCRE2_NEWLINE_LF | \ + PCRE2_NEWLINE_CRLF | \ +@@ -195,6 +194,13 @@ struct _GMatchInfo + pcre2_match_data *match_data; + }; + ++typedef enum ++{ ++ JIT_STATUS_DEFAULT, ++ JIT_STATUS_ENABLED, ++ JIT_STATUS_DISABLED ++} JITStatus; ++ + struct _GRegex + { + gint ref_count; /* the ref count for the immutable part (atomic) */ +@@ -203,6 +209,8 @@ struct _GRegex + GRegexCompileFlags compile_opts; /* options used at compile time on the pattern, pcre2 values */ + GRegexCompileFlags orig_compile_opts; /* options used at compile time on the pattern, gregex values */ + GRegexMatchFlags match_opts; /* options used at match time on the regex */ ++ gint jit_options; /* options which were enabled for jit compiler */ ++ JITStatus jit_status; /* indicates the status of jit compiler for this compiled regex */ + }; + + /* TRUE if ret is an error code, FALSE otherwise. */ +@@ -262,10 +270,11 @@ map_to_pcre2_compile_flags (gint pcre1_flags) + if (pcre1_flags & G_REGEX_BSR_ANYCRLF) + pcre2_flags |= PCRE2_BSR_ANYCRLF; + +- /* these are not available in pcre2 */ +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS ++ /* these are not available in pcre2, but we use G_REGEX_OPTIMIZE as a special ++ * case to request JIT compilation */ + if (pcre1_flags & G_REGEX_OPTIMIZE) + pcre2_flags |= 0; ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + if (pcre1_flags & G_REGEX_JAVASCRIPT_COMPAT) + pcre2_flags |= 0; + G_GNUC_END_IGNORE_DEPRECATIONS +@@ -291,8 +300,6 @@ map_to_pcre2_match_flags (gint pcre1_flags) + pcre2_flags |= PCRE2_NOTEOL; + if (pcre1_flags & G_REGEX_MATCH_NOTEMPTY) + pcre2_flags |= PCRE2_NOTEMPTY; +- if (pcre1_flags & G_REGEX_MATCH_PARTIAL) +- pcre2_flags |= PCRE2_PARTIAL_SOFT; + if (pcre1_flags & G_REGEX_MATCH_NEWLINE_CR) + pcre2_flags |= PCRE2_NEWLINE_CR; + if (pcre1_flags & G_REGEX_MATCH_NEWLINE_LF) +@@ -385,8 +392,6 @@ map_to_pcre1_match_flags (gint pcre2_flags) + pcre1_flags |= G_REGEX_MATCH_NOTEOL; + if (pcre2_flags & PCRE2_NOTEMPTY) + pcre1_flags |= G_REGEX_MATCH_NOTEMPTY; +- if (pcre2_flags & PCRE2_PARTIAL_SOFT) +- pcre1_flags |= G_REGEX_MATCH_PARTIAL; + if (pcre2_flags & PCRE2_NEWLINE_CR) + pcre1_flags |= G_REGEX_MATCH_NEWLINE_CR; + if (pcre2_flags & PCRE2_NEWLINE_LF) +@@ -461,6 +466,9 @@ match_error (gint errcode) + return _("bad offset"); + case PCRE2_ERROR_RECURSELOOP: + return _("recursion loop"); ++ case PCRE2_ERROR_JIT_BADOPTION: ++ /* should not happen in GRegex since we check modes before each match */ ++ return _("matching mode is requested that was not compiled for JIT"); + default: + break; + } +@@ -817,6 +825,56 @@ recalc_match_offsets (GMatchInfo *match_info, + return TRUE; + } + ++static void ++enable_jit_with_match_options (GRegex *regex, ++ GRegexMatchFlags match_options) ++{ ++ gint old_jit_options, new_jit_options, retval; ++ ++ if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE)) ++ return; ++ if (regex->jit_status == JIT_STATUS_DISABLED) ++ return; ++ ++ old_jit_options = regex->jit_options; ++ new_jit_options = old_jit_options | PCRE2_JIT_COMPLETE; ++ if (match_options & PCRE2_PARTIAL_HARD) ++ new_jit_options |= PCRE2_JIT_PARTIAL_HARD; ++ if (match_options & PCRE2_PARTIAL_SOFT) ++ new_jit_options |= PCRE2_JIT_PARTIAL_SOFT; ++ ++ /* no new options enabled */ ++ if (new_jit_options == old_jit_options) ++ return; ++ ++ 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; ++ case PCRE2_ERROR_NOMEMORY: ++ g_warning ("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; ++ case PCRE2_ERROR_JIT_BADOPTION: ++ g_warning ("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; ++ break; ++ default: ++ g_warning ("JIT compilation was requested with G_REGEX_OPTIMIZE, " ++ "but request for JIT support had unexpectedly failed. " ++ "Falling back to interpretive code."); ++ regex->jit_status = JIT_STATUS_DISABLED; ++ break; ++ } ++} ++ + /** + * g_match_info_get_regex: + * @match_info: a #GMatchInfo +@@ -956,13 +1014,28 @@ g_match_info_next (GMatchInfo *match_info, + } + + opts = map_to_pcre2_match_flags (match_info->regex->match_opts | match_info->match_opts); +- match_info->matches = pcre2_match (match_info->regex->pcre_re, +- (PCRE2_SPTR8) match_info->string, +- match_info->string_len, +- match_info->pos, +- opts & ~G_REGEX_FLAGS_CONVERTED, +- match_info->match_data, +- match_info->match_context); ++ ++ enable_jit_with_match_options (match_info->regex, opts); ++ if (match_info->regex->jit_status == JIT_STATUS_ENABLED) ++ { ++ match_info->matches = pcre2_jit_match (match_info->regex->pcre_re, ++ (PCRE2_SPTR8) match_info->string, ++ match_info->string_len, ++ match_info->pos, ++ opts & ~G_REGEX_FLAGS_CONVERTED, ++ match_info->match_data, ++ match_info->match_context); ++ } ++ else ++ { ++ match_info->matches = pcre2_match (match_info->regex->pcre_re, ++ (PCRE2_SPTR8) match_info->string, ++ match_info->string_len, ++ match_info->pos, ++ opts & ~G_REGEX_FLAGS_CONVERTED, ++ match_info->match_data, ++ match_info->match_context); ++ } + + if (IS_PCRE2_ERROR (match_info->matches)) + { +@@ -1582,6 +1655,7 @@ g_regex_new (const gchar *pattern, + regex->compile_opts = compile_options; + regex->orig_compile_opts = orig_compile_opts; + regex->match_opts = match_options; ++ enable_jit_with_match_options (regex, regex->match_opts); + + return regex; + } +@@ -1836,10 +1910,8 @@ g_regex_get_compile_flags (const GRegex *regex) + + g_return_val_if_fail (regex != NULL, 0); + +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + /* Preserve original G_REGEX_OPTIMIZE */ + extra_flags = (regex->orig_compile_opts & G_REGEX_OPTIMIZE); +-G_GNUC_END_IGNORE_DEPRECATIONS + + /* Also include the newline options */ + pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_NEWLINE, &info_value); +diff --git a/glib/gregex.h b/glib/gregex.h +index 7010d52ab8..30eb387073 100644 +--- a/glib/gregex.h ++++ b/glib/gregex.h +@@ -262,11 +262,13 @@ GQuark g_regex_error_quark (void); + * followed by "?" behaves as if it were followed by "?:" but named + * parentheses can still be used for capturing (and they acquire numbers + * in the usual way). +- * @G_REGEX_OPTIMIZE: Optimize the regular expression. If the pattern will +- * be used many times, then it may be worth the effort to optimize it +- * to improve the speed of matches. Deprecated in GLib 2.74 which now uses +- * libpcre2, which doesn’t require separate optimization of queries. This +- * option is now a no-op. Deprecated: 2.74 ++ * @G_REGEX_OPTIMIZE: Since 2.74 and the port to pcre2, requests JIT ++ * compilation, which, if the just-in-time compiler is available, further ++ * processes a compiled pattern into machine code that executes much ++ * faster. However, it comes at the cost of extra processing before the ++ * match is performed, so it is most beneficial to use this when the same ++ * compiled pattern is used for matching many times. Before 2.74 this ++ * option used the built-in non-JIT optimizations in pcre1. + * @G_REGEX_FIRSTLINE: Limits an unanchored pattern to match before (or at) the + * first newline. Since: 2.34 + * @G_REGEX_DUPNAMES: Names used to identify capturing subpatterns need not +@@ -311,7 +313,7 @@ typedef enum + G_REGEX_UNGREEDY = 1 << 9, + G_REGEX_RAW = 1 << 11, + G_REGEX_NO_AUTO_CAPTURE = 1 << 12, +- G_REGEX_OPTIMIZE GLIB_DEPRECATED_ENUMERATOR_IN_2_74 = 1 << 13, ++ G_REGEX_OPTIMIZE = 1 << 13, + G_REGEX_FIRSTLINE = 1 << 18, + G_REGEX_DUPNAMES = 1 << 19, + G_REGEX_NEWLINE_CR = 1 << 20, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 9a1977b248..bb1a5ff762 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -516,7 +516,7 @@ test_partial (gconstpointer d) + GRegex *regex; + GMatchInfo *match_info; + +- regex = g_regex_new (data->pattern, G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, NULL); ++ regex = g_regex_new (data->pattern, data->compile_opts, G_REGEX_MATCH_DEFAULT, NULL); + + g_assert (regex != NULL); + +@@ -534,12 +534,13 @@ test_partial (gconstpointer d) + g_regex_unref (regex); + } + +-#define TEST_PARTIAL_FULL(_pattern, _string, _match_opts, _expected) { \ ++#define TEST_PARTIAL_FULL(_pattern, _string, _compile_opts, _match_opts, _expected) { \ + TestMatchData *data; \ + gchar *path; \ + data = g_new0 (TestMatchData, 1); \ + data->pattern = _pattern; \ + data->string = _string; \ ++ data->compile_opts = _compile_opts; \ + data->match_opts = _match_opts; \ + data->expected = _expected; \ + path = g_strdup_printf ("/regex/match/partial/%d", ++total); \ +@@ -547,7 +548,7 @@ test_partial (gconstpointer d) + g_free (path); \ + } + +-#define TEST_PARTIAL(_pattern, _string, _expected) TEST_PARTIAL_FULL(_pattern, _string, G_REGEX_MATCH_PARTIAL, _expected) ++#define TEST_PARTIAL(_pattern, _string, _compile_opts, _expected) TEST_PARTIAL_FULL(_pattern, _string, _compile_opts, G_REGEX_MATCH_PARTIAL, _expected) + + typedef struct { + const gchar *pattern; +@@ -1504,7 +1505,7 @@ test_properties (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "ppPP01", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1525,7 +1526,7 @@ test_class (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "a:b:\340\254\236:\333\253:\316\240", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1571,7 +1572,7 @@ test_lookahead (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("\\w+(?=;)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "word1 word2: word3;", 0, &match); +@@ -1585,7 +1586,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("foo(?!bar)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1600,7 +1601,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("(?!bar)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1633,7 +1634,7 @@ test_lookbehind (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "Mon Tuesday Wed Saturday", 0, &match); +@@ -1897,7 +1898,7 @@ test_subpattern (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "aaaaaaaaaaaaaaaa", 0, &match); +@@ -1921,7 +1922,7 @@ test_condition (void) + gboolean res; + + error = NULL; +- regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1935,7 +1936,7 @@ test_condition (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1948,7 +1949,7 @@ test_condition (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a[zzzzzz]b", 0, &match); +@@ -1963,7 +1964,7 @@ test_condition (void) + + regex = g_regex_new ("(?(DEFINE) (? 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) )" + "\\b (?&byte) (\\.(?&byte)){3} \\b", +- G_REGEX_EXTENDED, 0, &error); ++ G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "128.0.0.1", 0, &match); +@@ -1982,7 +1983,7 @@ test_condition (void) + + regex = g_regex_new ("^(?(?=[^a-z]*[a-z])" + "\\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )$", +- G_REGEX_EXTENDED, 0, &error); ++ G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "01-abc-24", 0, &match); +@@ -2015,7 +2016,7 @@ test_recursion (void) + gint start; + + error = NULL; +- regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "(middle)", 0, &match); +@@ -2032,7 +2033,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match); +@@ -2045,7 +2046,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + g_regex_match (regex, "(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()", 0, &match); +@@ -2054,7 +2055,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, ">>>", 0, &match); +@@ -2073,7 +2074,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2086,7 +2087,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2099,7 +2100,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2219,26 +2220,18 @@ main (int argc, char *argv[]) + g_test_add_func ("/regex/compile-errors", test_compile_errors); + + /* TEST_NEW(pattern, compile_opts, match_opts) */ +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("[A-Z]+", G_REGEX_CASELESS | G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTBOL | G_REGEX_MATCH_PARTIAL); +-G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW("", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW(".*", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); +-G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW(".*", G_REGEX_MULTILINE, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT); +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); +-G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT); +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); +-G_GNUC_END_IGNORE_DEPRECATIONS + /* This gives "internal error: code overflow" with pcre 6.0 */ + TEST_NEW("(?i)(?-i)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW ("(?i)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); +@@ -2249,9 +2242,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW ("(?U)[a-z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + + /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */ +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0); +-G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_RAW, 0, G_REGEX_RAW, 0); + TEST_NEW_CHECK_FLAGS ("^.*", 0, 0, G_REGEX_ANCHORED, 0); + TEST_NEW_CHECK_FLAGS ("(*UTF8)a", 0, 0, 0 /* this is the default in GRegex */, 0); +@@ -2540,18 +2531,35 @@ G_GNUC_END_IGNORE_DEPRECATIONS + TEST_MATCH_COUNT("(a)?(b)", "b", 0, 0, 3); + TEST_MATCH_COUNT("(a)?(b)", "ab", 0, 0, 3); + +- /* TEST_PARTIAL(pattern, string, expected) */ +- TEST_PARTIAL("^ab", "a", TRUE); +- TEST_PARTIAL("^ab", "xa", FALSE); +- TEST_PARTIAL("ab", "xa", TRUE); +- TEST_PARTIAL("ab", "ab", FALSE); /* normal match. */ +- TEST_PARTIAL("a+b", "aa", TRUE); +- TEST_PARTIAL("(a)+b", "aa", TRUE); +- TEST_PARTIAL("a?b", "a", TRUE); +- +- /* Test soft vs. hard partial matching */ +- TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_MATCH_PARTIAL_SOFT, FALSE); +- TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_MATCH_PARTIAL_HARD, TRUE); ++ /* TEST_PARTIAL(pattern, string, expected), no JIT */ ++ TEST_PARTIAL("^ab", "a", G_REGEX_DEFAULT, TRUE); ++ TEST_PARTIAL("^ab", "xa", G_REGEX_DEFAULT, FALSE); ++ TEST_PARTIAL("ab", "xa", G_REGEX_DEFAULT, TRUE); ++ TEST_PARTIAL("ab", "ab", G_REGEX_DEFAULT, FALSE); /* normal match. */ ++ TEST_PARTIAL("a+b", "aa", G_REGEX_DEFAULT, TRUE); ++ TEST_PARTIAL("(a)+b", "aa", G_REGEX_DEFAULT, TRUE); ++ TEST_PARTIAL("a?b", "a", G_REGEX_DEFAULT, TRUE); ++ ++ /* TEST_PARTIAL(pattern, string, expected) with JIT */ ++ TEST_PARTIAL("^ab", "a", G_REGEX_OPTIMIZE, TRUE); ++ TEST_PARTIAL("^ab", "xa", G_REGEX_OPTIMIZE, FALSE); ++ TEST_PARTIAL("ab", "xa", G_REGEX_OPTIMIZE, TRUE); ++ TEST_PARTIAL("ab", "ab", G_REGEX_OPTIMIZE, FALSE); /* normal match. */ ++ TEST_PARTIAL("a+b", "aa", G_REGEX_OPTIMIZE, TRUE); ++ TEST_PARTIAL("(a)+b", "aa", G_REGEX_OPTIMIZE, TRUE); ++ TEST_PARTIAL("a?b", "a", G_REGEX_OPTIMIZE, TRUE); ++ ++ /* Test soft vs. hard partial matching, no JIT */ ++ TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_SOFT, FALSE); ++ TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_HARD, TRUE); ++ TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_SOFT, FALSE); ++ TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_DEFAULT, G_REGEX_MATCH_PARTIAL_HARD, TRUE); ++ ++ /* Test soft vs. hard partial matching with JIT */ ++ TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_SOFT, FALSE); ++ TEST_PARTIAL_FULL("cat(fish)?", "cat", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_HARD, TRUE); ++ TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_SOFT, FALSE); ++ TEST_PARTIAL_FULL("ab+", "ab", G_REGEX_OPTIMIZE, G_REGEX_MATCH_PARTIAL_HARD, TRUE); + + /* TEST_SUB_PATTERN(pattern, string, start_position, sub_n, expected_sub, + * expected_start, expected_end) */ +-- +GitLab + diff --git a/backport-gregex-use-correct-size-for-pcre2_pattern_info.patch b/backport-gregex-use-correct-size-for-pcre2_pattern_info.patch new file mode 100644 index 0000000000000000000000000000000000000000..0f9d0ef0b171c7995d894689b8030e792900428a --- /dev/null +++ b/backport-gregex-use-correct-size-for-pcre2_pattern_info.patch @@ -0,0 +1,35 @@ +From 710ccee65c010e4548ded487cdc191658f6a1f35 Mon Sep 17 00:00:00 2001 +From: Mamoru TASAKA +Date: Tue, 26 Jul 2022 21:51:45 +0900 +Subject: [PATCH] gregex: use correct size for pcre2_pattern_info + +man pcre2_pattern_info says that the 3rd argument must +point to uint32_t variable (except for some 2nd argument value), +so correctly use it. Especially using wrong size can cause +unexpected result on big endian. + +closes: #2699 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/710ccee65c010e4548ded487cdc191658f6a1f35 + +--- + glib/gregex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index dd61dc4813..08c43ef4b5 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1701,7 +1701,7 @@ regex_compile (const gchar *pattern, + PCRE2_SIZE erroffset; + gint errcode; + GRegexCompileFlags nonpcre_compile_options; +- unsigned long int pcre_compile_options; ++ uint32_t pcre_compile_options; + + nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK; + +-- +GitLab + diff --git a/backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-not-available.patch b/backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-not-available.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d812e049fd737df71cb1cb1ca7465e5b205c964 --- /dev/null +++ b/backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-not-available.patch @@ -0,0 +1,55 @@ +From 2c2e059cd354a9020ce9188e58e3ab0683008d08 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Fri, 22 Jul 2022 20:27:04 +0200 +Subject: [PATCH] gregex: use g_debug instead of g_warning in case JIT is not + available + +In case JIT is not available in pcre2 we printed warning about it. This +warning broke tests on systems which don't have JIT support in pcre2 +(e.g. macos). + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/2c2e059cd354a9020ce9188e58e3ab0683008d08 + +--- + glib/gregex.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index cf9ce23e8d..6741d2479f 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -855,21 +855,21 @@ enable_jit_with_match_options (GRegex *regex, + regex->jit_options = new_jit_options; + break; + case PCRE2_ERROR_NOMEMORY: +- g_warning ("JIT compilation was requested with G_REGEX_OPTIMIZE, " +- "but JIT was unable to allocate executable memory for the " +- "compiler. Falling back to interpretive code."); ++ 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; + case PCRE2_ERROR_JIT_BADOPTION: +- g_warning ("JIT compilation was requested with G_REGEX_OPTIMIZE, " +- "but JIT support is not available. Falling back to " +- "interpretive code."); ++ 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; + break; + default: +- g_warning ("JIT compilation was requested with G_REGEX_OPTIMIZE, " +- "but request for JIT support had unexpectedly failed. " +- "Falling back to interpretive code."); ++ g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, " ++ "but request for JIT support had unexpectedly failed. " ++ "Falling back to interpretive code."); + regex->jit_status = JIT_STATUS_DISABLED; + break; + } +-- +GitLab + diff --git a/backport-gsignal-Add-G_CONNECT_DEFAULT.patch b/backport-gsignal-Add-G_CONNECT_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..8dfc89241b834327ada1e9c8ba7c28c48f14f1f0 --- /dev/null +++ b/backport-gsignal-Add-G_CONNECT_DEFAULT.patch @@ -0,0 +1,211 @@ +From 7045260c226e409530e4f961f613f8c7d6f6725a Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 23 Jun 2022 09:41:21 +0100 +Subject: [PATCH] gsignal: Add G_CONNECT_DEFAULT + +This makes calls to g_signal_connect_data() and g_signal_connect_object() +with default flags more self-documenting. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7045260c226e409530e4f961f613f8c7d6f6725a + +--- + gio/gcancellable.c | 2 +- + gio/gdbusobjectmanagerclient.c | 4 ++-- + gio/gdbusserver.c | 2 +- + gio/glocalfilemonitor.c | 5 +++-- + gio/gsubprocess.c | 4 +++- + gio/gtask.c | 3 ++- + gobject/gobject.c | 8 ++++---- + gobject/gsignal.h | 11 ++++++++--- + gobject/tests/signals.c | 6 ++++-- + 9 files changed, 28 insertions(+), 17 deletions(-) + +diff --git a/gio/gcancellable.c b/gio/gcancellable.c +index 64755206be..fe3cbeb7f7 100644 +--- a/gio/gcancellable.c ++++ b/gio/gcancellable.c +@@ -589,7 +589,7 @@ g_cancellable_connect (GCancellable *cancellable, + id = g_signal_connect_data (cancellable, "cancelled", + callback, data, + (GClosureNotify) data_destroy_func, +- 0); ++ G_CONNECT_DEFAULT); + + g_mutex_unlock (&cancellable_mutex); + } +diff --git a/gio/gdbusobjectmanagerclient.c b/gio/gdbusobjectmanagerclient.c +index bfb73b5308..fa5e73041e 100644 +--- a/gio/gdbusobjectmanagerclient.c ++++ b/gio/gdbusobjectmanagerclient.c +@@ -1456,7 +1456,7 @@ initable_init (GInitable *initable, + G_CALLBACK (on_notify_g_name_owner), + weak_ref_new (G_OBJECT (manager)), + (GClosureNotify) weak_ref_free, +- 0 /* flags */); ++ G_CONNECT_DEFAULT); + + manager->priv->signal_signal_id = + g_signal_connect_data (manager->priv->control_proxy, +@@ -1464,7 +1464,7 @@ initable_init (GInitable *initable, + G_CALLBACK (on_control_proxy_g_signal), + weak_ref_new (G_OBJECT (manager)), + (GClosureNotify) weak_ref_free, +- 0 /* flags */); ++ G_CONNECT_DEFAULT); + + manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy); + if (manager->priv->name_owner == NULL && manager->priv->name != NULL) +diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c +index fe5b23ed4d..f144d129ae 100644 +--- a/gio/gdbusserver.c ++++ b/gio/gdbusserver.c +@@ -630,7 +630,7 @@ g_dbus_server_start (GDBusServer *server) + G_CALLBACK (on_run), + g_object_ref (server), + (GClosureNotify) g_object_unref, +- 0 /* flags */); ++ G_CONNECT_DEFAULT); + g_socket_service_start (G_SOCKET_SERVICE (server->listener)); + server->active = TRUE; + g_object_notify (G_OBJECT (server), "active"); +diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c +index fde52193a9..8de4079394 100644 +--- a/gio/glocalfilemonitor.c ++++ b/gio/glocalfilemonitor.c +@@ -809,7 +809,8 @@ g_local_file_monitor_start (GLocalFileMonitor *local_monitor, + + local_monitor->mount_monitor = g_unix_mount_monitor_get (); + g_signal_connect_object (local_monitor->mount_monitor, "mounts-changed", +- G_CALLBACK (g_local_file_monitor_mounts_changed), local_monitor, 0); ++ G_CALLBACK (g_local_file_monitor_mounts_changed), local_monitor, ++ G_CONNECT_DEFAULT); + #endif + } + +@@ -924,7 +925,7 @@ g_local_file_monitor_new_in_worker (const gchar *pathname, + { + if (callback) + g_signal_connect_data (monitor, "changed", G_CALLBACK (callback), +- user_data, destroy_user_data, 0 /* flags */); ++ user_data, destroy_user_data, G_CONNECT_DEFAULT); + + g_local_file_monitor_start (monitor, pathname, is_directory, flags, GLIB_PRIVATE_CALL(g_get_worker_context) ()); + } +diff --git a/gio/gsubprocess.c b/gio/gsubprocess.c +index bb157197fc..c4747a1481 100644 +--- a/gio/gsubprocess.c ++++ b/gio/gsubprocess.c +@@ -756,7 +756,9 @@ g_subprocess_wait_async (GSubprocess *subprocess, + * see the cancellation in the _finish(). + */ + if (cancellable) +- g_signal_connect_object (cancellable, "cancelled", G_CALLBACK (g_subprocess_wait_cancelled), task, 0); ++ g_signal_connect_object (cancellable, "cancelled", ++ G_CALLBACK (g_subprocess_wait_cancelled), ++ task, G_CONNECT_DEFAULT); + + subprocess->pending_waits = g_slist_prepend (subprocess->pending_waits, task); + task = NULL; +diff --git a/gio/gtask.c b/gio/gtask.c +index d0f8b4e33a..774cba793a 100644 +--- a/gio/gtask.c ++++ b/gio/gtask.c +@@ -1530,7 +1530,8 @@ g_task_start_task_thread (GTask *task, + g_signal_connect_data (task->cancellable, "cancelled", + G_CALLBACK (task_thread_cancelled), + g_object_ref (task), +- task_thread_cancelled_disconnect_notify, 0); ++ task_thread_cancelled_disconnect_notify, ++ G_CONNECT_DEFAULT); + } + + if (g_private_get (&task_private)) +diff --git a/gobject/gobject.c b/gobject/gobject.c +index df908984b7..5ba8fd017b 100644 +--- a/gobject/gobject.c ++++ b/gobject/gobject.c +@@ -3093,8 +3093,8 @@ g_object_get_property (GObject *object, + * + * The signal specs expected by this function have the form + * "modifier::signal_name", where modifier can be one of the following: +- * - signal: equivalent to g_signal_connect_data (..., NULL, 0) +- * - object-signal, object_signal: equivalent to g_signal_connect_object (..., 0) ++ * - signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_DEFAULT) ++ * - object-signal, object_signal: equivalent to g_signal_connect_object (..., G_CONNECT_DEFAULT) + * - swapped-signal, swapped_signal: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_SWAPPED) + * - swapped_object_signal, swapped-object-signal: equivalent to g_signal_connect_object (..., G_CONNECT_SWAPPED) + * - signal_after, signal-after: equivalent to g_signal_connect_data (..., NULL, G_CONNECT_AFTER) +@@ -3135,12 +3135,12 @@ g_object_connect (gpointer _object, + if (strncmp (signal_spec, "signal::", 8) == 0) + g_signal_connect_data (object, signal_spec + 8, + callback, data, NULL, +- 0); ++ G_CONNECT_DEFAULT); + else if (strncmp (signal_spec, "object_signal::", 15) == 0 || + strncmp (signal_spec, "object-signal::", 15) == 0) + g_signal_connect_object (object, signal_spec + 15, + callback, data, +- 0); ++ G_CONNECT_DEFAULT); + else if (strncmp (signal_spec, "swapped_signal::", 16) == 0 || + strncmp (signal_spec, "swapped-signal::", 16) == 0) + g_signal_connect_data (object, signal_spec + 16, +diff --git a/gobject/gsignal.h b/gobject/gsignal.h +index 7b3974a8c4..53da2a6eab 100644 +--- a/gobject/gsignal.h ++++ b/gobject/gsignal.h +@@ -155,9 +155,11 @@ typedef enum + #define G_SIGNAL_FLAGS_MASK 0x1ff + /** + * GConnectFlags: +- * @G_CONNECT_AFTER: whether the handler should be called before or after the +- * default handler of the signal. +- * @G_CONNECT_SWAPPED: whether the instance and data should be swapped when ++ * @G_CONNECT_DEFAULT: Default behaviour (no special flags). Since: 2.74 ++ * @G_CONNECT_AFTER: If set, the handler should be called after the ++ * default handler of the signal. Normally, the handler is called before ++ * the default handler. ++ * @G_CONNECT_SWAPPED: If set, the instance and data should be swapped when + * calling the handler; see g_signal_connect_swapped() for an example. + * + * The connection flags are used to specify the behaviour of a signal's +@@ -165,6 +167,7 @@ typedef enum + */ + typedef enum + { ++ G_CONNECT_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_CONNECT_AFTER = 1 << 0, + G_CONNECT_SWAPPED = 1 << 1 + } GConnectFlags; +@@ -504,6 +507,8 @@ void g_signal_chain_from_overridden_handler (gpointer instance, + * + * Returns: the handler ID, of type #gulong (always greater than 0 for successful connections) + */ ++/* Intentionally not using G_CONNECT_DEFAULT here to avoid deprecation ++ * warnings with older GLIB_VERSION_MAX_ALLOWED */ + #define g_signal_connect(instance, detailed_signal, c_handler, data) \ + g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0) + /** +diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c +index ea9a778bf8..e4be41575f 100644 +--- a/gobject/tests/signals.c ++++ b/gobject/tests/signals.c +@@ -1109,8 +1109,10 @@ test_destroy_target_object (void) + sender = g_object_new (test_get_type (), NULL); + target1 = g_object_new (test_get_type (), NULL); + target2 = g_object_new (test_get_type (), NULL); +- g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler1), target1, 0); +- g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler2), target2, 0); ++ g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler1), ++ target1, G_CONNECT_DEFAULT); ++ g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler2), ++ target2, G_CONNECT_DEFAULT); + g_signal_emit_by_name (sender, "simple"); + g_object_unref (sender); + } +-- +GitLab + diff --git a/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch b/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch new file mode 100644 index 0000000000000000000000000000000000000000..d865a121b8decf9955c98ff2860dfb3b53acf764 --- /dev/null +++ b/backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch @@ -0,0 +1,117 @@ +From 56d371942e43c52bc6131067e2dc2a35f6cd5a3d Mon Sep 17 00:00:00 2001 +From: Philip Withnall +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 + +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 + diff --git a/backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch b/backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch deleted file mode 100644 index af277b7a6a0481ae1fc34c3c3ffd582b0483d3af..0000000000000000000000000000000000000000 --- a/backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch +++ /dev/null @@ -1,73 +0,0 @@ -From b32727d43d9d11aa017f1f29648ad5019376537c Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:07:01 +0300 -Subject: [PATCH] gsocks5proxy: Fix buffer overflow on a really long domain - name - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/b32727d43d9d11aa017f1f29648ad5019376537c - ---- - gio/gsocks5proxy.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c -index 873db7ea6d..948ac8b8b8 100644 ---- a/gio/gsocks5proxy.c -+++ b/gio/gsocks5proxy.c -@@ -328,7 +328,7 @@ set_connect_msg (guint8 *msg, - * - * The parser only requires 4 bytes. - */ --#define SOCKS5_CONN_REP_LEN 255 -+#define SOCKS5_CONN_REP_LEN 257 - static gboolean - parse_connect_reply (const guint8 *data, gint *atype, GError **error) - { -@@ -509,7 +509,7 @@ g_socks5_proxy_connect (GProxy *proxy, - guint8 data[SOCKS5_CONN_REP_LEN]; - gint atype; - -- if (!g_input_stream_read_all (in, data, 4, NULL, -+ if (!g_input_stream_read_all (in, data, 4 /* VER, REP, RSV, ATYP */, NULL, - cancellable, error)) - goto error; - -@@ -519,23 +519,26 @@ g_socks5_proxy_connect (GProxy *proxy, - switch (atype) - { - case SOCKS5_ATYP_IPV4: -- if (!g_input_stream_read_all (in, data, 6, NULL, -- cancellable, error)) -+ if (!g_input_stream_read_all (in, data, -+ 4 /* IPv4 length */ + 2 /* port */, -+ NULL, cancellable, error)) - goto error; - break; - - case SOCKS5_ATYP_IPV6: -- if (!g_input_stream_read_all (in, data, 18, NULL, -- cancellable, error)) -+ if (!g_input_stream_read_all (in, data, -+ 16 /* IPv6 length */ + 2 /* port */, -+ NULL, cancellable, error)) - goto error; - break; - - case SOCKS5_ATYP_DOMAINNAME: -- if (!g_input_stream_read_all (in, data, 1, NULL, -- cancellable, error)) -+ if (!g_input_stream_read_all (in, data, 1 /* domain name length */, -+ NULL, cancellable, error)) - goto error; -- if (!g_input_stream_read_all (in, data, data[0] + 2, NULL, -- cancellable, error)) -+ if (!g_input_stream_read_all (in, data, -+ data[0] /* domain name length */ + 2 /* port */, -+ NULL, cancellable, error)) - goto error; - break; - } --- -GitLab - diff --git a/backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch b/backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch deleted file mode 100644 index dc9123970001cc30f9a7bee62f0e8fccee9a746f..0000000000000000000000000000000000000000 --- a/backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 40a46d1346fdd4e07c648ba1ee78dedd9bfa33ad Mon Sep 17 00:00:00 2001 -From: Benjamin Berg -Date: Tue, 6 Apr 2021 16:52:23 +0200 -Subject: [PATCH] gsocks5proxy: Handle EOF when reading from a stream - -The code did not handle EOF (0 byte read) correctly. This can e.g. cause -an infinite loop if an incorrect socks proxy is configured. - -Add the appropriate checks and return an G_IO_ERROR_CONNECTION_CLOSED -error if EOF is encountered. - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/40a46d1346fdd4e07c648ba1ee78dedd9bfa33ad - ---- - gio/gsocks5proxy.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/gio/gsocks5proxy.c b/gio/gsocks5proxy.c -index 09b7fcac29..873db7ea6d 100644 ---- a/gio/gsocks5proxy.c -+++ b/gio/gsocks5proxy.c -@@ -717,6 +717,16 @@ nego_reply_read_cb (GObject *source, - return; - } - -+ if (read == 0) -+ { -+ g_task_return_new_error (task, -+ G_IO_ERROR, -+ G_IO_ERROR_CONNECTION_CLOSED, -+ "Connection to SOCKSv5 proxy server lost"); -+ g_object_unref (task); -+ return; -+ } -+ - data->offset += read; - - if (data->offset == data->length) -@@ -821,6 +831,16 @@ auth_reply_read_cb (GObject *source, - return; - } - -+ if (read == 0) -+ { -+ g_task_return_new_error (task, -+ G_IO_ERROR, -+ G_IO_ERROR_CONNECTION_CLOSED, -+ "Connection to SOCKSv5 proxy server lost"); -+ g_object_unref (task); -+ return; -+ } -+ - data->offset += read; - - if (data->offset == data->length) -@@ -923,6 +943,16 @@ connect_reply_read_cb (GObject *source, - return; - } - -+ if (read == 0) -+ { -+ g_task_return_new_error (task, -+ G_IO_ERROR, -+ G_IO_ERROR_CONNECTION_CLOSED, -+ "Connection to SOCKSv5 proxy server lost"); -+ g_object_unref (task); -+ return; -+ } -+ - data->offset += read; - - if (data->offset == data->length) -@@ -983,6 +1013,16 @@ connect_addr_len_read_cb (GObject *source, - return; - } - -+ if (read == 0) -+ { -+ g_task_return_new_error (task, -+ G_IO_ERROR, -+ G_IO_ERROR_CONNECTION_CLOSED, -+ "Connection to SOCKSv5 proxy server lost"); -+ g_object_unref (task); -+ return; -+ } -+ - data->length = data->buffer[0] + 2; - data->offset = 0; - -@@ -1009,6 +1049,16 @@ connect_addr_read_cb (GObject *source, - return; - } - -+ if (read == 0) -+ { -+ g_task_return_new_error (task, -+ G_IO_ERROR, -+ G_IO_ERROR_CONNECTION_CLOSED, -+ "Connection to SOCKSv5 proxy server lost"); -+ g_object_unref (task); -+ return; -+ } -+ - data->offset += read; - - if (data->offset == data->length) --- -GitLab - diff --git a/backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch b/backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..78b0bccc8435dd4ad428c57cb12b8381ffe8d80d --- /dev/null +++ b/backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch @@ -0,0 +1,1307 @@ +From de8672fe0b9f55047fbaee6f425e330cdfc8189f Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 31 Mar 2022 14:30:43 +0100 +Subject: [PATCH] gtestutils: Add G_TEST_SUBPROCESS_DEFAULT, + G_TEST_TRAP_DEFAULT + +This makes calls to test subprocesses with default behaviour more +self-documenting. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/de8672fe0b9f55047fbaee6f425e330cdfc8189f + +--- + gio/tests/gapplication.c | 2 +- + gio/tests/gdbus-address-get-session.c | 6 +- + gio/tests/gdbus-non-socket.c | 2 +- + gio/tests/gdbus-peer.c | 10 +-- + gio/tests/glistmodel.c | 2 +- + gio/tests/gschema-compile.c | 2 +- + gio/tests/gsettings.c | 55 +++++++++----- + gio/tests/task.c | 8 +- + gio/tests/tls-bindings.c | 4 +- + gio/tests/win32-appinfo.c | 6 +- + glib/gtestutils.c | 3 +- + glib/gtestutils.h | 3 + + glib/tests/array-test.c | 4 +- + glib/tests/convert.c | 24 ++++-- + glib/tests/dataset.c | 2 +- + glib/tests/error.c | 2 +- + glib/tests/gvariant.c | 2 +- + glib/tests/hash.c | 3 +- + glib/tests/list.c | 2 +- + glib/tests/logging.c | 37 ++++++---- + glib/tests/mem-overflow.c | 9 ++- + glib/tests/refcount.c | 4 +- + glib/tests/scannerapi.c | 2 +- + glib/tests/slice.c | 4 +- + glib/tests/test-printf.c | 10 ++- + glib/tests/testing.c | 102 ++++++++++++++++---------- + glib/tests/thread-pool.c | 2 +- + glib/tests/utils.c | 9 ++- + glib/tests/win32.c | 9 ++- + gobject/tests/param.c | 5 +- + gobject/tests/properties.c | 4 +- + gobject/tests/signals.c | 4 +- + gobject/tests/testing.c | 3 +- + 33 files changed, 213 insertions(+), 133 deletions(-) + +diff --git a/gio/tests/gapplication.c b/gio/tests/gapplication.c +index 6f1a27e..b017e43 100644 +--- a/gio/tests/gapplication.c ++++ b/gio/tests/gapplication.c +@@ -827,7 +827,7 @@ test_help (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Application options*"); + } +diff --git a/gio/tests/gdbus-address-get-session.c b/gio/tests/gdbus-address-get-session.c +index 72de2c7..4758c8c 100644 +--- a/gio/tests/gdbus-address-get-session.c ++++ b/gio/tests/gdbus-address-get-session.c +@@ -142,7 +142,7 @@ test_x11_autolaunch (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_stderr_unmatched ("?*"); + g_test_trap_assert_stdout ("hello:this=address-is-from-the,mock=dbus-launch\n"); + g_test_trap_assert_passed (); +@@ -165,7 +165,7 @@ test_xdg_runtime (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_stderr_unmatched ("?*"); + g_test_trap_assert_stdout ("unix:path=/tmp/gdbus%2Cunix%2Ctest.*/bus\n"); + g_test_trap_assert_passed (); +@@ -201,7 +201,7 @@ test_win32_autolaunch (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + /* stderr is not checked: coverage prints warnings there */ + g_test_trap_assert_stdout ("nonce-tcp:host=localhost,port=*,noncefile=*\\gdbus-nonce-file-*\n"); + g_test_trap_assert_passed (); +diff --git a/gio/tests/gdbus-non-socket.c b/gio/tests/gdbus-non-socket.c +index 7ddb55b..c246aea 100644 +--- a/gio/tests/gdbus-non-socket.c ++++ b/gio/tests/gdbus-non-socket.c +@@ -220,7 +220,7 @@ test_non_socket (void) + + /* This is #ifdef G_OS_UNIX anyway, so just use g_test_trap_fork() */ + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; +- if (!g_test_trap_fork (0, 0)) ++ if (!g_test_trap_fork (0, G_TEST_TRAP_DEFAULT)) + { + /* parent */ + g_object_unref (streams[0]); +diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c +index 2f2caf7..dff47d4 100644 +--- a/gio/tests/gdbus-peer.c ++++ b/gio/tests/gdbus-peer.c +@@ -1164,7 +1164,7 @@ test_peer_invalid_server (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_SERVER_FLAGS_ALL*"); + } +@@ -1211,7 +1211,7 @@ test_peer_invalid_conn_stream_sync (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +@@ -1257,7 +1257,7 @@ test_peer_invalid_conn_stream_async (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +@@ -1286,7 +1286,7 @@ test_peer_invalid_conn_addr_sync (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +@@ -1309,7 +1309,7 @@ test_peer_invalid_conn_addr_async (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*G_DBUS_CONNECTION_FLAGS_ALL*"); + } +diff --git a/gio/tests/glistmodel.c b/gio/tests/glistmodel.c +index e50969e..62986d7 100644 +--- a/gio/tests/glistmodel.c ++++ b/gio/tests/glistmodel.c +@@ -62,7 +62,7 @@ test_store_non_gobjects (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*value * of type 'GType' is invalid or " + "out of range for property 'item-type'*"); +diff --git a/gio/tests/gschema-compile.c b/gio/tests/gschema-compile.c +index 8dc4985..6a51e42 100644 +--- a/gio/tests/gschema-compile.c ++++ b/gio/tests/gschema-compile.c +@@ -38,7 +38,7 @@ test_schema (gpointer data) + gchar *child_name; + + child_name = g_strdup_printf ("/gschema/%s%s/subprocess/do_compile", test->name, test->opt ? "/opt" : ""); +- g_test_trap_subprocess (child_name, 0, 0); ++ g_test_trap_subprocess (child_name, 0, G_TEST_SUBPROCESS_DEFAULT); + g_free (child_name); + + if (test->err) +diff --git a/gio/tests/gsettings.c b/gio/tests/gsettings.c +index 35d958e..1956ac5 100644 +--- a/gio/tests/gsettings.c ++++ b/gio/tests/gsettings.c +@@ -147,7 +147,7 @@ test_unknown_key (void) + g_object_unref (settings); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*does not contain*"); + } +@@ -170,7 +170,7 @@ test_no_schema (void) + g_assert_null (settings); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Settings schema 'no.such.schema' is not installed*"); + } +@@ -220,7 +220,7 @@ test_wrong_path (void) + settings = g_settings_new_with_path ("org.gtk.test", "/wrong-path/"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*but path * specified by schema*"); + } +@@ -238,7 +238,7 @@ test_no_path (void) + settings = g_settings_new ("org.gtk.test.no-path"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*attempting to create schema * without a path**"); + } +@@ -1507,7 +1507,7 @@ test_typesafe_binding (void) + g_object_unref (settings); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not compatible*"); + } +@@ -1665,12 +1665,14 @@ test_no_read_binding (void) + { + if (g_test_undefined ()) + { +- g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/fail", 0, 0); ++ g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/fail", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*property*is not readable*"); + } + +- g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/pass", 0, 0); ++ g_test_trap_subprocess ("/gsettings/no-read-binding/subprocess/pass", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -1708,12 +1710,14 @@ test_no_write_binding (void) + { + if (g_test_undefined ()) + { +- g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/fail", 0, 0); ++ g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/fail", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*property*is not writable*"); + } + +- g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/pass", 0, 0); ++ g_test_trap_subprocess ("/gsettings/no-write-binding/subprocess/pass", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -2141,19 +2145,23 @@ test_enums (void) + + if (g_test_undefined () && !backend_set) + { +- g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-key", 0, 0); ++ g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-key", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with an enum*"); + +- g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-value", 0, 0); ++ g_test_trap_subprocess ("/gsettings/enums/subprocess/non-enum-value", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*invalid enum value 42*"); + +- g_test_trap_subprocess ("/gsettings/enums/subprocess/range", 0, 0); ++ g_test_trap_subprocess ("/gsettings/enums/subprocess/range", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + +- g_test_trap_subprocess ("/gsettings/enums/subprocess/non-flags", 0, 0); ++ g_test_trap_subprocess ("/gsettings/enums/subprocess/non-flags", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with a flags*"); + } +@@ -2239,19 +2247,23 @@ test_flags (void) + + if (g_test_undefined () && !backend_set) + { +- g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-key", 0, 0); ++ g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-key", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with a flags*"); + +- g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-value", 0, 0); ++ g_test_trap_subprocess ("/gsettings/flags/subprocess/non-flags-value", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*invalid flags value 0x00000042*"); + +- g_test_trap_subprocess ("/gsettings/flags/subprocess/range", 0, 0); ++ g_test_trap_subprocess ("/gsettings/flags/subprocess/range", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + +- g_test_trap_subprocess ("/gsettings/flags/subprocess/non-enum", 0, 0); ++ g_test_trap_subprocess ("/gsettings/flags/subprocess/non-enum", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*not associated with an enum*"); + } +@@ -2328,11 +2340,13 @@ test_range (void) + + if (g_test_undefined () && !backend_set) + { +- g_test_trap_subprocess ("/gsettings/range/subprocess/high", 0, 0); ++ g_test_trap_subprocess ("/gsettings/range/subprocess/high", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + +- g_test_trap_subprocess ("/gsettings/range/subprocess/low", 0, 0); ++ g_test_trap_subprocess ("/gsettings/range/subprocess/low", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_settings_set_value*valid range*"); + } +@@ -2881,7 +2895,8 @@ test_per_desktop (void) + + if (!g_test_subprocess ()) + { +- g_test_trap_subprocess ("/gsettings/per-desktop/subprocess", 0, 0); ++ g_test_trap_subprocess ("/gsettings/per-desktop/subprocess", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +diff --git a/gio/tests/task.c b/gio/tests/task.c +index 7ce8438..d9e9148 100644 +--- a/gio/tests/task.c ++++ b/gio/tests/task.c +@@ -2303,7 +2303,7 @@ test_return_in_idle_error_first (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); + } +@@ -2319,7 +2319,7 @@ test_return_in_idle_value_first (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); + } +@@ -2335,7 +2335,7 @@ test_return_error_first (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); + } +@@ -2351,7 +2351,7 @@ test_return_value_first (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*assertion '!task->ever_returned' failed*"); + } +diff --git a/gio/tests/tls-bindings.c b/gio/tests/tls-bindings.c +index 681b658..81b3189 100644 +--- a/gio/tests/tls-bindings.c ++++ b/gio/tests/tls-bindings.c +@@ -40,7 +40,7 @@ get_tls_channel_binding (void) + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, (GError **)¬_null)); + + g_object_unref (tls); +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO-CRITICAL*"); + } +@@ -75,7 +75,7 @@ get_dtls_channel_binding (void) + G_TLS_CHANNEL_BINDING_TLS_UNIQUE, NULL, (GError **)¬_null)); + + g_object_unref (dtls); +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO-CRITICAL*"); + } +diff --git a/gio/tests/win32-appinfo.c b/gio/tests/win32-appinfo.c +index fa8aa2a..8402a20 100644 +--- a/gio/tests/win32-appinfo.c ++++ b/gio/tests/win32-appinfo.c +@@ -442,10 +442,12 @@ do_fail_on_broken_utf16_2 (void) + static void + test_fail_on_broken_utf16 (void) + { +- g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_1", 0, 0); ++ g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_1", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO:ERROR:*giowin32-private.c:*:_g_win32_extract_executable: assertion failed: (folded)*"); +- g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_2", 0, 0); ++ g_test_trap_subprocess ("/appinfo/subprocess/win32-assert-broken-utf16_2", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib-GIO:ERROR:*giowin32-private.c:*:_g_win32_extract_executable: assertion failed: (folded)*"); + } +diff --git a/glib/gtestutils.c b/glib/gtestutils.c +index dca4bad..c9c65e6 100644 +--- a/glib/gtestutils.c ++++ b/glib/gtestutils.c +@@ -355,6 +355,7 @@ + + /** + * GTestSubprocessFlags: ++ * @G_TEST_SUBPROCESS_DEFAULT: Default behaviour. Since: 2.74 + * @G_TEST_SUBPROCESS_INHERIT_STDIN: If this flag is given, the child + * process will inherit the parent's stdin. Otherwise, the child's + * stdin is redirected to `/dev/null`. +@@ -3780,7 +3781,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS + * } + * + * // Reruns this same test in a subprocess +- * g_test_trap_subprocess (NULL, 0, 0); ++ * g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + * g_test_trap_assert_failed (); + * g_test_trap_assert_stderr ("*ERROR*too large*"); + * } +diff --git a/glib/gtestutils.h b/glib/gtestutils.h +index 7dee482..794da05 100644 +--- a/glib/gtestutils.h ++++ b/glib/gtestutils.h +@@ -423,6 +423,7 @@ void g_test_queue_destroy (GDestroyNotify destroy_func, + + /** + * GTestTrapFlags: ++ * @G_TEST_TRAP_DEFAULT: Default behaviour. Since: 2.74 + * @G_TEST_TRAP_SILENCE_STDOUT: Redirect stdout of the test child to + * `/dev/null` so it cannot be observed on the console during test + * runs. The actual output is still captured though to allow later +@@ -443,6 +444,7 @@ void g_test_queue_destroy (GDestroyNotify destroy_func, + * #GTestSubprocessFlags. + */ + typedef enum { ++ G_TEST_TRAP_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_TEST_TRAP_SILENCE_STDOUT = 1 << 7, + G_TEST_TRAP_SILENCE_STDERR = 1 << 8, + G_TEST_TRAP_INHERIT_STDIN = 1 << 9 +@@ -457,6 +459,7 @@ gboolean g_test_trap_fork (guint64 usec_timeout, + G_GNUC_END_IGNORE_DEPRECATIONS + + typedef enum { ++ G_TEST_SUBPROCESS_DEFAULT GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_TEST_SUBPROCESS_INHERIT_STDIN = 1 << 0, + G_TEST_SUBPROCESS_INHERIT_STDOUT = 1 << 1, + G_TEST_SUBPROCESS_INHERIT_STDERR = 1 << 2 +diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c +index 284ac08..f2736dd 100644 +--- a/glib/tests/array-test.c ++++ b/glib/tests/array-test.c +@@ -859,7 +859,7 @@ array_overflow_append_vals (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*"); + } +@@ -878,7 +878,7 @@ array_overflow_set_size (void) + } + else + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*"); + } +diff --git a/glib/tests/convert.c b/glib/tests/convert.c +index de6c8a7..81b8bbe 100644 +--- a/glib/tests/convert.c ++++ b/glib/tests/convert.c +@@ -707,9 +707,11 @@ test_convert_embedded_nul (void) + static void + test_locale_to_utf8_embedded_nul (void) + { +- g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", 0, 0); ++ g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/utf8", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); +- g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", 0, 0); ++ g_test_trap_subprocess ("/conversion/locale-to-utf8/embedded-nul/subprocess/iconv", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -758,9 +760,11 @@ test_locale_to_utf8_embedded_nul_iconv (void) + static void + test_locale_from_utf8_embedded_nul (void) + { +- g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", 0, 0); ++ g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/utf8", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); +- g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", 0, 0); ++ g_test_trap_subprocess ("/conversion/locale-from-utf8/embedded-nul/subprocess/iconv", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -811,9 +815,11 @@ test_locale_from_utf8_embedded_nul_iconv (void) + static void + test_filename_to_utf8_embedded_nul (void) + { +- g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", 0, 0); ++ g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/utf8", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); +- g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", 0, 0); ++ g_test_trap_subprocess ("/conversion/filename-to-utf8/embedded-nul/subprocess/iconv", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -868,9 +874,11 @@ test_filename_to_utf8_embedded_nul_iconv (void) + static void + test_filename_from_utf8_embedded_nul (void) + { +- g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", 0, 0); ++ g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/utf8", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); +- g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", 0, 0); ++ g_test_trap_subprocess ("/conversion/filename-from-utf8/embedded-nul/subprocess/iconv", ++ 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +diff --git a/glib/tests/dataset.c b/glib/tests/dataset.c +index b02b3e4..3b96b42 100644 +--- a/glib/tests/dataset.c ++++ b/glib/tests/dataset.c +@@ -202,7 +202,7 @@ test_datalist_clear (void) + return; + } + +- g_test_trap_subprocess (NULL, 500000, 0); ++ g_test_trap_subprocess (NULL, 500000, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +diff --git a/glib/tests/error.c b/glib/tests/error.c +index 51a0c35..7ea04ea 100644 +--- a/glib/tests/error.c ++++ b/glib/tests/error.c +@@ -336,7 +336,7 @@ test_extended_duplicate (void) + if (!g_test_subprocess ()) + { + /* Spawn a subprocess and expect it to fail. */ +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*Attempted to register an extended error domain for TestError more than once*"); + } +diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c +index 0110f26..89dc914 100644 +--- a/glib/tests/gvariant.c ++++ b/glib/tests/gvariant.c +@@ -2934,7 +2934,7 @@ static void + do_failed_test (const char *test, + const gchar *pattern) + { +- g_test_trap_subprocess (test, 1000000, 0); ++ g_test_trap_subprocess (test, 1000000, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr (pattern); + } +diff --git a/glib/tests/hash.c b/glib/tests/hash.c +index 114b6a2..6d718a7 100644 +--- a/glib/tests/hash.c ++++ b/glib/tests/hash.c +@@ -873,7 +873,8 @@ test_recursive_remove_all_subprocess (void) + static void + test_recursive_remove_all (void) + { +- g_test_trap_subprocess ("/hash/recursive-remove-all/subprocess", 1000000, 0); ++ g_test_trap_subprocess ("/hash/recursive-remove-all/subprocess", 1000000, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +diff --git a/glib/tests/list.c b/glib/tests/list.c +index 4efd8b6..20d01db 100644 +--- a/glib/tests/list.c ++++ b/glib/tests/list.c +@@ -552,7 +552,7 @@ test_double_free (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*corrupted double-linked list detected*"); + } +diff --git a/glib/tests/logging.c b/glib/tests/logging.c +index e9c4e39..a65ba7c 100644 +--- a/glib/tests/logging.c ++++ b/glib/tests/logging.c +@@ -200,48 +200,59 @@ test_default_handler_0x400 (void) + static void + test_default_handler (void) + { +- g_test_trap_subprocess ("/logging/default-handler/subprocess/error", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/error", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*ERROR*message1*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*message2*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*message3*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*Message*message4*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout_unmatched ("*INFO*message5*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*INFO*message5*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/baz-debug", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/baz-debug", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*DEBUG*message6*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/debug", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/debug", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*DEBUG*6*6*6*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/debug-stderr", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/debug-stderr", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout_unmatched ("DEBUG"); + g_test_trap_assert_stderr ("*DEBUG*6*6*6*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/0x400", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/0x400", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*LOG-0x400*message7*"); + +- g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop", 0, 0); ++ g_test_trap_subprocess ("/logging/default-handler/subprocess/would-drop", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -254,7 +265,7 @@ test_fatal_log_mask (void) + g_log ("bu", G_LOG_LEVEL_INFO, "fatal"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + /* G_LOG_LEVEL_INFO isn't printed by default */ + g_test_trap_assert_stdout_unmatched ("*fatal*"); +@@ -361,7 +372,7 @@ test_gibberish (void) + g_warning ("bla bla \236\237\190"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*bla bla \\x9e\\x9f\\u000190*"); + } +diff --git a/glib/tests/mem-overflow.c b/glib/tests/mem-overflow.c +index fd92685..66a0056 100644 +--- a/glib/tests/mem-overflow.c ++++ b/glib/tests/mem-overflow.c +@@ -139,7 +139,8 @@ mem_overflow (void) + #define CHECK_SUBPROCESS_FAIL(name) do { \ + if (g_test_undefined ()) \ + { \ +- g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ ++ g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, \ ++ G_TEST_SUBPROCESS_DEFAULT); \ + g_test_trap_assert_failed(); \ + } \ + } while (0) +@@ -147,7 +148,8 @@ mem_overflow (void) + #define CHECK_SUBPROCESS_PASS(name) do { \ + if (g_test_undefined ()) \ + { \ +- g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, 0); \ ++ g_test_trap_subprocess ("/mem/overflow/subprocess/" #name, 0, \ ++ G_TEST_SUBPROCESS_DEFAULT); \ + g_test_trap_assert_passed(); \ + } \ + } while (0) +@@ -208,7 +210,8 @@ empty_alloc (void) + + g_assert_cmpint (sizeof (Empty), ==, 0); + +- g_test_trap_subprocess ("/mem/empty-alloc/subprocess", 0, 0); ++ g_test_trap_subprocess ("/mem/empty-alloc/subprocess", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + #endif +diff --git a/glib/tests/refcount.c b/glib/tests/refcount.c +index e19a2d7..2c527cf 100644 +--- a/glib/tests/refcount.c ++++ b/glib/tests/refcount.c +@@ -98,7 +98,7 @@ test_grefcount_saturation (void) + exit (0); + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + + #if defined (G_DISABLE_CHECKS) && defined (__GNUC__) + /* With checks disabled we don't get any warning */ +@@ -191,7 +191,7 @@ test_gatomicrefcount_saturation (void) + exit (0); + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + + #if defined (G_DISABLE_CHECKS) && defined (__GNUC__) + /* With checks disabled we don't get any warning */ +diff --git a/glib/tests/scannerapi.c b/glib/tests/scannerapi.c +index 6813184..21b01bf 100644 +--- a/glib/tests/scannerapi.c ++++ b/glib/tests/scannerapi.c +@@ -68,7 +68,7 @@ test_scanner_error (ScannerFixture *fix, + exit (0); + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*scanner-error-message-test*"); + } +diff --git a/glib/tests/slice.c b/glib/tests/slice.c +index a566280..7cf53b4 100644 +--- a/glib/tests/slice.c ++++ b/glib/tests/slice.c +@@ -25,7 +25,7 @@ test_slice_nodebug (void) + g_slice_debug_tree_statistics (); + return; + } +- g_test_trap_subprocess (NULL, 1000000, 0); ++ g_test_trap_subprocess (NULL, 1000000, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*GSlice: MemChecker: root=NULL*"); + +@@ -53,7 +53,7 @@ test_slice_debug (void) + g_slice_debug_tree_statistics (); + return; + } +- g_test_trap_subprocess (NULL, 1000000, 0); ++ g_test_trap_subprocess (NULL, 1000000, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*GSlice: MemChecker: * trunks, * branches, * old branches*"); + +diff --git a/glib/tests/test-printf.c b/glib/tests/test-printf.c +index 6eadf1e..9aca97f 100644 +--- a/glib/tests/test-printf.c ++++ b/glib/tests/test-printf.c +@@ -639,7 +639,7 @@ test_positional_params2 (void) + g_assert_cmpint (res, ==, 7); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("a b\n ab\nabcabc\n"); + } +@@ -674,7 +674,7 @@ test_percent2 (void) + g_assert_cmpint (res, ==, 1); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*%*"); + } +@@ -858,13 +858,15 @@ _Pragma ("GCC diagnostic pop") + static void + test_64bit2 (void) + { +- g_test_trap_subprocess ("/printf/test-64bit/subprocess/base", 0, 0); ++ g_test_trap_subprocess ("/printf/test-64bit/subprocess/base", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("123456\n-123456\n123456\n" + "361100\n0361100\n1e240\n" + "0x1e240\n1E240\n"); + #ifdef G_OS_WIN32 +- g_test_trap_subprocess ("/printf/test-64bit/subprocess/win32", 0, 0); ++ g_test_trap_subprocess ("/printf/test-64bit/subprocess/win32", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("123456\n-123456\n123456\n" + "361100\n0361100\n1e240\n" +diff --git a/glib/tests/testing.c b/glib/tests/testing.c +index accd5db..60fdb4c 100644 +--- a/glib/tests/testing.c ++++ b/glib/tests/testing.c +@@ -208,56 +208,69 @@ test_assertions (void) + g_variant_unref (v2); + g_variant_unref (v1); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_types", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_types", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_values", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpvariant_values", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstr", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstr", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null1", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null1", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null2", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_null2", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_length", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_length", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_values", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpstrv_values", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpint", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpint", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_len", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_len", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*len*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_data", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_data", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + g_test_trap_assert_stderr_unmatched ("*assertion failed*len*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_null", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpmem_null", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*NULL*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + +- g_test_trap_subprocess ("/misc/assertions/subprocess/bad_no_errno", 0, 0); ++ g_test_trap_subprocess ("/misc/assertions/subprocess/bad_no_errno", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*"); + } +@@ -312,7 +325,7 @@ static void + test_fork_timeout (void) + { + /* allow child to run for only a fraction of a second */ +- if (g_test_trap_fork (0.11 * 1000000, 0)) ++ if (g_test_trap_fork (0.11 * 1000000, G_TEST_TRAP_DEFAULT)) + { + /* loop and sleep forever */ + while (TRUE) +@@ -334,7 +347,7 @@ test_subprocess_fail (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*ERROR*test_subprocess_fail*should not be reached*"); + } +@@ -344,11 +357,12 @@ test_subprocess_no_such_test (void) + { + if (g_test_subprocess ()) + { +- g_test_trap_subprocess ("/trap_subprocess/this-test-does-not-exist", 0, 0); ++ g_test_trap_subprocess ("/trap_subprocess/this-test-does-not-exist", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_assert_not_reached (); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*test does not exist*"); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); +@@ -363,7 +377,7 @@ test_subprocess_patterns (void) + g_printerr ("some stderr text: semagic43\n"); + exit (0); + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*somagic17*"); + g_test_trap_assert_stderr ("*semagic43*"); +@@ -380,7 +394,7 @@ test_subprocess_timeout (void) + return; + } + /* allow child to run for only a fraction of a second */ +- g_test_trap_subprocess (NULL, 0.11 * 1000000, 0); ++ g_test_trap_subprocess (NULL, 0.11 * 1000000, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_assert_true (g_test_trap_reached_timeout ()); + } +@@ -508,16 +522,19 @@ test_fatal_log_handler_critical_fail (void) + static void + test_fatal_log_handler (void) + { +- g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-pass", 0, 0); ++ g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-pass", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*CRITICAL*g_str_has_prefix*"); + g_test_trap_assert_stderr ("*CRITICAL*Test passing*"); + +- g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/error-fail", 0, 0); ++ g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/error-fail", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*ERROR*Test failing*"); + +- g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-fail", 0, 0); ++ g_test_trap_subprocess ("/misc/fatal-log-handler/subprocess/critical-fail", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_str_has_prefix*"); + g_test_trap_assert_stderr_unmatched ("*CRITICAL*Test passing*"); +@@ -612,34 +629,41 @@ test_expected_messages_unexpected_extra_warning (void) + static void + test_expected_messages (void) + { +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/warning", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*This is a * warning*"); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/expect-warning", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/expect-warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr_unmatched ("*This is a * warning*"); + g_test_trap_assert_stderr ("*should not be reached*"); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/wrong-warning", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/wrong-warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr_unmatched ("*should not be reached*"); + g_test_trap_assert_stderr ("*GLib-CRITICAL*Did not see expected message testing-CRITICAL*should not be *WARNING*This is a * warning*"); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/expected", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/expected", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/null-domain", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/null-domain", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/extra-warning", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/extra-warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr (""); + +- g_test_trap_subprocess ("/misc/expected-messages/subprocess/unexpected-extra-warning", 0, 0); ++ g_test_trap_subprocess ("/misc/expected-messages/subprocess/unexpected-extra-warning", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*GLib:ERROR*Did not see expected message testing-CRITICAL*nope*"); + } +@@ -718,7 +742,8 @@ test_dash_p_child_sub_child (void) + static void + test_dash_p (void) + { +- g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden", 0, 0); ++ g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/subprocess/hidden ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub ran*"); +@@ -726,7 +751,8 @@ test_dash_p (void) + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/sub/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child*"); + +- g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden/sub", 0, 0); ++ g_test_trap_subprocess ("/misc/dash-p/subprocess/hidden/sub", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/subprocess/hidden/sub ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden ran*"); +@@ -734,7 +760,8 @@ test_dash_p (void) + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child*"); + +- g_test_trap_subprocess ("/misc/dash-p/child", 0, 0); ++ g_test_trap_subprocess ("/misc/dash-p/child", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child ran*"); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child/sub ran*"); +@@ -742,7 +769,8 @@ test_dash_p (void) + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child/subprocess ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/subprocess/hidden*"); + +- g_test_trap_subprocess ("/misc/dash-p/child/sub", 0, 0); ++ g_test_trap_subprocess ("/misc/dash-p/child/sub", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*Test /misc/dash-p/child/sub ran*"); + g_test_trap_assert_stdout_unmatched ("*Test /misc/dash-p/child ran*"); +@@ -761,7 +789,7 @@ test_nonfatal (void) + g_print ("The End\n"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*assertion failed*4 == 5*"); + g_test_trap_assert_stdout ("*The End*"); +@@ -800,7 +828,7 @@ test_fail (void) + subprocess_fail (); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + } + +@@ -822,7 +850,7 @@ test_incomplete (void) + subprocess_incomplete (); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + /* An incomplete test represents functionality that is known not to be + * implemented yet (an expected failure), so it does not cause test + * failure; but it does count as the test having been skipped, which +@@ -839,7 +867,7 @@ test_subprocess_timed_out (void) + g_usleep (1000000); + return; + } +- g_test_trap_subprocess (NULL, 50000, 0); ++ g_test_trap_subprocess (NULL, 50000, G_TEST_SUBPROCESS_DEFAULT); + g_assert_true (g_test_trap_reached_timeout ()); + } + +diff --git a/glib/tests/thread-pool.c b/glib/tests/thread-pool.c +index 5c70815..23ee27e 100644 +--- a/glib/tests/thread-pool.c ++++ b/glib/tests/thread-pool.c +@@ -108,7 +108,7 @@ test_create_first_pool (gconstpointer shared_first) + + if (!g_test_subprocess ()) + { +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + return; + } +diff --git a/glib/tests/utils.c b/glib/tests/utils.c +index 11fed55..dcdc5a6 100644 +--- a/glib/tests/utils.c ++++ b/glib/tests/utils.c +@@ -523,7 +523,7 @@ test_debug (void) + g_assert_cmpint (res, ==, 0); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stderr ("*Supported debug values: key1 key2 key3 all help*"); + } +@@ -553,7 +553,7 @@ test_codeset2 (void) + g_assert_cmpstr (c, ==, "UTF-8"); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + } + +@@ -957,7 +957,8 @@ test_aligned_mem (void) + if (g_test_undefined ()) \ + { \ + g_test_message (msg); \ +- g_test_trap_subprocess ("/utils/aligned-mem/subprocess/" #name, 0, 0); \ ++ g_test_trap_subprocess ("/utils/aligned-mem/subprocess/" #name, 0, \ ++ G_TEST_SUBPROCESS_DEFAULT); \ + g_test_trap_assert_failed (); \ + } \ + } while (0) +@@ -1025,7 +1026,7 @@ test_atexit (void) + g_atexit (atexit_func); + return; + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_passed (); + g_test_trap_assert_stdout ("*atexit called*"); + } +diff --git a/glib/tests/win32.c b/glib/tests/win32.c +index 1219973..3181657 100644 +--- a/glib/tests/win32.c ++++ b/glib/tests/win32.c +@@ -99,7 +99,8 @@ test_veh_crash_access_violation (void) + { + g_unsetenv ("G_DEBUGGER"); + /* Run a test that crashes */ +- g_test_trap_subprocess ("/win32/subprocess/access_violation", 0, 0); ++ g_test_trap_subprocess ("/win32/subprocess/access_violation", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + } + +@@ -108,7 +109,8 @@ test_veh_crash_illegal_instruction (void) + { + g_unsetenv ("G_DEBUGGER"); + /* Run a test that crashes */ +- g_test_trap_subprocess ("/win32/subprocess/illegal_instruction", 0, 0); ++ g_test_trap_subprocess ("/win32/subprocess/illegal_instruction", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + } + +@@ -125,7 +127,8 @@ test_veh_debug (void) + g_setenv ("G_DEBUGGER_OLD_CONSOLE", "1", TRUE); + g_free (command); + /* Run a test that crashes and runs a debugger */ +- g_test_trap_subprocess ("/win32/subprocess/debuggee", 0, 0); ++ g_test_trap_subprocess ("/win32/subprocess/debuggee", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("Debugger invoked, attaching to*"); + } +diff --git a/gobject/tests/param.c b/gobject/tests/param.c +index 692f07d..69401ba 100644 +--- a/gobject/tests/param.c ++++ b/gobject/tests/param.c +@@ -470,7 +470,7 @@ test_param_invalid_name (gconstpointer test_data) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_param_spec_is_valid_name (name)*"); + } +@@ -1115,7 +1115,8 @@ test_param_implement (void) + test_path = g_strdup_printf ("/param/implement/subprocess/%d-%d-%d-%d", + change_this_flag, change_this_type, + use_this_flag, use_this_type); +- g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, 0); ++ g_test_trap_subprocess (test_path, G_TIME_SPAN_SECOND, ++ G_TEST_SUBPROCESS_DEFAULT); + g_free (test_path); + + /* We want to ensure that any flags mismatch problems are reported first. */ +diff --git a/gobject/tests/properties.c b/gobject/tests/properties.c +index 3695ee1..1760030 100644 +--- a/gobject/tests/properties.c ++++ b/gobject/tests/properties.c +@@ -457,7 +457,7 @@ properties_testv_with_invalid_property_type (void) + + g_object_unref (test_obj); + } +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*foo*gint*gchararray*"); + } +@@ -495,7 +495,7 @@ properties_testv_with_invalid_property_names (void) + g_object_unref (test_obj); + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_object_new_is_valid_property*boo*"); + } +diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c +index ea9a778..8ae3c33 100644 +--- a/gobject/tests/signals.c ++++ b/gobject/tests/signals.c +@@ -1638,7 +1638,7 @@ test_lookup_invalid (void) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*WARNING*unable to look up invalid signal name*"); + } +@@ -1755,7 +1755,7 @@ test_signals_invalid_name (gconstpointer test_data) + return; + } + +- g_test_trap_subprocess (NULL, 0, 0); ++ g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*CRITICAL*g_signal_is_valid_name (signal_name)*"); + } +diff --git a/gobject/tests/testing.c b/gobject/tests/testing.c +index 5c7e663..929ed07 100644 +--- a/gobject/tests/testing.c ++++ b/gobject/tests/testing.c +@@ -52,7 +52,8 @@ test_assert_finalize_object (void) + + g_assert_finalize_object (obj); + +- g_test_trap_subprocess ("/assert/finalize_object/subprocess/bad", 0, 0); ++ g_test_trap_subprocess ("/assert/finalize_object/subprocess/bad", 0, ++ G_TEST_SUBPROCESS_DEFAULT); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*g_assert_finalize_object:*'weak_pointer' should be NULL*"); + } +-- +2.33.0 + diff --git a/backport-gthread-posix-Free-a-memory-leak-on-error-path.patch b/backport-gthread-posix-Free-a-memory-leak-on-error-path.patch deleted file mode 100644 index 41232948f4955d1380de97023bdd3f02e375280d..0000000000000000000000000000000000000000 --- a/backport-gthread-posix-Free-a-memory-leak-on-error-path.patch +++ /dev/null @@ -1,27 +0,0 @@ -From d129395fe2f22f12004526bc11ca7d407f42e4ab Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?GOUJON=20=C3=89van?= -Date: Thu, 22 Jul 2021 16:41:09 +0200 -Subject: [PATCH] g_system_thread_new: Free a memory leak on error path - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d129395fe2f22f12004526bc11ca7d407f42e4ab - ---- - glib/gthread-posix.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c -index 3d69767e67..8e2e66db54 100644 ---- a/glib/gthread-posix.c -+++ b/glib/gthread-posix.c -@@ -1331,6 +1331,7 @@ g_system_thread_new (GThreadFunc proxy, - { - g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, - "Error creating thread: %s", g_strerror (ret)); -+ g_free (thread->thread.name); - g_slice_free (GThreadPosix, thread); - return NULL; - } --- -GitLab - diff --git a/backport-gtype-Add-G_TYPE_FLAG_NONE.patch b/backport-gtype-Add-G_TYPE_FLAG_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f03059311dc4194c7d99f4e492f0ec54b6db35f --- /dev/null +++ b/backport-gtype-Add-G_TYPE_FLAG_NONE.patch @@ -0,0 +1,64 @@ +From 5e164c661537f6b6ef5adcf0fac949959ef9ffd5 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 31 Mar 2022 13:58:36 +0100 +Subject: [PATCH] gtype: Add G_TYPE_FLAG_NONE + +This makes code that sets no flags a bit more self-documenting: +using G_TYPE_FLAG_NONE makes it clearer that no special behaviour is +required than literal 0, and clearer that there is no weird casting +between types than (GTypeFlags) 0. + +GTypeFlags and GTypeFundamentalFlags occupy the same namespace and the +same bitfield, so I intentionally haven't added +G_TYPE_FUNDAMENTAL_FLAGS_NONE. + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5e164c661537f6b6ef5adcf0fac949959ef9ffd5 + +--- + gobject/gtype.h | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/gobject/gtype.h b/gobject/gtype.h +index 66cac1fc58..73d665626b 100644 +--- a/gobject/gtype.h ++++ b/gobject/gtype.h +@@ -1030,6 +1030,8 @@ typedef void (*GTypeInterfaceCheckFunc) (gpointer check_data, + */ + typedef enum /*< skip >*/ + { ++ /* There is no G_TYPE_FUNDAMENTAL_FLAGS_NONE: this is implemented to use ++ * the same bits as GTypeFlags */ + G_TYPE_FLAG_CLASSED = (1 << 0), + G_TYPE_FLAG_INSTANTIATABLE = (1 << 1), + G_TYPE_FLAG_DERIVABLE = (1 << 2), +@@ -1037,6 +1039,7 @@ typedef enum /*< skip >*/ + } GTypeFundamentalFlags; + /** + * GTypeFlags: ++ * @G_TYPE_FLAG_NONE: No special flags. Since: 2.74 + * @G_TYPE_FLAG_ABSTRACT: Indicates an abstract type. No instances can be + * created for an abstract type + * @G_TYPE_FLAG_VALUE_ABSTRACT: Indicates an abstract value type, i.e. a type +@@ -1049,6 +1052,7 @@ typedef enum /*< skip >*/ + */ + typedef enum /*< skip >*/ + { ++ G_TYPE_FLAG_NONE GLIB_AVAILABLE_ENUMERATOR_IN_2_74 = 0, + G_TYPE_FLAG_ABSTRACT = (1 << 4), + G_TYPE_FLAG_VALUE_ABSTRACT = (1 << 5), + G_TYPE_FLAG_FINAL GLIB_AVAILABLE_ENUMERATOR_IN_2_70 = (1 << 6) +@@ -2180,6 +2184,8 @@ type_name##_get_type_once (void) \ + _G_DEFINE_TYPE_EXTENDED_BEGIN_PRE(TypeName, type_name, TYPE_PARENT) \ + _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \ + ++/* Intentionally using (GTypeFlags) 0 instead of G_TYPE_FLAG_NONE here, ++ * to avoid deprecation warnings with older GLIB_VERSION_MAX_ALLOWED */ + #define _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PREREQ) \ + \ + static void type_name##_default_init (TypeName##Interface *klass); \ +-- +GitLab + diff --git a/backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch b/backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch deleted file mode 100644 index 4877e527a9827c3319681bb46141f0674f87432b..0000000000000000000000000000000000000000 --- a/backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5419228f632af830d9117c142a1c7c1a9708cc08 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:26:20 +0300 -Subject: [PATCH] gtype: Fix pointer being dereferenced despite NULL check - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/5419228f632af830d9117c142a1c7c1a9708cc08 - ---- - gobject/gtype.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/gobject/gtype.c b/gobject/gtype.c -index 34f62ecba5..26ec30b7b7 100644 ---- a/gobject/gtype.c -+++ b/gobject/gtype.c -@@ -3159,11 +3159,14 @@ g_type_class_peek_parent (gpointer g_class) - g_return_val_if_fail (g_class != NULL, NULL); - - node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class)); -+ -+ g_return_val_if_fail (node != NULL, NULL); -+ - /* We used to acquire a read lock here. That is not necessary, since - * parent->data->class.class is constant as long as the derived class - * exists. - */ -- if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node)) -+ if (node->is_classed && node->data && NODE_PARENT_TYPE (node)) - { - node = lookup_type_node_I (NODE_PARENT_TYPE (node)); - class = node->data->class.class; --- -GitLab - diff --git a/backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch b/backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch deleted file mode 100644 index 3e978a0092f77fb069b226379ab78286f4101198..0000000000000000000000000000000000000000 --- a/backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch +++ /dev/null @@ -1,58 +0,0 @@ -From bb40105fe95b5d95e31715ddb210380d381a1e26 Mon Sep 17 00:00:00 2001 -From: Jamie Bainbridge -Date: Wed, 8 Sep 2021 12:08:17 +1000 -Subject: [PATCH] gutils: Avoid segfault in g_get_user_database_entry - -g_get_user_database_entry() capitalises the first letter of pw_name -with g_ascii_toupper (pw->pw_name[0]). - -However, the manpage for getpwnam() and getpwuid() says the result of -those calls "may point to a static area". GLib is then trying to edit -static memory which belongs to a shared library, so segfaults. - -The reentrant variants of the above calls are supposed to fill the user -buffer supplied to them, however Michael Catanzaro also found a bug in -systemd where the data is not copied to the user buffer and still points -to static memory, resulting in the same sort of segfault. See: -https://github.com/systemd/systemd/issues/20679 - -Solve both these cases in GLib by copying pw_name off to a temporary -variable, set uppercase on that variable, and use the variable to join -into the desired string. Free the variable after it is no longer needed. - -Signed-off-by: Jamie Bainbridge - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/bb40105fe95b5d95e31715ddb210380d381a1e26 - ---- - glib/gutils.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/glib/gutils.c b/glib/gutils.c -index b7a2113d41..4bccd72297 100644 ---- a/glib/gutils.c -+++ b/glib/gutils.c -@@ -692,14 +692,17 @@ g_get_user_database_entry (void) - { - gchar **gecos_fields; - gchar **name_parts; -+ gchar *uppercase_pw_name; - - /* split the gecos field and substitute '&' */ - gecos_fields = g_strsplit (pw->pw_gecos, ",", 0); - name_parts = g_strsplit (gecos_fields[0], "&", 0); -- pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]); -- e.real_name = g_strjoinv (pw->pw_name, name_parts); -+ uppercase_pw_name = g_strdup (pw->pw_name); -+ uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]); -+ e.real_name = g_strjoinv (uppercase_pw_name, name_parts); - g_strfreev (gecos_fields); - g_strfreev (name_parts); -+ g_free (uppercase_pw_name); - } - #endif - --- -GitLab - diff --git a/backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch b/backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch deleted file mode 100644 index 50392fc47533342e7529139adfca2cf627664eac..0000000000000000000000000000000000000000 --- a/backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 05dffc1a7f562e9c8c6c21b67f99204f7a7b4e27 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:20:26 +0300 -Subject: [PATCH] gvariant: Fix memory leak on a TYPE_CHECK failure - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/05dffc1a7f562e9c8c6c21b67f99204f7a7b4e27 - ---- - glib/gvariant.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index a9bb99c647..4a9704c19c 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -800,7 +800,13 @@ g_variant_new_array (const GVariantType *child_type, - - for (i = 0; i < n_children; i++) - { -- TYPE_CHECK (children[i], child_type, NULL); -+ if G_UNLIKELY (!g_variant_is_of_type (children[i], child_type)) -+ { -+ while (i != 0) -+ g_variant_unref (my_children[--i]); -+ g_free (my_children); -+ g_return_val_if_fail (g_variant_is_of_type (children[i], child_type), NULL); -+ } - my_children[i] = g_variant_ref_sink (children[i]); - trusted &= g_variant_is_trusted (children[i]); - } --- -GitLab - diff --git a/backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch b/backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch deleted file mode 100644 index 29217873ea7ccf6e7020a389d6d87c2f53c70caf..0000000000000000000000000000000000000000 --- a/backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 7f6ce4d8d234996b523b71abef139f1c80c88254 Mon Sep 17 00:00:00 2001 -From: Egor Bychin -Date: Mon, 11 Oct 2021 14:24:12 +0300 -Subject: [PATCH] gvariant: Fix pointers being dereferenced despite NULL checks - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7f6ce4d8d234996b523b71abef139f1c80c88254 - ---- - glib/gvariant.c | 14 ++++++++------ - 1 file changed, 8 insertions(+), 6 deletions(-) - -diff --git a/glib/gvariant.c b/glib/gvariant.c -index 4a9704c19c..5fa6a82685 100644 ---- a/glib/gvariant.c -+++ b/glib/gvariant.c -@@ -3196,8 +3196,7 @@ struct heap_builder - #define GVSB_MAGIC ((gsize) 1033660112u) - #define GVSB_MAGIC_PARTIAL ((gsize) 2942751021u) - #define GVHB_MAGIC ((gsize) 3087242682u) --#define is_valid_builder(b) (b != NULL && \ -- GVSB(b)->magic == GVSB_MAGIC) -+#define is_valid_builder(b) (GVSB(b)->magic == GVSB_MAGIC) - #define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC) - - /* Just to make sure that by adding a union to GVariantBuilder, we -@@ -3207,7 +3206,9 @@ G_STATIC_ASSERT (sizeof (GVariantBuilder) == sizeof (gsize[16])); - static gboolean - ensure_valid_builder (GVariantBuilder *builder) - { -- if (is_valid_builder (builder)) -+ if (builder == NULL) -+ return FALSE; -+ else if (is_valid_builder (builder)) - return TRUE; - if (builder->u.s.partial_magic == GVSB_MAGIC_PARTIAL) - { -@@ -3853,8 +3854,7 @@ struct heap_dict - #define GVSD_MAGIC ((gsize) 2579507750u) - #define GVSD_MAGIC_PARTIAL ((gsize) 3488698669u) - #define GVHD_MAGIC ((gsize) 2450270775u) --#define is_valid_dict(d) (d != NULL && \ -- GVSD(d)->magic == GVSD_MAGIC) -+#define is_valid_dict(d) (GVSD(d)->magic == GVSD_MAGIC) - #define is_valid_heap_dict(d) (GVHD(d)->magic == GVHD_MAGIC) - - /* Just to make sure that by adding a union to GVariantDict, we didn't -@@ -3864,7 +3864,9 @@ G_STATIC_ASSERT (sizeof (GVariantDict) == sizeof (gsize[16])); - static gboolean - ensure_valid_dict (GVariantDict *dict) - { -- if (is_valid_dict (dict)) -+ if (dict == NULL) -+ return FALSE; -+ else if (is_valid_dict (dict)) - return TRUE; - if (dict->u.s.partial_magic == GVSD_MAGIC_PARTIAL) - { --- -GitLab - diff --git a/backport-regex-Actually-check-for-match-options-changes.patch b/backport-regex-Actually-check-for-match-options-changes.patch new file mode 100644 index 0000000000000000000000000000000000000000..a87c890e419fc889726516e8ecde76b4be0eb730 --- /dev/null +++ b/backport-regex-Actually-check-for-match-options-changes.patch @@ -0,0 +1,25 @@ +From d4966911e6b35d8923bc6cd58e7cb8a1b0e09d4a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch b/backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8ddc8ba3db1418f4975541250c3a3f1b9414ed5 --- /dev/null +++ b/backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch @@ -0,0 +1,193 @@ +From 23c1b401d8c78c2c66d55b94d7d833210d518853 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Add-test-for-gtksourceview-regression.patch b/backport-regex-Add-test-for-gtksourceview-regression.patch new file mode 100644 index 0000000000000000000000000000000000000000..b109dfebf0731f10680feac0649d17f60a75456a --- /dev/null +++ b/backport-regex-Add-test-for-gtksourceview-regression.patch @@ -0,0 +1,33 @@ +From df66951b96fdb800c0b6bd11292bb23fbcd6ed85 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +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 + diff --git a/backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch b/backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch new file mode 100644 index 0000000000000000000000000000000000000000..f46b0af6db54a4acc59771f5f4a66a542b523f75 --- /dev/null +++ b/backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch @@ -0,0 +1,38 @@ +From fe1c2628d52ca67ffe59420a0b4d371893795e62 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Compute-the-offsets-size-based-on-match-results.patch b/backport-regex-Compute-the-offsets-size-based-on-match-results.patch new file mode 100644 index 0000000000000000000000000000000000000000..8579bdaf2316c9eee34096458a543d17257dbbd2 --- /dev/null +++ b/backport-regex-Compute-the-offsets-size-based-on-match-results.patch @@ -0,0 +1,59 @@ +From e8628a7ed59e54b5a5e498de0375f101a4e76e64 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch b/backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..d09aef854de1d5bcd697e02e4a4f1cd26b546789 --- /dev/null +++ b/backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch @@ -0,0 +1,1062 @@ +From d639c4ec009537b743dcd2209184638d9f5d68b9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 6 Sep 2022 14:49:10 +0200 +Subject: [PATCH] regex: Do not mix PCRE2 Compile, Match, Newline and BSR flags + +As per the PCRE2 port we still used to try to map the old GRegex flags +(PCRE1 based) with the new PCRE2 ones, but doing that we were also +mixing flags with enums, leading to unexpected behaviors when trying to +get new line and BSR options out of bigger flags arrays. + +So, avoid doing any mapping and store the values as native PCRE2 flags +internally and converting them back only when requested. + +This fixes some regressions on newline handling. + +Fixes: #2729 +Fixes: #2688 +Fixes: GNOME/gtksourceview#278 +--- + glib/gregex.c | 637 +++++++++++++++++++++++---------------------- + glib/tests/regex.c | 18 ++ + 2 files changed, 341 insertions(+), 314 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index a16ea98..95695f7 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -3,6 +3,7 @@ + * Copyright (C) 1999, 2000 Scott Wimer + * Copyright (C) 2004, Matthias Clasen + * Copyright (C) 2005 - 2007, Marco Barisione ++ * Copyright (C) 2022, Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -108,62 +109,105 @@ + * library written by Philip Hazel. + */ + +-/* Signifies that flags have already been converted from pcre1 to pcre2. The +- * value 0x04000000u is also the value of PCRE2_MATCH_INVALID_UTF in pcre2.h, +- * but it is not used in gregex, so we can reuse it for this flag. +- */ +-#define G_REGEX_FLAGS_CONVERTED 0x04000000u ++#define G_REGEX_PCRE_GENERIC_MASK (PCRE2_ANCHORED | \ ++ PCRE2_NO_UTF_CHECK | \ ++ PCRE2_ENDANCHORED) ++ + /* Mask of all the possible values for GRegexCompileFlags. */ +-#define G_REGEX_COMPILE_MASK (PCRE2_CASELESS | \ +- PCRE2_MULTILINE | \ +- PCRE2_DOTALL | \ +- PCRE2_EXTENDED | \ +- PCRE2_ANCHORED | \ +- PCRE2_DOLLAR_ENDONLY | \ +- PCRE2_UNGREEDY | \ +- PCRE2_UTF | \ +- PCRE2_NO_AUTO_CAPTURE | \ +- PCRE2_FIRSTLINE | \ +- PCRE2_DUPNAMES | \ +- PCRE2_NEWLINE_CR | \ +- PCRE2_NEWLINE_LF | \ +- PCRE2_NEWLINE_CRLF | \ +- PCRE2_NEWLINE_ANYCRLF | \ +- PCRE2_BSR_ANYCRLF | \ +- G_REGEX_FLAGS_CONVERTED) +- +-/* Mask of all GRegexCompileFlags values that are (not) passed trough to PCRE */ +-#define G_REGEX_COMPILE_PCRE_MASK (G_REGEX_COMPILE_MASK & ~G_REGEX_COMPILE_NONPCRE_MASK) +-#define G_REGEX_COMPILE_NONPCRE_MASK (PCRE2_UTF | \ +- G_REGEX_FLAGS_CONVERTED) ++#define G_REGEX_COMPILE_MASK (G_REGEX_DEFAULT | \ ++ G_REGEX_CASELESS | \ ++ G_REGEX_MULTILINE | \ ++ G_REGEX_DOTALL | \ ++ G_REGEX_EXTENDED | \ ++ G_REGEX_ANCHORED | \ ++ G_REGEX_DOLLAR_ENDONLY | \ ++ G_REGEX_UNGREEDY | \ ++ G_REGEX_RAW | \ ++ G_REGEX_NO_AUTO_CAPTURE | \ ++ G_REGEX_OPTIMIZE | \ ++ G_REGEX_FIRSTLINE | \ ++ G_REGEX_DUPNAMES | \ ++ G_REGEX_NEWLINE_CR | \ ++ G_REGEX_NEWLINE_LF | \ ++ G_REGEX_NEWLINE_CRLF | \ ++ G_REGEX_NEWLINE_ANYCRLF | \ ++ G_REGEX_BSR_ANYCRLF) ++ ++#define G_REGEX_PCRE2_COMPILE_MASK (PCRE2_ALLOW_EMPTY_CLASS | \ ++ PCRE2_ALT_BSUX | \ ++ PCRE2_AUTO_CALLOUT | \ ++ PCRE2_CASELESS | \ ++ PCRE2_DOLLAR_ENDONLY | \ ++ PCRE2_DOTALL | \ ++ PCRE2_DUPNAMES | \ ++ PCRE2_EXTENDED | \ ++ PCRE2_FIRSTLINE | \ ++ PCRE2_MATCH_UNSET_BACKREF | \ ++ PCRE2_MULTILINE | \ ++ PCRE2_NEVER_UCP | \ ++ PCRE2_NEVER_UTF | \ ++ PCRE2_NO_AUTO_CAPTURE | \ ++ PCRE2_NO_AUTO_POSSESS | \ ++ PCRE2_NO_DOTSTAR_ANCHOR | \ ++ PCRE2_NO_START_OPTIMIZE | \ ++ PCRE2_UCP | \ ++ PCRE2_UNGREEDY | \ ++ PCRE2_UTF | \ ++ PCRE2_NEVER_BACKSLASH_C | \ ++ PCRE2_ALT_CIRCUMFLEX | \ ++ PCRE2_ALT_VERBNAMES | \ ++ PCRE2_USE_OFFSET_LIMIT | \ ++ PCRE2_EXTENDED_MORE | \ ++ PCRE2_LITERAL | \ ++ PCRE2_MATCH_INVALID_UTF | \ ++ G_REGEX_PCRE_GENERIC_MASK) ++ ++#define G_REGEX_COMPILE_NONPCRE_MASK (PCRE2_UTF) + + /* Mask of all the possible values for GRegexMatchFlags. */ +-#define G_REGEX_MATCH_MASK (PCRE2_ANCHORED | \ +- PCRE2_NOTBOL | \ +- PCRE2_NOTEOL | \ +- PCRE2_NOTEMPTY | \ +- PCRE2_NEWLINE_CR | \ +- PCRE2_NEWLINE_LF | \ +- PCRE2_NEWLINE_CRLF | \ +- PCRE2_NEWLINE_ANY | \ +- PCRE2_NEWLINE_ANYCRLF | \ +- PCRE2_BSR_ANYCRLF | \ +- PCRE2_BSR_UNICODE | \ +- PCRE2_PARTIAL_SOFT | \ +- PCRE2_PARTIAL_HARD | \ +- PCRE2_NOTEMPTY_ATSTART | \ +- G_REGEX_FLAGS_CONVERTED) +- ++#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_DEFAULT | \ ++ G_REGEX_MATCH_ANCHORED | \ ++ G_REGEX_MATCH_NOTBOL | \ ++ G_REGEX_MATCH_NOTEOL | \ ++ G_REGEX_MATCH_NOTEMPTY | \ ++ G_REGEX_MATCH_PARTIAL | \ ++ G_REGEX_MATCH_NEWLINE_CR | \ ++ G_REGEX_MATCH_NEWLINE_LF | \ ++ G_REGEX_MATCH_NEWLINE_CRLF | \ ++ G_REGEX_MATCH_NEWLINE_ANY | \ ++ G_REGEX_MATCH_NEWLINE_ANYCRLF | \ ++ G_REGEX_MATCH_BSR_ANYCRLF | \ ++ G_REGEX_MATCH_BSR_ANY | \ ++ G_REGEX_MATCH_PARTIAL_SOFT | \ ++ G_REGEX_MATCH_PARTIAL_HARD | \ ++ G_REGEX_MATCH_NOTEMPTY_ATSTART) ++ ++#define G_REGEX_PCRE2_MATCH_MASK (PCRE2_NOTBOL |\ ++ PCRE2_NOTEOL |\ ++ PCRE2_NOTEMPTY |\ ++ PCRE2_NOTEMPTY_ATSTART |\ ++ PCRE2_PARTIAL_SOFT |\ ++ PCRE2_PARTIAL_HARD |\ ++ PCRE2_NO_JIT |\ ++ PCRE2_COPY_MATCHED_SUBJECT |\ ++ G_REGEX_PCRE_GENERIC_MASK) ++ ++/* TODO: Support PCRE2_NEWLINE_NUL */ + #define G_REGEX_NEWLINE_MASK (PCRE2_NEWLINE_CR | \ + PCRE2_NEWLINE_LF | \ + PCRE2_NEWLINE_CRLF | \ + PCRE2_NEWLINE_ANYCRLF) + +-#define G_REGEX_MATCH_NEWLINE_MASK (PCRE2_NEWLINE_CR | \ +- PCRE2_NEWLINE_LF | \ +- PCRE2_NEWLINE_CRLF | \ +- PCRE2_NEWLINE_ANYCRLF | \ +- PCRE2_NEWLINE_ANY) ++#define G_REGEX_COMPILE_NEWLINE_MASK (G_REGEX_NEWLINE_CR | \ ++ G_REGEX_NEWLINE_LF | \ ++ G_REGEX_NEWLINE_CRLF | \ ++ G_REGEX_NEWLINE_ANYCRLF) ++ ++#define G_REGEX_MATCH_NEWLINE_MASK (G_REGEX_MATCH_NEWLINE_CR | \ ++ G_REGEX_MATCH_NEWLINE_LF | \ ++ G_REGEX_MATCH_NEWLINE_CRLF | \ ++ G_REGEX_MATCH_NEWLINE_ANY | \ ++ G_REGEX_MATCH_NEWLINE_ANYCRLF) + + /* if the string is in UTF-8 use g_utf8_ functions, else use + * use just +/- 1. */ +@@ -178,7 +222,7 @@ struct _GMatchInfo + { + gint ref_count; /* the ref count (atomic) */ + GRegex *regex; /* the regex */ +- GRegexMatchFlags match_opts; /* options used at match time on 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 */ + gint pos; /* position in the string where last match left off */ +@@ -204,9 +248,10 @@ struct _GRegex + gint ref_count; /* the ref count for the immutable part (atomic) */ + gchar *pattern; /* the pattern */ + pcre2_code *pcre_re; /* compiled form of the pattern */ +- GRegexCompileFlags compile_opts; /* options used at compile time on the pattern, pcre2 values */ ++ uint32_t compile_opts; /* options used at compile time on the pattern, pcre2 values */ + GRegexCompileFlags orig_compile_opts; /* options used at compile time on the pattern, gregex values */ +- GRegexMatchFlags match_opts; /* options used at match time on the regex */ ++ 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 */ + JITStatus jit_status; /* indicates the status of jit compiler for this compiled regex */ + }; +@@ -223,197 +268,182 @@ static GList *split_replacement (const gchar *replacement, + GError **error); + static void free_interpolation_data (InterpolationData *data); + +-static gint +-map_to_pcre2_compile_flags (gint pcre1_flags) ++static uint32_t ++get_pcre2_compile_options (GRegexCompileFlags compile_flags) + { +- /* Maps compile flags from pcre1 to pcre2 values +- */ +- gint pcre2_flags = G_REGEX_FLAGS_CONVERTED; +- +- if (pcre1_flags & G_REGEX_FLAGS_CONVERTED) +- return pcre1_flags; ++ /* Maps compile flags to pcre2 values */ ++ uint32_t pcre2_flags = 0; + +- if (pcre1_flags & G_REGEX_CASELESS) ++ if (compile_flags & G_REGEX_CASELESS) + pcre2_flags |= PCRE2_CASELESS; +- if (pcre1_flags & G_REGEX_MULTILINE) ++ if (compile_flags & G_REGEX_MULTILINE) + pcre2_flags |= PCRE2_MULTILINE; +- if (pcre1_flags & G_REGEX_DOTALL) ++ if (compile_flags & G_REGEX_DOTALL) + pcre2_flags |= PCRE2_DOTALL; +- if (pcre1_flags & G_REGEX_EXTENDED) ++ if (compile_flags & G_REGEX_EXTENDED) + pcre2_flags |= PCRE2_EXTENDED; +- if (pcre1_flags & G_REGEX_ANCHORED) ++ if (compile_flags & G_REGEX_ANCHORED) + pcre2_flags |= PCRE2_ANCHORED; +- if (pcre1_flags & G_REGEX_DOLLAR_ENDONLY) ++ if (compile_flags & G_REGEX_DOLLAR_ENDONLY) + pcre2_flags |= PCRE2_DOLLAR_ENDONLY; +- if (pcre1_flags & G_REGEX_UNGREEDY) ++ if (compile_flags & G_REGEX_UNGREEDY) + pcre2_flags |= PCRE2_UNGREEDY; +- if (!(pcre1_flags & G_REGEX_RAW)) ++ if (!(compile_flags & G_REGEX_RAW)) + pcre2_flags |= PCRE2_UTF; +- if (pcre1_flags & G_REGEX_NO_AUTO_CAPTURE) ++ if (compile_flags & G_REGEX_NO_AUTO_CAPTURE) + pcre2_flags |= PCRE2_NO_AUTO_CAPTURE; +- if (pcre1_flags & G_REGEX_FIRSTLINE) ++ if (compile_flags & G_REGEX_FIRSTLINE) + pcre2_flags |= PCRE2_FIRSTLINE; +- if (pcre1_flags & G_REGEX_DUPNAMES) ++ if (compile_flags & G_REGEX_DUPNAMES) + pcre2_flags |= PCRE2_DUPNAMES; +- if (pcre1_flags & G_REGEX_NEWLINE_CR) +- pcre2_flags |= PCRE2_NEWLINE_CR; +- if (pcre1_flags & G_REGEX_NEWLINE_LF) +- pcre2_flags |= PCRE2_NEWLINE_LF; +- /* Check for exact match for a composite flag */ +- if ((pcre1_flags & G_REGEX_NEWLINE_CRLF) == G_REGEX_NEWLINE_CRLF) +- pcre2_flags |= PCRE2_NEWLINE_CRLF; +- /* Check for exact match for a composite flag */ +- if ((pcre1_flags & G_REGEX_NEWLINE_ANYCRLF) == G_REGEX_NEWLINE_ANYCRLF) +- pcre2_flags |= PCRE2_NEWLINE_ANYCRLF; +- if (pcre1_flags & G_REGEX_BSR_ANYCRLF) +- pcre2_flags |= PCRE2_BSR_ANYCRLF; +- +- /* these are not available in pcre2, but we use G_REGEX_OPTIMIZE as a special +- * case to request JIT compilation */ +- if (pcre1_flags & G_REGEX_OPTIMIZE) +- pcre2_flags |= 0; +-G_GNUC_BEGIN_IGNORE_DEPRECATIONS +- if (pcre1_flags & G_REGEX_JAVASCRIPT_COMPAT) +- pcre2_flags |= 0; +-G_GNUC_END_IGNORE_DEPRECATIONS +- +- return pcre2_flags; ++ ++ return pcre2_flags & G_REGEX_PCRE2_COMPILE_MASK; + } + +-static gint +-map_to_pcre2_match_flags (gint pcre1_flags) ++static uint32_t ++get_pcre2_match_options (GRegexMatchFlags match_flags, ++ GRegexCompileFlags compile_flags) + { +- /* Maps match flags from pcre1 to pcre2 values +- */ +- gint pcre2_flags = G_REGEX_FLAGS_CONVERTED; +- +- if (pcre1_flags & G_REGEX_FLAGS_CONVERTED) +- return pcre1_flags; ++ /* Maps match flags to pcre2 values */ ++ uint32_t pcre2_flags = 0; + +- if (pcre1_flags & G_REGEX_MATCH_ANCHORED) ++ if (match_flags & G_REGEX_MATCH_ANCHORED) + pcre2_flags |= PCRE2_ANCHORED; +- if (pcre1_flags & G_REGEX_MATCH_NOTBOL) ++ if (match_flags & G_REGEX_MATCH_NOTBOL) + pcre2_flags |= PCRE2_NOTBOL; +- if (pcre1_flags & G_REGEX_MATCH_NOTEOL) ++ if (match_flags & G_REGEX_MATCH_NOTEOL) + pcre2_flags |= PCRE2_NOTEOL; +- if (pcre1_flags & G_REGEX_MATCH_NOTEMPTY) ++ if (match_flags & G_REGEX_MATCH_NOTEMPTY) + pcre2_flags |= PCRE2_NOTEMPTY; +- if (pcre1_flags & G_REGEX_MATCH_NEWLINE_CR) +- pcre2_flags |= PCRE2_NEWLINE_CR; +- if (pcre1_flags & G_REGEX_MATCH_NEWLINE_LF) +- pcre2_flags |= PCRE2_NEWLINE_LF; +- /* Check for exact match for a composite flag */ +- if ((pcre1_flags & G_REGEX_MATCH_NEWLINE_CRLF) == G_REGEX_MATCH_NEWLINE_CRLF) +- pcre2_flags |= PCRE2_NEWLINE_CRLF; +- if (pcre1_flags & G_REGEX_MATCH_NEWLINE_ANY) +- pcre2_flags |= PCRE2_NEWLINE_ANY; +- /* Check for exact match for a composite flag */ +- if ((pcre1_flags & G_REGEX_MATCH_NEWLINE_ANYCRLF) == G_REGEX_MATCH_NEWLINE_ANYCRLF) +- pcre2_flags |= PCRE2_NEWLINE_ANYCRLF; +- if (pcre1_flags & G_REGEX_MATCH_BSR_ANYCRLF) +- pcre2_flags |= PCRE2_BSR_ANYCRLF; +- if (pcre1_flags & G_REGEX_MATCH_BSR_ANY) +- pcre2_flags |= PCRE2_BSR_UNICODE; +- if (pcre1_flags & G_REGEX_MATCH_PARTIAL_SOFT) ++ if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT) + pcre2_flags |= PCRE2_PARTIAL_SOFT; +- if (pcre1_flags & G_REGEX_MATCH_PARTIAL_HARD) ++ if (match_flags & G_REGEX_MATCH_PARTIAL_HARD) + pcre2_flags |= PCRE2_PARTIAL_HARD; +- if (pcre1_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART) ++ if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART) + pcre2_flags |= PCRE2_NOTEMPTY_ATSTART; + +- return pcre2_flags; ++ if (compile_flags & G_REGEX_RAW) ++ pcre2_flags |= PCRE2_NO_UTF_CHECK; ++ ++ return pcre2_flags & G_REGEX_PCRE2_MATCH_MASK; + } + +-static gint +-map_to_pcre1_compile_flags (gint pcre2_flags) ++static GRegexCompileFlags ++g_regex_compile_flags_from_pcre2 (uint32_t pcre2_flags) + { +- /* Maps compile flags from pcre2 to pcre1 values +- */ +- gint pcre1_flags = 0; +- +- if (!(pcre2_flags & G_REGEX_FLAGS_CONVERTED)) +- return pcre2_flags; ++ GRegexCompileFlags compile_flags = G_REGEX_DEFAULT; + + if (pcre2_flags & PCRE2_CASELESS) +- pcre1_flags |= G_REGEX_CASELESS; ++ compile_flags |= G_REGEX_CASELESS; + if (pcre2_flags & PCRE2_MULTILINE) +- pcre1_flags |= G_REGEX_MULTILINE; ++ compile_flags |= G_REGEX_MULTILINE; + if (pcre2_flags & PCRE2_DOTALL) +- pcre1_flags |= G_REGEX_DOTALL; ++ compile_flags |= G_REGEX_DOTALL; + if (pcre2_flags & PCRE2_EXTENDED) +- pcre1_flags |= G_REGEX_EXTENDED; ++ compile_flags |= G_REGEX_EXTENDED; + if (pcre2_flags & PCRE2_ANCHORED) +- pcre1_flags |= G_REGEX_ANCHORED; ++ compile_flags |= G_REGEX_ANCHORED; + if (pcre2_flags & PCRE2_DOLLAR_ENDONLY) +- pcre1_flags |= G_REGEX_DOLLAR_ENDONLY; ++ compile_flags |= G_REGEX_DOLLAR_ENDONLY; + if (pcre2_flags & PCRE2_UNGREEDY) +- pcre1_flags |= G_REGEX_UNGREEDY; ++ compile_flags |= G_REGEX_UNGREEDY; + if (!(pcre2_flags & PCRE2_UTF)) +- pcre1_flags |= G_REGEX_RAW; ++ compile_flags |= G_REGEX_RAW; + if (pcre2_flags & PCRE2_NO_AUTO_CAPTURE) +- pcre1_flags |= G_REGEX_NO_AUTO_CAPTURE; ++ compile_flags |= G_REGEX_NO_AUTO_CAPTURE; + if (pcre2_flags & PCRE2_FIRSTLINE) +- pcre1_flags |= G_REGEX_FIRSTLINE; ++ compile_flags |= G_REGEX_FIRSTLINE; + if (pcre2_flags & PCRE2_DUPNAMES) +- pcre1_flags |= G_REGEX_DUPNAMES; +- if (pcre2_flags & PCRE2_NEWLINE_CR) +- pcre1_flags |= G_REGEX_NEWLINE_CR; +- if (pcre2_flags & PCRE2_NEWLINE_LF) +- pcre1_flags |= G_REGEX_NEWLINE_LF; +- /* Check for exact match for a composite flag */ +- if ((pcre2_flags & PCRE2_NEWLINE_CRLF) == PCRE2_NEWLINE_CRLF) +- pcre1_flags |= G_REGEX_NEWLINE_CRLF; +- /* Check for exact match for a composite flag */ +- if ((pcre2_flags & PCRE2_NEWLINE_ANYCRLF) == PCRE2_NEWLINE_ANYCRLF) +- pcre1_flags |= G_REGEX_NEWLINE_ANYCRLF; +- if (pcre2_flags & PCRE2_BSR_ANYCRLF) +- pcre1_flags |= G_REGEX_BSR_ANYCRLF; +- +- return pcre1_flags; ++ compile_flags |= G_REGEX_DUPNAMES; ++ ++ return compile_flags & G_REGEX_COMPILE_MASK; + } + +-static gint +-map_to_pcre1_match_flags (gint pcre2_flags) ++static GRegexMatchFlags ++g_regex_match_flags_from_pcre2 (uint32_t pcre2_flags) + { +- /* Maps match flags from pcre2 to pcre1 values +- */ +- gint pcre1_flags = 0; +- +- if (!(pcre2_flags & G_REGEX_FLAGS_CONVERTED)) +- return pcre2_flags; ++ GRegexMatchFlags match_flags = G_REGEX_MATCH_DEFAULT; + + if (pcre2_flags & PCRE2_ANCHORED) +- pcre1_flags |= G_REGEX_MATCH_ANCHORED; ++ match_flags |= G_REGEX_MATCH_ANCHORED; + if (pcre2_flags & PCRE2_NOTBOL) +- pcre1_flags |= G_REGEX_MATCH_NOTBOL; ++ match_flags |= G_REGEX_MATCH_NOTBOL; + if (pcre2_flags & PCRE2_NOTEOL) +- pcre1_flags |= G_REGEX_MATCH_NOTEOL; ++ match_flags |= G_REGEX_MATCH_NOTEOL; + if (pcre2_flags & PCRE2_NOTEMPTY) +- pcre1_flags |= G_REGEX_MATCH_NOTEMPTY; +- if (pcre2_flags & PCRE2_NEWLINE_CR) +- pcre1_flags |= G_REGEX_MATCH_NEWLINE_CR; +- if (pcre2_flags & PCRE2_NEWLINE_LF) +- pcre1_flags |= G_REGEX_MATCH_NEWLINE_LF; +- /* Check for exact match for a composite flag */ +- if ((pcre2_flags & PCRE2_NEWLINE_CRLF) == PCRE2_NEWLINE_CRLF) +- pcre1_flags |= G_REGEX_MATCH_NEWLINE_CRLF; +- if (pcre2_flags & PCRE2_NEWLINE_ANY) +- pcre1_flags |= G_REGEX_MATCH_NEWLINE_ANY; +- /* Check for exact match for a composite flag */ +- if ((pcre2_flags & PCRE2_NEWLINE_ANYCRLF) == PCRE2_NEWLINE_ANYCRLF) +- pcre1_flags |= G_REGEX_MATCH_NEWLINE_ANYCRLF; +- if (pcre2_flags & PCRE2_BSR_ANYCRLF) +- pcre1_flags |= G_REGEX_MATCH_BSR_ANYCRLF; +- if (pcre2_flags & PCRE2_BSR_UNICODE) +- pcre1_flags |= G_REGEX_MATCH_BSR_ANY; ++ match_flags |= G_REGEX_MATCH_NOTEMPTY; + if (pcre2_flags & PCRE2_PARTIAL_SOFT) +- pcre1_flags |= G_REGEX_MATCH_PARTIAL_SOFT; ++ match_flags |= G_REGEX_MATCH_PARTIAL_SOFT; + if (pcre2_flags & PCRE2_PARTIAL_HARD) +- pcre1_flags |= G_REGEX_MATCH_PARTIAL_HARD; ++ match_flags |= G_REGEX_MATCH_PARTIAL_HARD; + if (pcre2_flags & PCRE2_NOTEMPTY_ATSTART) +- pcre1_flags |= G_REGEX_MATCH_NOTEMPTY_ATSTART; ++ match_flags |= G_REGEX_MATCH_NOTEMPTY_ATSTART; ++ ++ return (match_flags & G_REGEX_MATCH_MASK); ++} ++ ++static uint32_t ++get_pcre2_newline_compile_options (GRegexCompileFlags compile_flags) ++{ ++ compile_flags &= G_REGEX_COMPILE_NEWLINE_MASK; ++ ++ switch (compile_flags) ++ { ++ case G_REGEX_NEWLINE_CR: ++ return PCRE2_NEWLINE_CR; ++ case G_REGEX_NEWLINE_LF: ++ return PCRE2_NEWLINE_LF; ++ case G_REGEX_NEWLINE_CRLF: ++ return PCRE2_NEWLINE_CRLF; ++ case G_REGEX_NEWLINE_ANYCRLF: ++ return PCRE2_NEWLINE_ANYCRLF; ++ default: ++ if (compile_flags != 0) ++ return 0; ++ ++ return PCRE2_NEWLINE_ANY; ++ } ++} ++ ++static uint32_t ++get_pcre2_newline_match_options (GRegexMatchFlags match_flags) ++{ ++ switch (match_flags & G_REGEX_MATCH_NEWLINE_MASK) ++ { ++ case G_REGEX_MATCH_NEWLINE_CR: ++ return PCRE2_NEWLINE_CR; ++ case G_REGEX_MATCH_NEWLINE_LF: ++ return PCRE2_NEWLINE_LF; ++ case G_REGEX_MATCH_NEWLINE_CRLF: ++ return PCRE2_NEWLINE_CRLF; ++ case G_REGEX_MATCH_NEWLINE_ANY: ++ return PCRE2_NEWLINE_ANY; ++ case G_REGEX_MATCH_NEWLINE_ANYCRLF: ++ return PCRE2_NEWLINE_ANYCRLF; ++ default: ++ return 0; ++ } ++} ++ ++static uint32_t ++get_pcre2_bsr_compile_options (GRegexCompileFlags compile_flags) ++{ ++ if (compile_flags & G_REGEX_BSR_ANYCRLF) ++ return PCRE2_BSR_ANYCRLF; + +- return pcre1_flags; ++ return PCRE2_BSR_UNICODE; ++} ++ ++static uint32_t ++get_pcre2_bsr_match_options (GRegexMatchFlags match_flags) ++{ ++ if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF) ++ return PCRE2_BSR_ANYCRLF; ++ ++ if (match_flags & G_REGEX_MATCH_BSR_ANY) ++ return PCRE2_BSR_UNICODE; ++ ++ return 0; + } + + static const gchar * +@@ -742,12 +772,12 @@ translate_compile_error (gint *errcode, const gchar **errmsg) + /* GMatchInfo */ + + static GMatchInfo * +-match_info_new (const GRegex *regex, +- const gchar *string, +- gint string_len, +- gint start_position, +- gint match_options, +- gboolean is_dfa) ++match_info_new (const GRegex *regex, ++ const gchar *string, ++ gint string_len, ++ gint start_position, ++ GRegexMatchFlags match_options, ++ gboolean is_dfa) + { + GMatchInfo *match_info; + +@@ -761,7 +791,8 @@ match_info_new (const GRegex *regex, + match_info->string_len = string_len; + match_info->matches = PCRE2_ERROR_NOMATCH; + match_info->pos = start_position; +- match_info->match_opts = match_options; ++ match_info->match_opts = ++ get_pcre2_match_options (match_options, regex->orig_compile_opts); + + pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, + &match_info->n_subpatterns); +@@ -822,8 +853,8 @@ recalc_match_offsets (GMatchInfo *match_info, + } + + static void +-enable_jit_with_match_options (GRegex *regex, +- GRegexMatchFlags match_options) ++enable_jit_with_match_options (GRegex *regex, ++ uint32_t match_options) + { + gint old_jit_options, new_jit_options, retval; + +@@ -1009,7 +1040,7 @@ g_match_info_next (GMatchInfo *match_info, + return FALSE; + } + +- opts = map_to_pcre2_match_flags (match_info->regex->match_opts | match_info->match_opts); ++ 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) +@@ -1018,7 +1049,7 @@ g_match_info_next (GMatchInfo *match_info, + (PCRE2_SPTR8) match_info->string, + match_info->string_len, + match_info->pos, +- opts & ~G_REGEX_FLAGS_CONVERTED, ++ opts, + match_info->match_data, + match_info->match_context); + } +@@ -1028,7 +1059,7 @@ g_match_info_next (GMatchInfo *match_info, + (PCRE2_SPTR8) match_info->string, + match_info->string_len, + match_info->pos, +- opts & ~G_REGEX_FLAGS_CONVERTED, ++ opts, + match_info->match_data, + match_info->match_context); + } +@@ -1563,14 +1594,14 @@ g_regex_unref (GRegex *regex) + } + } + +-/* +- * @match_options: (inout) (optional): +- */ +-static pcre2_code *regex_compile (const gchar *pattern, +- GRegexCompileFlags compile_options, +- GRegexCompileFlags *compile_options_out, +- GRegexMatchFlags *match_options, +- GError **error); ++static pcre2_code * regex_compile (const gchar *pattern, ++ uint32_t compile_options, ++ uint32_t newline_options, ++ uint32_t bsr_options, ++ GError **error); ++ ++static uint32_t get_pcre2_inline_compile_options (pcre2_code *re, ++ uint32_t compile_options); + + /** + * g_regex_new: +@@ -1596,11 +1627,10 @@ g_regex_new (const gchar *pattern, + GRegex *regex; + pcre2_code *re; + static gsize initialised = 0; +- GRegexCompileFlags orig_compile_opts; +- +- orig_compile_opts = compile_options; +- compile_options = map_to_pcre2_compile_flags (compile_options); +- match_options = map_to_pcre2_match_flags (match_options); ++ uint32_t pcre_compile_options; ++ uint32_t pcre_match_options; ++ uint32_t newline_options; ++ uint32_t bsr_options; + + g_return_val_if_fail (pattern != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); +@@ -1618,113 +1648,97 @@ g_regex_new (const gchar *pattern, + g_once_init_leave (&initialised, supports_utf8 ? 1 : 2); + } + +- if (G_UNLIKELY (initialised != 1)) ++ if (G_UNLIKELY (initialised != 1)) + { + g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, + _("PCRE library is compiled with incompatible options")); + return NULL; + } + +- switch (compile_options & G_REGEX_NEWLINE_MASK) ++ pcre_compile_options = get_pcre2_compile_options (compile_options); ++ pcre_match_options = get_pcre2_match_options (match_options, compile_options); ++ ++ newline_options = get_pcre2_newline_match_options (match_options); ++ if (newline_options == 0) ++ newline_options = get_pcre2_newline_compile_options (compile_options); ++ ++ if (newline_options == 0) + { +- case 0: /* PCRE2_NEWLINE_ANY */ +- case PCRE2_NEWLINE_CR: +- case PCRE2_NEWLINE_LF: +- case PCRE2_NEWLINE_CRLF: +- case PCRE2_NEWLINE_ANYCRLF: +- break; +- default: + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS, + "Invalid newline flags"); + return NULL; + } + +- re = regex_compile (pattern, compile_options, &compile_options, +- &match_options, error); ++ bsr_options = get_pcre2_bsr_match_options (match_options); ++ if (!bsr_options) ++ bsr_options = get_pcre2_bsr_compile_options (compile_options); ++ ++ re = regex_compile (pattern, pcre_compile_options, ++ newline_options, bsr_options, error); + if (re == NULL) + return NULL; + ++ pcre_compile_options |= ++ get_pcre2_inline_compile_options (re, pcre_compile_options); ++ + regex = g_new0 (GRegex, 1); + regex->ref_count = 1; + regex->pattern = g_strdup (pattern); + regex->pcre_re = re; +- regex->compile_opts = compile_options; +- regex->orig_compile_opts = orig_compile_opts; +- regex->match_opts = match_options; ++ regex->compile_opts = pcre_compile_options; ++ 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); + + return regex; + } + +-static gint +-extract_newline_options (const GRegexCompileFlags compile_options, +- const GRegexMatchFlags *match_options) +-{ +- gint newline_options = PCRE2_NEWLINE_ANY; +- +- if (compile_options & G_REGEX_NEWLINE_MASK) +- newline_options = compile_options & G_REGEX_NEWLINE_MASK; +- if (match_options && *match_options & G_REGEX_MATCH_NEWLINE_MASK) +- newline_options = *match_options & G_REGEX_MATCH_NEWLINE_MASK; +- +- return newline_options; +-} +- +-static gint +-extract_bsr_options (const GRegexCompileFlags compile_options, +- const GRegexMatchFlags *match_options) +-{ +- gint bsr_options = PCRE2_BSR_UNICODE; +- +- if (compile_options & PCRE2_BSR_ANYCRLF) +- bsr_options = PCRE2_BSR_ANYCRLF; +- if (match_options && *match_options & PCRE2_BSR_ANYCRLF) +- bsr_options = PCRE2_BSR_ANYCRLF; +- if (match_options && *match_options & PCRE2_BSR_UNICODE) +- bsr_options = PCRE2_BSR_UNICODE; +- +- return bsr_options; +-} +- + static pcre2_code * +-regex_compile (const gchar *pattern, +- GRegexCompileFlags compile_options, +- GRegexCompileFlags *compile_options_out, +- GRegexMatchFlags *match_options, +- GError **error) ++regex_compile (const gchar *pattern, ++ uint32_t compile_options, ++ uint32_t newline_options, ++ uint32_t bsr_options, ++ GError **error) + { + pcre2_code *re; + pcre2_compile_context *context; + const gchar *errmsg; + PCRE2_SIZE erroffset; + gint errcode; +- GRegexCompileFlags nonpcre_compile_options; +- uint32_t pcre_compile_options; +- +- nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK; + + context = pcre2_compile_context_create (NULL); + + /* set newline options */ +- pcre2_set_newline (context, extract_newline_options (compile_options, match_options)); ++ if (pcre2_set_newline (context, newline_options) != 0) ++ { ++ g_set_error (error, G_REGEX_ERROR, ++ G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS, ++ "Invalid newline flags"); ++ pcre2_compile_context_free (context); ++ return NULL; ++ } + + /* set bsr options */ +- pcre2_set_bsr (context, extract_bsr_options (compile_options, match_options)); ++ if (pcre2_set_bsr (context, bsr_options) != 0) ++ { ++ g_set_error (error, G_REGEX_ERROR, ++ G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS, ++ "Invalid BSR flags"); ++ pcre2_compile_context_free (context); ++ return NULL; ++ } + + /* In case UTF-8 mode is used, also set PCRE2_NO_UTF_CHECK */ + if (compile_options & PCRE2_UTF) +- { +- compile_options |= PCRE2_NO_UTF_CHECK; +- if (match_options != NULL) +- *match_options |= PCRE2_NO_UTF_CHECK; +- } ++ compile_options |= PCRE2_NO_UTF_CHECK; + + compile_options |= PCRE2_UCP; + + /* compile the pattern */ + re = pcre2_compile ((PCRE2_SPTR8) pattern, + PCRE2_ZERO_TERMINATED, +- compile_options & ~G_REGEX_FLAGS_CONVERTED, ++ compile_options, + &errcode, + &erroffset, + context); +@@ -1755,16 +1769,22 @@ regex_compile (const gchar *pattern, + return NULL; + } + ++ return re; ++} ++ ++static uint32_t ++get_pcre2_inline_compile_options (pcre2_code *re, ++ uint32_t compile_options) ++{ ++ uint32_t pcre_compile_options; ++ uint32_t nonpcre_compile_options; ++ + /* For options set at the beginning of the pattern, pcre puts them into + * compile options, e.g. "(?i)foo" will make the pcre structure store + * PCRE2_CASELESS even though it wasn't explicitly given for compilation. */ ++ nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK; + pcre2_pattern_info (re, PCRE2_INFO_ALLOPTIONS, &pcre_compile_options); +- compile_options = pcre_compile_options & G_REGEX_COMPILE_PCRE_MASK; +- +- /* Don't leak PCRE2_NEWLINE_ANY, which is part of PCRE2_NEWLINE_ANYCRLF */ +- if ((pcre_compile_options & PCRE2_NEWLINE_ANYCRLF) != PCRE2_NEWLINE_ANYCRLF) +- compile_options &= ~PCRE2_NEWLINE_ANY; +- ++ compile_options = pcre_compile_options & G_REGEX_PCRE2_COMPILE_MASK; + compile_options |= nonpcre_compile_options; + + if (!(compile_options & PCRE2_DUPNAMES)) +@@ -1775,10 +1795,7 @@ regex_compile (const gchar *pattern, + compile_options |= PCRE2_DUPNAMES; + } + +- if (compile_options_out != 0) +- *compile_options_out = compile_options; +- +- return re; ++ return compile_options; + } + + /** +@@ -1940,7 +1957,7 @@ g_regex_get_compile_flags (const GRegex *regex) + break; + } + +- return map_to_pcre1_compile_flags (regex->compile_opts) | extra_flags; ++ return g_regex_compile_flags_from_pcre2 (regex->compile_opts) | extra_flags; + } + + /** +@@ -1956,9 +1973,15 @@ g_regex_get_compile_flags (const GRegex *regex) + GRegexMatchFlags + g_regex_get_match_flags (const GRegex *regex) + { ++ uint32_t flags; ++ + g_return_val_if_fail (regex != NULL, 0); + +- return map_to_pcre1_match_flags (regex->match_opts & G_REGEX_MATCH_MASK); ++ flags = g_regex_match_flags_from_pcre2 (regex->match_opts); ++ flags |= (regex->orig_match_opts & G_REGEX_MATCH_NEWLINE_MASK); ++ flags |= (regex->orig_match_opts & (G_REGEX_MATCH_BSR_ANY | G_REGEX_MATCH_BSR_ANYCRLF)); ++ ++ return flags; + } + + /** +@@ -1992,9 +2015,6 @@ g_regex_match_simple (const gchar *pattern, + GRegex *regex; + gboolean result; + +- compile_options = map_to_pcre2_compile_flags (compile_options); +- match_options = map_to_pcre2_match_flags (match_options); +- + regex = g_regex_new (pattern, compile_options, G_REGEX_MATCH_DEFAULT, NULL); + if (!regex) + return FALSE; +@@ -2062,8 +2082,6 @@ g_regex_match (const GRegex *regex, + GRegexMatchFlags match_options, + GMatchInfo **match_info) + { +- match_options = map_to_pcre2_match_flags (match_options); +- + return g_regex_match_full (regex, string, -1, 0, match_options, + match_info, NULL); + } +@@ -2147,8 +2165,6 @@ g_regex_match_full (const GRegex *regex, + GMatchInfo *info; + gboolean match_ok; + +- match_options = map_to_pcre2_match_flags (match_options); +- + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (start_position >= 0, FALSE); +@@ -2199,8 +2215,6 @@ g_regex_match_all (const GRegex *regex, + GRegexMatchFlags match_options, + GMatchInfo **match_info) + { +- match_options = map_to_pcre2_match_flags (match_options); +- + return g_regex_match_all_full (regex, string, -1, 0, match_options, + match_info, NULL); + } +@@ -2272,8 +2286,8 @@ g_regex_match_all_full (const GRegex *regex, + gboolean done; + pcre2_code *pcre_re; + gboolean retval; +- +- match_options = map_to_pcre2_match_flags (match_options); ++ uint32_t newline_options; ++ uint32_t bsr_options; + + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); +@@ -2281,6 +2295,14 @@ g_regex_match_all_full (const GRegex *regex, + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE); + ++ newline_options = get_pcre2_newline_match_options (match_options); ++ if (!newline_options) ++ newline_options = get_pcre2_newline_compile_options (regex->orig_compile_opts); ++ ++ bsr_options = get_pcre2_bsr_match_options (match_options); ++ if (!bsr_options) ++ bsr_options = get_pcre2_bsr_compile_options (regex->orig_compile_opts); ++ + /* For PCRE2 we need to turn off PCRE2_NO_AUTO_POSSESS, which is an + * optimization for normal regex matching, but results in omitting some + * shorter matches here, and an observable behaviour change. +@@ -2289,7 +2311,7 @@ g_regex_match_all_full (const GRegex *regex, + * codesearch.debian.net, so don't bother caching the recompiled RE. */ + pcre_re = regex_compile (regex->pattern, + regex->compile_opts | PCRE2_NO_AUTO_POSSESS, +- NULL, NULL, error); ++ newline_options, bsr_options, error); + if (pcre_re == NULL) + return FALSE; + +@@ -2303,7 +2325,7 @@ g_regex_match_all_full (const GRegex *regex, + info->matches = pcre2_dfa_match (pcre_re, + (PCRE2_SPTR8) info->string, info->string_len, + info->pos, +- (regex->match_opts | match_options | PCRE2_NO_UTF_CHECK) & ~G_REGEX_FLAGS_CONVERTED, ++ (regex->match_opts | info->match_opts), + info->match_data, + info->match_context, + info->workspace, info->n_workspace); +@@ -2436,9 +2458,6 @@ g_regex_split_simple (const gchar *pattern, + GRegex *regex; + gchar **result; + +- compile_options = map_to_pcre2_compile_flags (compile_options); +- match_options = map_to_pcre2_match_flags (match_options); +- + regex = g_regex_new (pattern, compile_options, 0, NULL); + if (!regex) + return NULL; +@@ -2482,8 +2501,6 @@ g_regex_split (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options) + { +- match_options = map_to_pcre2_match_flags (match_options); +- + return g_regex_split_full (regex, string, -1, 0, + match_options, 0, NULL); + } +@@ -2548,8 +2565,6 @@ g_regex_split_full (const GRegex *regex, + /* the returned array of char **s */ + gchar **string_list; + +- match_options = map_to_pcre2_match_flags (match_options); +- + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +@@ -3174,8 +3189,6 @@ g_regex_replace (const GRegex *regex, + GList *list; + GError *tmp_error = NULL; + +- match_options = map_to_pcre2_match_flags (match_options); +- + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +@@ -3245,8 +3258,6 @@ g_regex_replace_literal (const GRegex *regex, + GRegexMatchFlags match_options, + GError **error) + { +- match_options = map_to_pcre2_match_flags (match_options); +- + g_return_val_if_fail (replacement != NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + +@@ -3335,8 +3346,6 @@ g_regex_replace_eval (const GRegex *regex, + gboolean done = FALSE; + GError *tmp_error = NULL; + +- match_options = map_to_pcre2_match_flags (match_options); +- + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 0d01d59..79e6b4a 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -1,6 +1,7 @@ + /* + * Copyright (C) 2005 - 2006, Marco Barisione + * Copyright (C) 2010 Red Hat, Inc. ++ * Copyright (C) 2022, Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -2353,7 +2354,13 @@ main (int argc, char *argv[]) + + /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */ + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0); ++ TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, ++ G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY); ++ TEST_NEW_CHECK_FLAGS ("a", 0, G_REGEX_MATCH_NEWLINE_ANYCRLF | G_REGEX_MATCH_BSR_ANYCRLF, ++ G_REGEX_NEWLINE_ANYCRLF | G_REGEX_BSR_ANYCRLF, ++ G_REGEX_MATCH_NEWLINE_ANYCRLF | G_REGEX_MATCH_BSR_ANYCRLF); + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_RAW, 0, G_REGEX_RAW, 0); ++ TEST_NEW_CHECK_FLAGS ("(?J)a", 0, 0, G_REGEX_DUPNAMES, 0); + TEST_NEW_CHECK_FLAGS ("^.*", 0, 0, G_REGEX_ANCHORED, 0); + TEST_NEW_CHECK_FLAGS ("(*UTF8)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*UCP)a", 0, 0, 0 /* this always on in GRegex */, 0); +@@ -2559,6 +2566,8 @@ main (int argc, char *argv[]) + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\rb\rc", -1, 0, 0, FALSE); ++ TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_ANYCRLF, 0, "a\r\nb\nc", -1, 0, 0, TRUE); ++ TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_ANYCRLF, 0, "a\r\nb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE); +@@ -2568,6 +2577,8 @@ main (int argc, char *argv[]) + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\rb\rc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); + TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); ++ TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a\r\nb\rc", -1, 0, 0, TRUE); ++ TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a\r\nb\nc", -1, 0, 0, TRUE); + + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\nb\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\rb\rc", -1, 0, 0, TRUE); +@@ -2577,6 +2588,13 @@ main (int argc, char *argv[]) + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); + TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_CRLF, "a\rb\rc", -1, 0, 0, FALSE); + ++ /* See https://gitlab.gnome.org/GNOME/glib/-/issues/2729#note_1544130 */ ++ TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANY, "a", -1, 0, 0, TRUE); ++ TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a", -1, 0, 0, TRUE); ++ TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, TRUE); ++ TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a", -1, 0, 0, TRUE); ++ TEST_MATCH("^a$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_ANYCRLF, "a", -1, 0, 0, TRUE); ++ + TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); +-- +2.33.0 +GitLab diff --git a/backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch b/backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..57b4c7dcfad0e4f061c7bd0674ba70047f2b6bed --- /dev/null +++ b/backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch @@ -0,0 +1,241 @@ +From bec68b2d74853de5e23ee40c890433fa336ffbc5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Handle-JIT-errors-more-explicitly.patch b/backport-regex-Handle-JIT-errors-more-explicitly.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1d61315551da8a10953994207457cd51bf915b7 --- /dev/null +++ b/backport-regex-Handle-JIT-errors-more-explicitly.patch @@ -0,0 +1,35 @@ +From 5e76cde5ffeac79b939cf84202024859cda5e753 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Make-possible-to-test-replacements-with-options.patch b/backport-regex-Make-possible-to-test-replacements-with-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..d9bed10e308f4d001c00099cdb671c362c9c3b7a --- /dev/null +++ b/backport-regex-Make-possible-to-test-replacements-with-options.patch @@ -0,0 +1,71 @@ +From 0831393dd08d5f9dcf2e0517dbb4ea546ff7156b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch b/backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch new file mode 100644 index 0000000000000000000000000000000000000000..135e07602397c38d54023dfc1471f9a93fb33b1a --- /dev/null +++ b/backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch @@ -0,0 +1,188 @@ +From 653f8eb0203485c7ffb0eeae81e6e30437d18529 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch b/backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch new file mode 100644 index 0000000000000000000000000000000000000000..2ad0033e9c956ff05543038175cbdaa1c5fee024 --- /dev/null +++ b/backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch @@ -0,0 +1,148 @@ +From 1d628dac92283d75f7c751ddad72c28f4a7afe39 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + #include + + #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 + diff --git a/backport-replace-pcre1-with-pcre2.patch b/backport-replace-pcre1-with-pcre2.patch new file mode 100644 index 0000000000000000000000000000000000000000..451313517748c940b134465f01164c4581ce38df --- /dev/null +++ b/backport-replace-pcre1-with-pcre2.patch @@ -0,0 +1,2473 @@ +From 8d5a44dc8f36cce270519bd52fcecf330ccb43b4 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Tue, 12 Jul 2022 11:46:34 +0000 +Subject: [PATCH] replace pcre1 with pcre2 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/8d5a44dc8f36cce270519bd52fcecf330ccb43b4 + +--- + docs/reference/glib/regex-syntax.xml | 46 -- + glib/gregex.c | 1113 ++++++++++++++++---------- + glib/gregex.h | 11 +- + glib/meson.build | 10 +- + glib/tests/meson.build | 4 +- + glib/tests/regex.c | 175 ++-- + meson.build | 41 +- + po/sk.po | 2 +- + subprojects/pcre.wrap | 11 - + 9 files changed, 819 insertions(+), 594 deletions(-) + delete mode 100644 subprojects/pcre.wrap + +diff --git a/docs/reference/glib/regex-syntax.xml b/docs/reference/glib/regex-syntax.xml +index 5dd9291..0b413aa 100644 +--- a/docs/reference/glib/regex-syntax.xml ++++ b/docs/reference/glib/regex-syntax.xml +@@ -2442,52 +2442,6 @@ processing option does not affect the called subpattern. + + + +- +- + + Copyright + +diff --git a/glib/gregex.c b/glib/gregex.c +index 9a8229a..da37213 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -22,7 +22,8 @@ + + #include + +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + + #include "gtypes.h" + #include "gregex.h" +@@ -107,87 +108,63 @@ + * library written by Philip Hazel. + */ + ++/* Signifies that flags have already been converted from pcre1 to pcre2. The ++ * value 0x04000000u is also the value of PCRE2_MATCH_INVALID_UTF in pcre2.h, ++ * but it is not used in gregex, so we can reuse it for this flag. ++ */ ++#define G_REGEX_FLAGS_CONVERTED 0x04000000u + /* Mask of all the possible values for GRegexCompileFlags. */ +-#define G_REGEX_COMPILE_MASK (G_REGEX_CASELESS | \ +- G_REGEX_MULTILINE | \ +- G_REGEX_DOTALL | \ +- G_REGEX_EXTENDED | \ +- G_REGEX_ANCHORED | \ +- G_REGEX_DOLLAR_ENDONLY | \ +- G_REGEX_UNGREEDY | \ +- G_REGEX_RAW | \ +- G_REGEX_NO_AUTO_CAPTURE | \ +- G_REGEX_OPTIMIZE | \ +- G_REGEX_FIRSTLINE | \ +- G_REGEX_DUPNAMES | \ +- G_REGEX_NEWLINE_CR | \ +- G_REGEX_NEWLINE_LF | \ +- G_REGEX_NEWLINE_CRLF | \ +- G_REGEX_NEWLINE_ANYCRLF | \ +- G_REGEX_BSR_ANYCRLF | \ +- G_REGEX_JAVASCRIPT_COMPAT) ++#define G_REGEX_COMPILE_MASK (PCRE2_CASELESS | \ ++ PCRE2_MULTILINE | \ ++ PCRE2_DOTALL | \ ++ PCRE2_EXTENDED | \ ++ PCRE2_ANCHORED | \ ++ PCRE2_DOLLAR_ENDONLY | \ ++ PCRE2_UNGREEDY | \ ++ PCRE2_UTF | \ ++ PCRE2_NO_AUTO_CAPTURE | \ ++ PCRE2_FIRSTLINE | \ ++ PCRE2_DUPNAMES | \ ++ PCRE2_NEWLINE_CR | \ ++ PCRE2_NEWLINE_LF | \ ++ PCRE2_NEWLINE_CRLF | \ ++ PCRE2_NEWLINE_ANYCRLF | \ ++ PCRE2_BSR_ANYCRLF | \ ++ G_REGEX_FLAGS_CONVERTED) + + /* Mask of all GRegexCompileFlags values that are (not) passed trough to PCRE */ + #define G_REGEX_COMPILE_PCRE_MASK (G_REGEX_COMPILE_MASK & ~G_REGEX_COMPILE_NONPCRE_MASK) +-#define G_REGEX_COMPILE_NONPCRE_MASK (G_REGEX_RAW | \ +- G_REGEX_OPTIMIZE) ++#define G_REGEX_COMPILE_NONPCRE_MASK (PCRE2_UTF | \ ++ G_REGEX_FLAGS_CONVERTED) + + /* Mask of all the possible values for GRegexMatchFlags. */ +-#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_ANCHORED | \ +- G_REGEX_MATCH_NOTBOL | \ +- G_REGEX_MATCH_NOTEOL | \ +- G_REGEX_MATCH_NOTEMPTY | \ +- G_REGEX_MATCH_PARTIAL | \ +- G_REGEX_MATCH_NEWLINE_CR | \ +- G_REGEX_MATCH_NEWLINE_LF | \ +- G_REGEX_MATCH_NEWLINE_CRLF | \ +- G_REGEX_MATCH_NEWLINE_ANY | \ +- G_REGEX_MATCH_NEWLINE_ANYCRLF | \ +- G_REGEX_MATCH_BSR_ANYCRLF | \ +- G_REGEX_MATCH_BSR_ANY | \ +- G_REGEX_MATCH_PARTIAL_SOFT | \ +- G_REGEX_MATCH_PARTIAL_HARD | \ +- G_REGEX_MATCH_NOTEMPTY_ATSTART) +- +-/* we rely on these flags having the same values */ +-G_STATIC_ASSERT (G_REGEX_CASELESS == PCRE_CASELESS); +-G_STATIC_ASSERT (G_REGEX_MULTILINE == PCRE_MULTILINE); +-G_STATIC_ASSERT (G_REGEX_DOTALL == PCRE_DOTALL); +-G_STATIC_ASSERT (G_REGEX_EXTENDED == PCRE_EXTENDED); +-G_STATIC_ASSERT (G_REGEX_ANCHORED == PCRE_ANCHORED); +-G_STATIC_ASSERT (G_REGEX_DOLLAR_ENDONLY == PCRE_DOLLAR_ENDONLY); +-G_STATIC_ASSERT (G_REGEX_UNGREEDY == PCRE_UNGREEDY); +-G_STATIC_ASSERT (G_REGEX_NO_AUTO_CAPTURE == PCRE_NO_AUTO_CAPTURE); +-G_STATIC_ASSERT (G_REGEX_FIRSTLINE == PCRE_FIRSTLINE); +-G_STATIC_ASSERT (G_REGEX_DUPNAMES == PCRE_DUPNAMES); +-G_STATIC_ASSERT (G_REGEX_NEWLINE_CR == PCRE_NEWLINE_CR); +-G_STATIC_ASSERT (G_REGEX_NEWLINE_LF == PCRE_NEWLINE_LF); +-G_STATIC_ASSERT (G_REGEX_NEWLINE_CRLF == PCRE_NEWLINE_CRLF); +-G_STATIC_ASSERT (G_REGEX_NEWLINE_ANYCRLF == PCRE_NEWLINE_ANYCRLF); +-G_STATIC_ASSERT (G_REGEX_BSR_ANYCRLF == PCRE_BSR_ANYCRLF); +-G_STATIC_ASSERT (G_REGEX_JAVASCRIPT_COMPAT == PCRE_JAVASCRIPT_COMPAT); +- +-G_STATIC_ASSERT (G_REGEX_MATCH_ANCHORED == PCRE_ANCHORED); +-G_STATIC_ASSERT (G_REGEX_MATCH_NOTBOL == PCRE_NOTBOL); +-G_STATIC_ASSERT (G_REGEX_MATCH_NOTEOL == PCRE_NOTEOL); +-G_STATIC_ASSERT (G_REGEX_MATCH_NOTEMPTY == PCRE_NOTEMPTY); +-G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL == PCRE_PARTIAL); +-G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_CR == PCRE_NEWLINE_CR); +-G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_LF == PCRE_NEWLINE_LF); +-G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_CRLF == PCRE_NEWLINE_CRLF); +-G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_ANY == PCRE_NEWLINE_ANY); +-G_STATIC_ASSERT (G_REGEX_MATCH_NEWLINE_ANYCRLF == PCRE_NEWLINE_ANYCRLF); +-G_STATIC_ASSERT (G_REGEX_MATCH_BSR_ANYCRLF == PCRE_BSR_ANYCRLF); +-G_STATIC_ASSERT (G_REGEX_MATCH_BSR_ANY == PCRE_BSR_UNICODE); +-G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL_SOFT == PCRE_PARTIAL_SOFT); +-G_STATIC_ASSERT (G_REGEX_MATCH_PARTIAL_HARD == PCRE_PARTIAL_HARD); +-G_STATIC_ASSERT (G_REGEX_MATCH_NOTEMPTY_ATSTART == PCRE_NOTEMPTY_ATSTART); +- +-/* These PCRE flags are unused or not exposed publicly in GRegexFlags, so +- * it should be ok to reuse them for different things. +- */ +-G_STATIC_ASSERT (G_REGEX_OPTIMIZE == PCRE_NO_UTF8_CHECK); +-G_STATIC_ASSERT (G_REGEX_RAW == PCRE_UTF8); ++#define G_REGEX_MATCH_MASK (PCRE2_ANCHORED | \ ++ PCRE2_NOTBOL | \ ++ PCRE2_NOTEOL | \ ++ PCRE2_NOTEMPTY | \ ++ PCRE2_PARTIAL_SOFT | \ ++ PCRE2_NEWLINE_CR | \ ++ PCRE2_NEWLINE_LF | \ ++ PCRE2_NEWLINE_CRLF | \ ++ PCRE2_NEWLINE_ANY | \ ++ PCRE2_NEWLINE_ANYCRLF | \ ++ PCRE2_BSR_ANYCRLF | \ ++ PCRE2_BSR_UNICODE | \ ++ PCRE2_PARTIAL_SOFT | \ ++ PCRE2_PARTIAL_HARD | \ ++ PCRE2_NOTEMPTY_ATSTART | \ ++ G_REGEX_FLAGS_CONVERTED) ++ ++#define G_REGEX_NEWLINE_MASK (PCRE2_NEWLINE_CR | \ ++ PCRE2_NEWLINE_LF | \ ++ PCRE2_NEWLINE_CRLF | \ ++ PCRE2_NEWLINE_ANYCRLF) ++ ++#define G_REGEX_MATCH_NEWLINE_MASK (PCRE2_NEWLINE_CR | \ ++ PCRE2_NEWLINE_LF | \ ++ PCRE2_NEWLINE_CRLF | \ ++ PCRE2_NEWLINE_ANYCRLF | \ ++ PCRE2_NEWLINE_ANY) + + /* if the string is in UTF-8 use g_utf8_ functions, else use + * use just +/- 1. */ +@@ -208,24 +185,26 @@ struct _GMatchInfo + gint pos; /* position in the string where last match left off */ + gint n_offsets; /* number of offsets */ + gint *offsets; /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */ +- gint *workspace; /* workspace for pcre_dfa_exec() */ ++ gint *workspace; /* workspace for pcre2_dfa_match() */ + gint 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; ++ pcre2_match_data *match_data; + }; + + struct _GRegex + { + gint ref_count; /* the ref count for the immutable part (atomic) */ + gchar *pattern; /* the pattern */ +- pcre *pcre_re; /* compiled form of the pattern */ +- GRegexCompileFlags compile_opts; /* options used at compile time on the pattern */ ++ pcre2_code *pcre_re; /* compiled form of the pattern */ ++ GRegexCompileFlags compile_opts; /* options used at compile time on the pattern, pcre2 values */ ++ GRegexCompileFlags orig_compile_opts; /* options used at compile time on the pattern, gregex values */ + GRegexMatchFlags match_opts; /* options used at match time on the regex */ +- pcre_extra *extra; /* data stored when G_REGEX_OPTIMIZE is used */ + }; + + /* TRUE if ret is an error code, FALSE otherwise. */ +-#define IS_PCRE_ERROR(ret) ((ret) < PCRE_ERROR_NOMATCH && (ret) != PCRE_ERROR_PARTIAL) ++#define IS_PCRE2_ERROR(ret) ((ret) < PCRE2_ERROR_NOMATCH && (ret) != PCRE2_ERROR_PARTIAL) + + typedef struct _InterpolationData InterpolationData; + static gboolean interpolation_list_needs_match (GList *list); +@@ -236,70 +215,249 @@ static GList *split_replacement (const gchar *replacement, + GError **error); + static void free_interpolation_data (InterpolationData *data); + ++static gint ++map_to_pcre2_compile_flags (gint pcre1_flags) ++{ ++ /* Maps compile flags from pcre1 to pcre2 values ++ */ ++ gint pcre2_flags = G_REGEX_FLAGS_CONVERTED; ++ ++ if (pcre1_flags & G_REGEX_FLAGS_CONVERTED) ++ return pcre1_flags; ++ ++ if (pcre1_flags & G_REGEX_CASELESS) ++ pcre2_flags |= PCRE2_CASELESS; ++ if (pcre1_flags & G_REGEX_MULTILINE) ++ pcre2_flags |= PCRE2_MULTILINE; ++ if (pcre1_flags & G_REGEX_DOTALL) ++ pcre2_flags |= PCRE2_DOTALL; ++ if (pcre1_flags & G_REGEX_EXTENDED) ++ pcre2_flags |= PCRE2_EXTENDED; ++ if (pcre1_flags & G_REGEX_ANCHORED) ++ pcre2_flags |= PCRE2_ANCHORED; ++ if (pcre1_flags & G_REGEX_DOLLAR_ENDONLY) ++ pcre2_flags |= PCRE2_DOLLAR_ENDONLY; ++ if (pcre1_flags & G_REGEX_UNGREEDY) ++ pcre2_flags |= PCRE2_UNGREEDY; ++ if (!(pcre1_flags & G_REGEX_RAW)) ++ pcre2_flags |= PCRE2_UTF; ++ if (pcre1_flags & G_REGEX_NO_AUTO_CAPTURE) ++ pcre2_flags |= PCRE2_NO_AUTO_CAPTURE; ++ if (pcre1_flags & G_REGEX_FIRSTLINE) ++ pcre2_flags |= PCRE2_FIRSTLINE; ++ if (pcre1_flags & G_REGEX_DUPNAMES) ++ pcre2_flags |= PCRE2_DUPNAMES; ++ if (pcre1_flags & G_REGEX_NEWLINE_CR) ++ pcre2_flags |= PCRE2_NEWLINE_CR; ++ if (pcre1_flags & G_REGEX_NEWLINE_LF) ++ pcre2_flags |= PCRE2_NEWLINE_LF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre1_flags & G_REGEX_NEWLINE_CRLF) == G_REGEX_NEWLINE_CRLF) ++ pcre2_flags |= PCRE2_NEWLINE_CRLF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre1_flags & G_REGEX_NEWLINE_ANYCRLF) == G_REGEX_NEWLINE_ANYCRLF) ++ pcre2_flags |= PCRE2_NEWLINE_ANYCRLF; ++ if (pcre1_flags & G_REGEX_BSR_ANYCRLF) ++ pcre2_flags |= PCRE2_BSR_ANYCRLF; ++ ++ /* these are not available in pcre2 */ ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS ++ if (pcre1_flags & G_REGEX_OPTIMIZE) ++ pcre2_flags |= 0; ++ if (pcre1_flags & G_REGEX_JAVASCRIPT_COMPAT) ++ pcre2_flags |= 0; ++G_GNUC_END_IGNORE_DEPRECATIONS ++ ++ return pcre2_flags; ++} ++ ++static gint ++map_to_pcre2_match_flags (gint pcre1_flags) ++{ ++ /* Maps match flags from pcre1 to pcre2 values ++ */ ++ gint pcre2_flags = G_REGEX_FLAGS_CONVERTED; ++ ++ if (pcre1_flags & G_REGEX_FLAGS_CONVERTED) ++ return pcre1_flags; ++ ++ if (pcre1_flags & G_REGEX_MATCH_ANCHORED) ++ pcre2_flags |= PCRE2_ANCHORED; ++ if (pcre1_flags & G_REGEX_MATCH_NOTBOL) ++ pcre2_flags |= PCRE2_NOTBOL; ++ if (pcre1_flags & G_REGEX_MATCH_NOTEOL) ++ pcre2_flags |= PCRE2_NOTEOL; ++ if (pcre1_flags & G_REGEX_MATCH_NOTEMPTY) ++ pcre2_flags |= PCRE2_NOTEMPTY; ++ if (pcre1_flags & G_REGEX_MATCH_PARTIAL) ++ pcre2_flags |= PCRE2_PARTIAL_SOFT; ++ if (pcre1_flags & G_REGEX_MATCH_NEWLINE_CR) ++ pcre2_flags |= PCRE2_NEWLINE_CR; ++ if (pcre1_flags & G_REGEX_MATCH_NEWLINE_LF) ++ pcre2_flags |= PCRE2_NEWLINE_LF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre1_flags & G_REGEX_MATCH_NEWLINE_CRLF) == G_REGEX_MATCH_NEWLINE_CRLF) ++ pcre2_flags |= PCRE2_NEWLINE_CRLF; ++ if (pcre1_flags & G_REGEX_MATCH_NEWLINE_ANY) ++ pcre2_flags |= PCRE2_NEWLINE_ANY; ++ /* Check for exact match for a composite flag */ ++ if ((pcre1_flags & G_REGEX_MATCH_NEWLINE_ANYCRLF) == G_REGEX_MATCH_NEWLINE_ANYCRLF) ++ pcre2_flags |= PCRE2_NEWLINE_ANYCRLF; ++ if (pcre1_flags & G_REGEX_MATCH_BSR_ANYCRLF) ++ pcre2_flags |= PCRE2_BSR_ANYCRLF; ++ if (pcre1_flags & G_REGEX_MATCH_BSR_ANY) ++ pcre2_flags |= PCRE2_BSR_UNICODE; ++ if (pcre1_flags & G_REGEX_MATCH_PARTIAL_SOFT) ++ pcre2_flags |= PCRE2_PARTIAL_SOFT; ++ if (pcre1_flags & G_REGEX_MATCH_PARTIAL_HARD) ++ pcre2_flags |= PCRE2_PARTIAL_HARD; ++ if (pcre1_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART) ++ pcre2_flags |= PCRE2_NOTEMPTY_ATSTART; ++ ++ return pcre2_flags; ++} ++ ++static gint ++map_to_pcre1_compile_flags (gint pcre2_flags) ++{ ++ /* Maps compile flags from pcre2 to pcre1 values ++ */ ++ gint pcre1_flags = 0; ++ ++ if (!(pcre2_flags & G_REGEX_FLAGS_CONVERTED)) ++ return pcre2_flags; ++ ++ if (pcre2_flags & PCRE2_CASELESS) ++ pcre1_flags |= G_REGEX_CASELESS; ++ if (pcre2_flags & PCRE2_MULTILINE) ++ pcre1_flags |= G_REGEX_MULTILINE; ++ if (pcre2_flags & PCRE2_DOTALL) ++ pcre1_flags |= G_REGEX_DOTALL; ++ if (pcre2_flags & PCRE2_EXTENDED) ++ pcre1_flags |= G_REGEX_EXTENDED; ++ if (pcre2_flags & PCRE2_ANCHORED) ++ pcre1_flags |= G_REGEX_ANCHORED; ++ if (pcre2_flags & PCRE2_DOLLAR_ENDONLY) ++ pcre1_flags |= G_REGEX_DOLLAR_ENDONLY; ++ if (pcre2_flags & PCRE2_UNGREEDY) ++ pcre1_flags |= G_REGEX_UNGREEDY; ++ if (!(pcre2_flags & PCRE2_UTF)) ++ pcre1_flags |= G_REGEX_RAW; ++ if (pcre2_flags & PCRE2_NO_AUTO_CAPTURE) ++ pcre1_flags |= G_REGEX_NO_AUTO_CAPTURE; ++ if (pcre2_flags & PCRE2_FIRSTLINE) ++ pcre1_flags |= G_REGEX_FIRSTLINE; ++ if (pcre2_flags & PCRE2_DUPNAMES) ++ pcre1_flags |= G_REGEX_DUPNAMES; ++ if (pcre2_flags & PCRE2_NEWLINE_CR) ++ pcre1_flags |= G_REGEX_NEWLINE_CR; ++ if (pcre2_flags & PCRE2_NEWLINE_LF) ++ pcre1_flags |= G_REGEX_NEWLINE_LF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre2_flags & PCRE2_NEWLINE_CRLF) == PCRE2_NEWLINE_CRLF) ++ pcre1_flags |= G_REGEX_NEWLINE_CRLF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre2_flags & PCRE2_NEWLINE_ANYCRLF) == PCRE2_NEWLINE_ANYCRLF) ++ pcre1_flags |= G_REGEX_NEWLINE_ANYCRLF; ++ if (pcre2_flags & PCRE2_BSR_ANYCRLF) ++ pcre1_flags |= G_REGEX_BSR_ANYCRLF; ++ ++ return pcre1_flags; ++} ++ ++static gint ++map_to_pcre1_match_flags (gint pcre2_flags) ++{ ++ /* Maps match flags from pcre2 to pcre1 values ++ */ ++ gint pcre1_flags = 0; ++ ++ if (!(pcre2_flags & G_REGEX_FLAGS_CONVERTED)) ++ return pcre2_flags; ++ ++ if (pcre2_flags & PCRE2_ANCHORED) ++ pcre1_flags |= G_REGEX_MATCH_ANCHORED; ++ if (pcre2_flags & PCRE2_NOTBOL) ++ pcre1_flags |= G_REGEX_MATCH_NOTBOL; ++ if (pcre2_flags & PCRE2_NOTEOL) ++ pcre1_flags |= G_REGEX_MATCH_NOTEOL; ++ if (pcre2_flags & PCRE2_NOTEMPTY) ++ pcre1_flags |= G_REGEX_MATCH_NOTEMPTY; ++ if (pcre2_flags & PCRE2_PARTIAL_SOFT) ++ pcre1_flags |= G_REGEX_MATCH_PARTIAL; ++ if (pcre2_flags & PCRE2_NEWLINE_CR) ++ pcre1_flags |= G_REGEX_MATCH_NEWLINE_CR; ++ if (pcre2_flags & PCRE2_NEWLINE_LF) ++ pcre1_flags |= G_REGEX_MATCH_NEWLINE_LF; ++ /* Check for exact match for a composite flag */ ++ if ((pcre2_flags & PCRE2_NEWLINE_CRLF) == PCRE2_NEWLINE_CRLF) ++ pcre1_flags |= G_REGEX_MATCH_NEWLINE_CRLF; ++ if (pcre2_flags & PCRE2_NEWLINE_ANY) ++ pcre1_flags |= G_REGEX_MATCH_NEWLINE_ANY; ++ /* Check for exact match for a composite flag */ ++ if ((pcre2_flags & PCRE2_NEWLINE_ANYCRLF) == PCRE2_NEWLINE_ANYCRLF) ++ pcre1_flags |= G_REGEX_MATCH_NEWLINE_ANYCRLF; ++ if (pcre2_flags & PCRE2_BSR_ANYCRLF) ++ pcre1_flags |= G_REGEX_MATCH_BSR_ANYCRLF; ++ if (pcre2_flags & PCRE2_BSR_UNICODE) ++ pcre1_flags |= G_REGEX_MATCH_BSR_ANY; ++ if (pcre2_flags & PCRE2_PARTIAL_SOFT) ++ pcre1_flags |= G_REGEX_MATCH_PARTIAL_SOFT; ++ if (pcre2_flags & PCRE2_PARTIAL_HARD) ++ pcre1_flags |= G_REGEX_MATCH_PARTIAL_HARD; ++ if (pcre2_flags & PCRE2_NOTEMPTY_ATSTART) ++ pcre1_flags |= G_REGEX_MATCH_NOTEMPTY_ATSTART; ++ ++ return pcre1_flags; ++} + + static const gchar * + match_error (gint errcode) + { + switch (errcode) + { +- case PCRE_ERROR_NOMATCH: ++ case PCRE2_ERROR_NOMATCH: + /* not an error */ + break; +- case PCRE_ERROR_NULL: ++ case PCRE2_ERROR_NULL: + /* NULL argument, this should not happen in GRegex */ + g_warning ("A NULL argument was passed to PCRE"); + break; +- case PCRE_ERROR_BADOPTION: ++ case PCRE2_ERROR_BADOPTION: + return "bad options"; +- case PCRE_ERROR_BADMAGIC: ++ case PCRE2_ERROR_BADMAGIC: + return _("corrupted object"); +- case PCRE_ERROR_UNKNOWN_OPCODE: +- return N_("internal error or corrupted object"); +- case PCRE_ERROR_NOMEMORY: ++ case PCRE2_ERROR_NOMEMORY: + return _("out of memory"); +- case PCRE_ERROR_NOSUBSTRING: +- /* not used by pcre_exec() */ ++ case PCRE2_ERROR_NOSUBSTRING: ++ /* not used by pcre2_match() */ + break; +- case PCRE_ERROR_MATCHLIMIT: ++ case PCRE2_ERROR_MATCHLIMIT: + return _("backtracking limit reached"); +- case PCRE_ERROR_CALLOUT: ++ case PCRE2_ERROR_CALLOUT: + /* callouts are not implemented */ + break; +- case PCRE_ERROR_BADUTF8: +- case PCRE_ERROR_BADUTF8_OFFSET: ++ case PCRE2_ERROR_BADUTFOFFSET: + /* we do not check if strings are valid */ + break; +- case PCRE_ERROR_PARTIAL: ++ case PCRE2_ERROR_PARTIAL: + /* not an error */ + break; +- case PCRE_ERROR_BADPARTIAL: +- return _("the pattern contains items not supported for partial matching"); +- case PCRE_ERROR_INTERNAL: ++ case PCRE2_ERROR_INTERNAL: + return _("internal error"); +- case PCRE_ERROR_BADCOUNT: +- /* negative ovecsize, this should not happen in GRegex */ +- g_warning ("A negative ovecsize was passed to PCRE"); +- break; +- case PCRE_ERROR_DFA_UITEM: ++ case PCRE2_ERROR_DFA_UITEM: + return _("the pattern contains items not supported for partial matching"); +- case PCRE_ERROR_DFA_UCOND: ++ case PCRE2_ERROR_DFA_UCOND: + return _("back references as conditions are not supported for partial matching"); +- case PCRE_ERROR_DFA_UMLIMIT: +- /* the match_field field is not used in GRegex */ +- break; +- case PCRE_ERROR_DFA_WSSIZE: ++ case PCRE2_ERROR_DFA_WSSIZE: + /* handled expanding the workspace */ + break; +- case PCRE_ERROR_DFA_RECURSE: +- case PCRE_ERROR_RECURSIONLIMIT: ++ case PCRE2_ERROR_DFA_RECURSE: ++ case PCRE2_ERROR_RECURSIONLIMIT: + return _("recursion limit reached"); +- case PCRE_ERROR_BADNEWLINE: +- return _("invalid combination of newline flags"); +- case PCRE_ERROR_BADOFFSET: ++ case PCRE2_ERROR_BADOFFSET: + return _("bad offset"); +- case PCRE_ERROR_SHORTUTF8: +- return _("short utf8"); +- case PCRE_ERROR_RECURSELOOP: ++ case PCRE2_ERROR_RECURSELOOP: + return _("recursion loop"); + default: + break; +@@ -310,242 +468,263 @@ match_error (gint errcode) + static void + translate_compile_error (gint *errcode, const gchar **errmsg) + { +- /* Compile errors are created adding 100 to the error code returned +- * by PCRE. +- * If errcode is known we put the translatable error message in +- * erromsg. If errcode is unknown we put the generic +- * G_REGEX_ERROR_COMPILE error code in errcode and keep the +- * untranslated error message returned by PCRE. ++ /* If errcode is known we put the translatable error message in ++ * errmsg. If errcode is unknown we put the generic ++ * G_REGEX_ERROR_COMPILE error code in errcode. + * Note that there can be more PCRE errors with the same GRegexError + * and that some PCRE errors are useless for us. + */ +- *errcode += 100; + + switch (*errcode) + { +- case G_REGEX_ERROR_STRAY_BACKSLASH: ++ case PCRE2_ERROR_END_BACKSLASH: ++ *errcode = G_REGEX_ERROR_STRAY_BACKSLASH; + *errmsg = _("\\ at end of pattern"); + break; +- case G_REGEX_ERROR_MISSING_CONTROL_CHAR: ++ case PCRE2_ERROR_END_BACKSLASH_C: ++ *errcode = G_REGEX_ERROR_MISSING_CONTROL_CHAR; + *errmsg = _("\\c at end of pattern"); + break; +- case G_REGEX_ERROR_UNRECOGNIZED_ESCAPE: ++ case PCRE2_ERROR_UNKNOWN_ESCAPE: ++ case PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE: ++ *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE; + *errmsg = _("unrecognized character following \\"); + break; +- case G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER: ++ case PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER: ++ *errcode = G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER; + *errmsg = _("numbers out of order in {} quantifier"); + break; +- case G_REGEX_ERROR_QUANTIFIER_TOO_BIG: ++ case PCRE2_ERROR_QUANTIFIER_TOO_BIG: ++ *errcode = G_REGEX_ERROR_QUANTIFIER_TOO_BIG; + *errmsg = _("number too big in {} quantifier"); + break; +- case G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS: ++ case PCRE2_ERROR_MISSING_SQUARE_BRACKET: ++ *errcode = G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS; + *errmsg = _("missing terminating ] for character class"); + break; +- case G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS: ++ case PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS: ++ *errcode = G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS; + *errmsg = _("invalid escape sequence in character class"); + break; +- case G_REGEX_ERROR_RANGE_OUT_OF_ORDER: ++ case PCRE2_ERROR_CLASS_RANGE_ORDER: ++ *errcode = G_REGEX_ERROR_RANGE_OUT_OF_ORDER; + *errmsg = _("range out of order in character class"); + break; +- case G_REGEX_ERROR_NOTHING_TO_REPEAT: ++ case PCRE2_ERROR_QUANTIFIER_INVALID: ++ case PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT: ++ *errcode = G_REGEX_ERROR_NOTHING_TO_REPEAT; + *errmsg = _("nothing to repeat"); + break; +- case 111: /* internal error: unexpected repeat */ +- *errcode = G_REGEX_ERROR_INTERNAL; +- *errmsg = _("unexpected repeat"); +- break; +- case G_REGEX_ERROR_UNRECOGNIZED_CHARACTER: ++ case PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY: ++ *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; + *errmsg = _("unrecognized character after (? or (?-"); + break; +- case G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS: ++ case PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS: ++ *errcode = G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS; + *errmsg = _("POSIX named classes are supported only within a class"); + break; +- case G_REGEX_ERROR_UNMATCHED_PARENTHESIS: ++ case PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING: ++ *errcode = G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED; ++ *errmsg = _("POSIX collating elements are not supported"); ++ break; ++ case PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS: ++ case PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS: ++ case PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING: ++ *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS; + *errmsg = _("missing terminating )"); + break; +- case G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE: ++ case PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE: ++ *errcode = G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE; + *errmsg = _("reference to non-existent subpattern"); + break; +- case G_REGEX_ERROR_UNTERMINATED_COMMENT: ++ case PCRE2_ERROR_MISSING_COMMENT_CLOSING: ++ *errcode = G_REGEX_ERROR_UNTERMINATED_COMMENT; + *errmsg = _("missing ) after comment"); + break; +- case G_REGEX_ERROR_EXPRESSION_TOO_LARGE: ++ case PCRE2_ERROR_PATTERN_TOO_LARGE: ++ *errcode = G_REGEX_ERROR_EXPRESSION_TOO_LARGE; + *errmsg = _("regular expression is too large"); + break; +- case G_REGEX_ERROR_MEMORY_ERROR: +- *errmsg = _("failed to get memory"); +- break; +- case 122: /* unmatched parentheses */ +- *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS; +- *errmsg = _(") without opening ("); +- break; +- case 123: /* internal error: code overflow */ +- *errcode = G_REGEX_ERROR_INTERNAL; +- *errmsg = _("code overflow"); +- break; +- case 124: /* "unrecognized character after (?<\0 */ +- *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; +- *errmsg = _("unrecognized character after (?<"); ++ case PCRE2_ERROR_MISSING_CONDITION_CLOSING: ++ *errcode = G_REGEX_ERROR_MALFORMED_CONDITION; ++ *errmsg = _("malformed number or name after (?("); + break; +- case G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND: ++ case PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH: ++ *errcode = G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND; + *errmsg = _("lookbehind assertion is not fixed length"); + break; +- case G_REGEX_ERROR_MALFORMED_CONDITION: +- *errmsg = _("malformed number or name after (?("); +- break; +- case G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES: ++ case PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES: ++ *errcode = G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES; + *errmsg = _("conditional group contains more than two branches"); + break; +- case G_REGEX_ERROR_ASSERTION_EXPECTED: ++ case PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED: ++ *errcode = G_REGEX_ERROR_ASSERTION_EXPECTED; + *errmsg = _("assertion expected after (?("); + break; +- case 129: +- *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS; +- /* translators: '(?R' and '(?[+-]digits' are both meant as (groups of) +- * sequences here, '(?-54' would be an example for the second group. +- */ +- *errmsg = _("(?R or (?[+-]digits must be followed by )"); ++ case PCRE2_ERROR_BAD_RELATIVE_REFERENCE: ++ *errcode = G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE; ++ *errmsg = _("a numbered reference must not be zero"); + break; +- case G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME: ++ case PCRE2_ERROR_UNKNOWN_POSIX_CLASS: ++ *errcode = G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME; + *errmsg = _("unknown POSIX class name"); + break; +- case G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED: +- *errmsg = _("POSIX collating elements are not supported"); +- break; +- case G_REGEX_ERROR_HEX_CODE_TOO_LARGE: ++ case PCRE2_ERROR_CODE_POINT_TOO_BIG: ++ case PCRE2_ERROR_INVALID_HEXADECIMAL: ++ *errcode = G_REGEX_ERROR_HEX_CODE_TOO_LARGE; + *errmsg = _("character value in \\x{...} sequence is too large"); + break; +- case G_REGEX_ERROR_INVALID_CONDITION: +- *errmsg = _("invalid condition (?(0)"); +- break; +- case G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND: ++ case PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C: ++ *errcode = G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND; + *errmsg = _("\\C not allowed in lookbehind assertion"); + break; +- case 137: /* PCRE does not support \\L, \\l, \\N{name}, \\U, or \\u\0 */ +- /* A number of Perl escapes are not handled by PCRE. +- * Therefore it explicitly raises ERR37. +- */ +- *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE; +- *errmsg = _("escapes \\L, \\l, \\N{name}, \\U, and \\u are not supported"); +- break; +- case G_REGEX_ERROR_INFINITE_LOOP: +- *errmsg = _("recursive call could loop indefinitely"); +- break; +- case 141: /* unrecognized character after (?P\0 */ +- *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; +- *errmsg = _("unrecognized character after (?P"); +- break; +- case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR: ++ case PCRE2_ERROR_MISSING_NAME_TERMINATOR: ++ *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR; + *errmsg = _("missing terminator in subpattern name"); + break; +- case G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME: ++ case PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME: ++ *errcode = G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME; + *errmsg = _("two named subpatterns have the same name"); + break; +- case G_REGEX_ERROR_MALFORMED_PROPERTY: ++ case PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY: ++ *errcode = G_REGEX_ERROR_MALFORMED_PROPERTY; + *errmsg = _("malformed \\P or \\p sequence"); + break; +- case G_REGEX_ERROR_UNKNOWN_PROPERTY: ++ case PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY: ++ *errcode = G_REGEX_ERROR_UNKNOWN_PROPERTY; + *errmsg = _("unknown property name after \\P or \\p"); + break; +- case G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG: ++ case PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG: ++ *errcode = G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG; + *errmsg = _("subpattern name is too long (maximum 32 characters)"); + break; +- case G_REGEX_ERROR_TOO_MANY_SUBPATTERNS: ++ case PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS: ++ *errcode = G_REGEX_ERROR_TOO_MANY_SUBPATTERNS; + *errmsg = _("too many named subpatterns (maximum 10,000)"); + break; +- case G_REGEX_ERROR_INVALID_OCTAL_VALUE: ++ case PCRE2_ERROR_OCTAL_BYTE_TOO_BIG: ++ *errcode = G_REGEX_ERROR_INVALID_OCTAL_VALUE; + *errmsg = _("octal value is greater than \\377"); + break; +- case 152: /* internal error: overran compiling workspace */ +- *errcode = G_REGEX_ERROR_INTERNAL; +- *errmsg = _("overran compiling workspace"); +- break; +- case 153: /* internal error: previously-checked referenced subpattern not found */ +- *errcode = G_REGEX_ERROR_INTERNAL; +- *errmsg = _("previously-checked referenced subpattern not found"); +- break; +- case G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE: ++ case PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES: ++ *errcode = G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE; + *errmsg = _("DEFINE group contains more than one branch"); + break; +- case G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS: ++ case PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE: ++ *errcode = G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS; + *errmsg = _("inconsistent NEWLINE options"); + break; +- case G_REGEX_ERROR_MISSING_BACK_REFERENCE: ++ case PCRE2_ERROR_BACKSLASH_G_SYNTAX: ++ *errcode = G_REGEX_ERROR_MISSING_BACK_REFERENCE; + *errmsg = _("\\g is not followed by a braced, angle-bracketed, or quoted name or " + "number, or by a plain number"); + break; +- case G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE: +- *errmsg = _("a numbered reference must not be zero"); +- break; +- case G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN: ++ case PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED: ++ *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN; + *errmsg = _("an argument is not allowed for (*ACCEPT), (*FAIL), or (*COMMIT)"); + break; +- case G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB: ++ case PCRE2_ERROR_VERB_UNKNOWN: ++ *errcode = G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB; + *errmsg = _("(*VERB) not recognized"); + break; +- case G_REGEX_ERROR_NUMBER_TOO_BIG: ++ case PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG: ++ *errcode = G_REGEX_ERROR_NUMBER_TOO_BIG; + *errmsg = _("number is too big"); + break; +- case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME: ++ case PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED: ++ *errcode = G_REGEX_ERROR_MISSING_SUBPATTERN_NAME; + *errmsg = _("missing subpattern name after (?&"); + break; +- case G_REGEX_ERROR_MISSING_DIGIT: +- *errmsg = _("digit expected after (?+"); +- break; +- case G_REGEX_ERROR_INVALID_DATA_CHARACTER: +- *errmsg = _("] is an invalid data character in JavaScript compatibility mode"); +- break; +- case G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME: ++ case PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH: ++ *errcode = G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME; + *errmsg = _("different names for subpatterns of the same number are not allowed"); + break; +- case G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED: ++ case PCRE2_ERROR_MARK_MISSING_ARGUMENT: ++ *errcode = G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED; + *errmsg = _("(*MARK) must have an argument"); + break; +- case G_REGEX_ERROR_INVALID_CONTROL_CHAR: ++ case PCRE2_ERROR_BACKSLASH_C_SYNTAX: ++ *errcode = G_REGEX_ERROR_INVALID_CONTROL_CHAR; + *errmsg = _( "\\c must be followed by an ASCII character"); + break; +- case G_REGEX_ERROR_MISSING_NAME: ++ case PCRE2_ERROR_BACKSLASH_K_SYNTAX: ++ *errcode = G_REGEX_ERROR_MISSING_NAME; + *errmsg = _("\\k is not followed by a braced, angle-bracketed, or quoted name"); + break; +- case G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS: ++ case PCRE2_ERROR_BACKSLASH_N_IN_CLASS: ++ *errcode = G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS; + *errmsg = _("\\N is not supported in a class"); + break; +- case G_REGEX_ERROR_TOO_MANY_FORWARD_REFERENCES: +- *errmsg = _("too many forward references"); +- break; +- case G_REGEX_ERROR_NAME_TOO_LONG: ++ case PCRE2_ERROR_VERB_NAME_TOO_LONG: ++ *errcode = G_REGEX_ERROR_NAME_TOO_LONG; + *errmsg = _("name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)"); + break; +- case G_REGEX_ERROR_CHARACTER_VALUE_TOO_LARGE: +- *errmsg = _("character value in \\u.... sequence is too large"); ++ case PCRE2_ERROR_INTERNAL_CODE_OVERFLOW: ++ *errcode = G_REGEX_ERROR_INTERNAL; ++ *errmsg = _("code overflow"); + break; +- +- case 116: /* erroffset passed as NULL */ +- /* This should not happen as we never pass a NULL erroffset */ +- g_warning ("erroffset passed as NULL"); +- *errcode = G_REGEX_ERROR_COMPILE; ++ case PCRE2_ERROR_UNRECOGNIZED_AFTER_QUERY_P: ++ *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; ++ *errmsg = _("unrecognized character after (?P"); + break; +- case 117: /* unknown option bit(s) set */ +- /* This should not happen as we check options before passing them +- * to pcre_compile2() */ +- g_warning ("unknown option bit(s) set"); +- *errcode = G_REGEX_ERROR_COMPILE; ++ case PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE: ++ *errcode = G_REGEX_ERROR_INTERNAL; ++ *errmsg = _("overran compiling workspace"); + break; +- case 132: /* this version of PCRE is compiled without UTF support */ +- case 144: /* invalid UTF-8 string */ +- case 145: /* support for \\P, \\p, and \\X has not been compiled */ +- case 167: /* this version of PCRE is not compiled with Unicode property support */ +- case 173: /* disallowed Unicode code point (>= 0xd800 && <= 0xdfff) */ +- case 174: /* invalid UTF-16 string */ +- /* These errors should not happen as we are using an UTF-8 and UCP-enabled PCRE +- * and we do not check if strings are valid */ +- case 170: /* internal error: unknown opcode in find_fixedlength() */ ++ case PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN: + *errcode = G_REGEX_ERROR_INTERNAL; ++ *errmsg = _("previously-checked referenced subpattern not found"); + break; +- ++ case PCRE2_ERROR_HEAP_FAILED: ++ case PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW: ++ case PCRE2_ERROR_UNICODE_NOT_SUPPORTED: ++ case PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT: ++ case PCRE2_ERROR_NO_SURROGATES_IN_UTF16: ++ case PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS: ++ case PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE: ++ case PCRE2_ERROR_INTERNAL_STUDY_ERROR: ++ case PCRE2_ERROR_UTF_IS_DISABLED: ++ case PCRE2_ERROR_UCP_IS_DISABLED: ++ case PCRE2_ERROR_INTERNAL_BAD_CODE_AUTO_POSSESS: ++ case PCRE2_ERROR_BACKSLASH_C_LIBRARY_DISABLED: ++ case PCRE2_ERROR_INTERNAL_BAD_CODE: ++ case PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP: ++ *errcode = G_REGEX_ERROR_INTERNAL; ++ *errmsg = _("internal error"); ++ break; ++ case PCRE2_ERROR_INVALID_SUBPATTERN_NAME: ++ case PCRE2_ERROR_CLASS_INVALID_RANGE: ++ case PCRE2_ERROR_ZERO_RELATIVE_REFERENCE: ++ case PCRE2_ERROR_PARENTHESES_STACK_CHECK: ++ case PCRE2_ERROR_LOOKBEHIND_TOO_COMPLICATED: ++ case PCRE2_ERROR_CALLOUT_NUMBER_TOO_BIG: ++ case PCRE2_ERROR_MISSING_CALLOUT_CLOSING: ++ case PCRE2_ERROR_ESCAPE_INVALID_IN_VERB: ++ case PCRE2_ERROR_NULL_PATTERN: ++ case PCRE2_ERROR_BAD_OPTIONS: ++ case PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP: ++ case PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE: ++ case PCRE2_ERROR_INVALID_OCTAL: ++ case PCRE2_ERROR_CALLOUT_STRING_TOO_LONG: ++ case PCRE2_ERROR_BACKSLASH_U_CODE_POINT_TOO_BIG: ++ case PCRE2_ERROR_MISSING_OCTAL_OR_HEX_DIGITS: ++ case PCRE2_ERROR_VERSION_CONDITION_SYNTAX: ++ case PCRE2_ERROR_CALLOUT_NO_STRING_DELIMITER: ++ case PCRE2_ERROR_CALLOUT_BAD_STRING_DELIMITER: ++ case PCRE2_ERROR_BACKSLASH_C_CALLER_DISABLED: ++ case PCRE2_ERROR_QUERY_BARJX_NEST_TOO_DEEP: ++ case PCRE2_ERROR_PATTERN_TOO_COMPLICATED: ++ case PCRE2_ERROR_LOOKBEHIND_TOO_LONG: ++ case PCRE2_ERROR_PATTERN_STRING_TOO_LONG: ++ case PCRE2_ERROR_BAD_LITERAL_OPTIONS: + default: + *errcode = G_REGEX_ERROR_COMPILE; ++ *errmsg = _("internal error"); ++ break; + } ++ ++ g_assert (*errcode != 0); ++ g_assert (*errmsg != NULL); + } + + /* GMatchInfo */ +@@ -568,12 +747,16 @@ match_info_new (const GRegex *regex, + match_info->regex = g_regex_ref ((GRegex *)regex); + match_info->string = string; + match_info->string_len = string_len; +- match_info->matches = PCRE_ERROR_NOMATCH; ++ match_info->matches = PCRE2_ERROR_NOMATCH; + match_info->pos = start_position; + match_info->match_opts = match_options; + +- pcre_fullinfo (regex->pcre_re, regex->extra, +- PCRE_INFO_CAPTURECOUNT, &match_info->n_subpatterns); ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, ++ &match_info->n_subpatterns); ++ ++ match_info->match_context = pcre2_match_context_create (NULL); ++ pcre2_set_match_limit (match_info->match_context, 65536); /* should be plenty */ ++ pcre2_set_recursion_limit (match_info->match_context, 64); /* should be plenty */ + + if (is_dfa) + { +@@ -593,9 +776,41 @@ match_info_new (const GRegex *regex, + match_info->offsets[0] = -1; + match_info->offsets[1] = -1; + ++ match_info->match_data = pcre2_match_data_create_from_pattern ( ++ match_info->regex->pcre_re, ++ NULL); ++ + return match_info; + } + ++static gboolean ++recalc_match_offsets (GMatchInfo *match_info, ++ GError **error) ++{ ++ PCRE2_SIZE *ovector; ++ gint i; ++ ++ if (pcre2_get_ovector_count (match_info->match_data) > G_MAXINT / 2) ++ { ++ g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, ++ _("Error while matching regular expression %s: %s"), ++ match_info->regex->pattern, _("code overflow")); ++ return FALSE; ++ } ++ ++ 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)); ++ for (i = 0; i < match_info->n_offsets; i++) ++ { ++ match_info->offsets[i] = (int) ovector[i]; ++ } ++ ++ return TRUE; ++} ++ + /** + * g_match_info_get_regex: + * @match_info: a #GMatchInfo +@@ -667,6 +882,10 @@ g_match_info_unref (GMatchInfo *match_info) + if (g_atomic_int_dec_and_test (&match_info->ref_count)) + { + g_regex_unref (match_info->regex); ++ if (match_info->match_context) ++ pcre2_match_context_free (match_info->match_context); ++ if (match_info->match_data) ++ pcre2_match_data_free (match_info->match_data); + g_free (match_info->offsets); + g_free (match_info->workspace); + g_free (match_info); +@@ -713,6 +932,7 @@ g_match_info_next (GMatchInfo *match_info, + { + gint prev_match_start; + gint prev_match_end; ++ gint opts; + + g_return_val_if_fail (match_info != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); +@@ -725,25 +945,29 @@ g_match_info_next (GMatchInfo *match_info, + { + /* we have reached the end of the string */ + match_info->pos = -1; +- match_info->matches = PCRE_ERROR_NOMATCH; ++ match_info->matches = PCRE2_ERROR_NOMATCH; + return FALSE; + } + +- match_info->matches = pcre_exec (match_info->regex->pcre_re, +- match_info->regex->extra, +- match_info->string, +- match_info->string_len, +- match_info->pos, +- match_info->regex->match_opts | match_info->match_opts, +- match_info->offsets, +- match_info->n_offsets); +- if (IS_PCRE_ERROR (match_info->matches)) ++ opts = map_to_pcre2_match_flags (match_info->regex->match_opts | match_info->match_opts); ++ match_info->matches = pcre2_match (match_info->regex->pcre_re, ++ (PCRE2_SPTR8) match_info->string, ++ match_info->string_len, ++ match_info->pos, ++ opts & ~G_REGEX_FLAGS_CONVERTED, ++ match_info->match_data, ++ match_info->match_context); ++ ++ if (IS_PCRE2_ERROR (match_info->matches)) + { + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, + _("Error while matching regular expression %s: %s"), + match_info->regex->pattern, match_error (match_info->matches)); + return FALSE; + } ++ else ++ if (!recalc_match_offsets (match_info, error)) ++ return FALSE; + + /* avoid infinite loops if the pattern is an empty string or something + * equivalent */ +@@ -753,7 +977,7 @@ g_match_info_next (GMatchInfo *match_info, + { + /* we have reached the end of the string */ + match_info->pos = -1; +- match_info->matches = PCRE_ERROR_NOMATCH; ++ match_info->matches = PCRE2_ERROR_NOMATCH; + return FALSE; + } + +@@ -831,10 +1055,10 @@ g_match_info_get_match_count (const GMatchInfo *match_info) + { + g_return_val_if_fail (match_info, -1); + +- if (match_info->matches == PCRE_ERROR_NOMATCH) ++ if (match_info->matches == PCRE2_ERROR_NOMATCH) + /* no match */ + return 0; +- else if (match_info->matches < PCRE_ERROR_NOMATCH) ++ else if (match_info->matches < PCRE2_ERROR_NOMATCH) + /* error */ + return -1; + else +@@ -889,7 +1113,7 @@ g_match_info_is_partial_match (const GMatchInfo *match_info) + { + g_return_val_if_fail (match_info != NULL, FALSE); + +- return match_info->matches == PCRE_ERROR_PARTIAL; ++ return match_info->matches == PCRE2_ERROR_PARTIAL; + } + + /** +@@ -986,8 +1210,6 @@ gchar * + g_match_info_fetch (const GMatchInfo *match_info, + gint match_num) + { +- /* we cannot use pcre_get_substring() because it allocates the +- * string using pcre_malloc(). */ + gchar *match = NULL; + gint start, end; + +@@ -1067,24 +1289,25 @@ g_match_info_fetch_pos (const GMatchInfo *match_info, + * Returns number of first matched subpattern with name @name. + * There may be more than one in case when DUPNAMES is used, + * and not all subpatterns with that name match; +- * pcre_get_stringnumber() does not work in that case. ++ * pcre2_substring_number_from_name() does not work in that case. + */ + static gint + get_matched_substring_number (const GMatchInfo *match_info, + const gchar *name) + { + gint entrysize; +- gchar *first, *last; ++ PCRE2_SPTR first, last; + guchar *entry; + +- if (!(match_info->regex->compile_opts & G_REGEX_DUPNAMES)) +- return pcre_get_stringnumber (match_info->regex->pcre_re, name); ++ if (!(match_info->regex->compile_opts & PCRE2_DUPNAMES)) ++ return pcre2_substring_number_from_name (match_info->regex->pcre_re, (PCRE2_SPTR8) name); + +- /* This code is copied from pcre_get.c: get_first_set() */ +- entrysize = pcre_get_stringtable_entries (match_info->regex->pcre_re, +- name, +- &first, +- &last); ++ /* This code is analogous to code from pcre2_substring.c: ++ * pcre2_substring_get_byname() */ ++ entrysize = pcre2_substring_nametable_scan (match_info->regex->pcre_re, ++ (PCRE2_SPTR8) name, ++ &first, ++ &last); + + if (entrysize <= 0) + return entrysize; +@@ -1122,8 +1345,6 @@ gchar * + g_match_info_fetch_named (const GMatchInfo *match_info, + const gchar *name) + { +- /* we cannot use pcre_get_named_substring() because it allocates the +- * string using pcre_malloc(). */ + gint num; + + g_return_val_if_fail (match_info != NULL, NULL); +@@ -1205,8 +1426,6 @@ g_match_info_fetch_named_pos (const GMatchInfo *match_info, + gchar ** + g_match_info_fetch_all (const GMatchInfo *match_info) + { +- /* we cannot use pcre_get_substring_list() because the returned value +- * isn't suitable for g_strfreev(). */ + gchar **result; + gint i; + +@@ -1264,9 +1483,7 @@ g_regex_unref (GRegex *regex) + { + g_free (regex->pattern); + if (regex->pcre_re != NULL) +- pcre_free (regex->pcre_re); +- if (regex->extra != NULL) +- pcre_free (regex->extra); ++ pcre2_code_free (regex->pcre_re); + g_free (regex); + } + } +@@ -1274,11 +1491,11 @@ g_regex_unref (GRegex *regex) + /* + * @match_options: (inout) (optional): + */ +-static pcre *regex_compile (const gchar *pattern, +- GRegexCompileFlags compile_options, +- GRegexCompileFlags *compile_options_out, +- GRegexMatchFlags *match_options, +- GError **error); ++static pcre2_code *regex_compile (const gchar *pattern, ++ GRegexCompileFlags compile_options, ++ GRegexCompileFlags *compile_options_out, ++ GRegexMatchFlags *match_options, ++ GError **error); + + /** + * g_regex_new: +@@ -1302,10 +1519,13 @@ g_regex_new (const gchar *pattern, + GError **error) + { + GRegex *regex; +- pcre *re; +- const gchar *errmsg; +- gboolean optimize = FALSE; ++ pcre2_code *re; + static gsize initialised = 0; ++ GRegexCompileFlags orig_compile_opts; ++ ++ orig_compile_opts = compile_options; ++ compile_options = map_to_pcre2_compile_flags (compile_options); ++ match_options = map_to_pcre2_match_flags (match_options); + + g_return_val_if_fail (pattern != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); +@@ -1314,17 +1534,13 @@ g_regex_new (const gchar *pattern, + + if (g_once_init_enter (&initialised)) + { +- int supports_utf8, supports_ucp; ++ int supports_utf8; + +- pcre_config (PCRE_CONFIG_UTF8, &supports_utf8); ++ pcre2_config (PCRE2_CONFIG_UNICODE, &supports_utf8); + if (!supports_utf8) + g_critical (_("PCRE library is compiled without UTF8 support")); + +- pcre_config (PCRE_CONFIG_UNICODE_PROPERTIES, &supports_ucp); +- if (!supports_ucp) +- g_critical (_("PCRE library is compiled without UTF8 properties support")); +- +- g_once_init_leave (&initialised, supports_utf8 && supports_ucp ? 1 : 2); ++ g_once_init_leave (&initialised, supports_utf8 ? 1 : 2); + } + + if (G_UNLIKELY (initialised != 1)) +@@ -1334,14 +1550,22 @@ g_regex_new (const gchar *pattern, + return NULL; + } + +- /* G_REGEX_OPTIMIZE has the same numeric value of PCRE_NO_UTF8_CHECK, +- * as we do not need to wrap PCRE_NO_UTF8_CHECK. */ +- if (compile_options & G_REGEX_OPTIMIZE) +- optimize = TRUE; ++ switch (compile_options & G_REGEX_NEWLINE_MASK) ++ { ++ case 0: /* PCRE2_NEWLINE_ANY */ ++ case PCRE2_NEWLINE_CR: ++ case PCRE2_NEWLINE_LF: ++ case PCRE2_NEWLINE_CRLF: ++ case PCRE2_NEWLINE_ANYCRLF: ++ break; ++ default: ++ g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS, ++ "Invalid newline flags"); ++ return NULL; ++ } + + re = regex_compile (pattern, compile_options, &compile_options, + &match_options, error); +- + if (re == NULL) + return NULL; + +@@ -1350,80 +1574,85 @@ g_regex_new (const gchar *pattern, + regex->pattern = g_strdup (pattern); + regex->pcre_re = re; + regex->compile_opts = compile_options; ++ regex->orig_compile_opts = orig_compile_opts; + regex->match_opts = match_options; + +- if (optimize) +- { +- regex->extra = pcre_study (regex->pcre_re, 0, &errmsg); +- if (errmsg != NULL) +- { +- GError *tmp_error = g_error_new (G_REGEX_ERROR, +- G_REGEX_ERROR_OPTIMIZE, +- _("Error while optimizing " +- "regular expression %s: %s"), +- regex->pattern, +- errmsg); +- g_propagate_error (error, tmp_error); +- +- g_regex_unref (regex); +- return NULL; +- } +- } +- + return regex; + } + +-static pcre * +-regex_compile (const gchar *pattern, +- GRegexCompileFlags compile_options, +- GRegexCompileFlags *compile_options_out, +- GRegexMatchFlags *match_options, +- GError **error) ++static gint ++extract_newline_options (const GRegexCompileFlags compile_options, ++ const GRegexMatchFlags *match_options) ++{ ++ gint newline_options = PCRE2_NEWLINE_ANY; ++ ++ if (compile_options & G_REGEX_NEWLINE_MASK) ++ newline_options = compile_options & G_REGEX_NEWLINE_MASK; ++ if (match_options && *match_options & G_REGEX_MATCH_NEWLINE_MASK) ++ newline_options = *match_options & G_REGEX_MATCH_NEWLINE_MASK; ++ ++ return newline_options; ++} ++ ++static gint ++extract_bsr_options (const GRegexCompileFlags compile_options, ++ const GRegexMatchFlags *match_options) ++{ ++ gint bsr_options = PCRE2_BSR_UNICODE; ++ ++ if (compile_options & PCRE2_BSR_ANYCRLF) ++ bsr_options = PCRE2_BSR_ANYCRLF; ++ if (match_options && *match_options & PCRE2_BSR_ANYCRLF) ++ bsr_options = PCRE2_BSR_ANYCRLF; ++ if (match_options && *match_options & PCRE2_BSR_UNICODE) ++ bsr_options = PCRE2_BSR_UNICODE; ++ ++ return bsr_options; ++} ++ ++static pcre2_code * ++regex_compile (const gchar *pattern, ++ GRegexCompileFlags compile_options, ++ GRegexCompileFlags *compile_options_out, ++ GRegexMatchFlags *match_options, ++ GError **error) + { +- pcre *re; ++ pcre2_code *re; ++ pcre2_compile_context *context; + const gchar *errmsg; +- gint erroffset; ++ PCRE2_SIZE erroffset; + gint errcode; + GRegexCompileFlags nonpcre_compile_options; + unsigned long int pcre_compile_options; + + nonpcre_compile_options = compile_options & G_REGEX_COMPILE_NONPCRE_MASK; + +- /* In GRegex the string are, by default, UTF-8 encoded. PCRE +- * instead uses UTF-8 only if required with PCRE_UTF8. */ +- if (compile_options & G_REGEX_RAW) +- { +- /* disable utf-8 */ +- compile_options &= ~G_REGEX_RAW; +- } +- else +- { +- /* enable utf-8 */ +- compile_options |= PCRE_UTF8 | PCRE_NO_UTF8_CHECK; ++ context = pcre2_compile_context_create (NULL); + +- if (match_options != NULL) +- *match_options |= PCRE_NO_UTF8_CHECK; +- } ++ /* set newline options */ ++ pcre2_set_newline (context, extract_newline_options (compile_options, match_options)); ++ ++ /* set bsr options */ ++ pcre2_set_bsr (context, extract_bsr_options (compile_options, match_options)); + +- /* PCRE_NEWLINE_ANY is the default for the internal PCRE but +- * not for the system one. */ +- if (!(compile_options & G_REGEX_NEWLINE_CR) && +- !(compile_options & G_REGEX_NEWLINE_LF)) ++ /* In case UTF-8 mode is used, also set PCRE2_NO_UTF_CHECK */ ++ if (compile_options & PCRE2_UTF) + { +- compile_options |= PCRE_NEWLINE_ANY; ++ compile_options |= PCRE2_NO_UTF_CHECK; ++ if (match_options != NULL) ++ *match_options |= PCRE2_NO_UTF_CHECK; + } + +- compile_options |= PCRE_UCP; +- +- /* PCRE_BSR_UNICODE is the default for the internal PCRE but +- * possibly not for the system one. +- */ +- if (~compile_options & G_REGEX_BSR_ANYCRLF) +- compile_options |= PCRE_BSR_UNICODE; ++ compile_options |= PCRE2_UCP; + + /* compile the pattern */ +- re = pcre_compile2 (pattern, compile_options, &errcode, +- &errmsg, &erroffset, NULL); ++ re = pcre2_compile ((PCRE2_SPTR8) pattern, ++ PCRE2_ZERO_TERMINATED, ++ compile_options & ~G_REGEX_FLAGS_CONVERTED, ++ &errcode, ++ &erroffset, ++ context); ++ pcre2_compile_context_free (context); + + /* if the compilation failed, set the error member and return + * immediately */ +@@ -1440,7 +1669,7 @@ regex_compile (const gchar *pattern, + + tmp_error = g_error_new (G_REGEX_ERROR, errcode, + _("Error while compiling regular " +- "expression %s at char %d: %s"), ++ "expression %s at char %" G_GSIZE_FORMAT ": %s"), + pattern, erroffset, errmsg); + g_propagate_error (error, tmp_error); + +@@ -1449,22 +1678,22 @@ regex_compile (const gchar *pattern, + + /* For options set at the beginning of the pattern, pcre puts them into + * compile options, e.g. "(?i)foo" will make the pcre structure store +- * PCRE_CASELESS even though it wasn't explicitly given for compilation. */ +- pcre_fullinfo (re, NULL, PCRE_INFO_OPTIONS, &pcre_compile_options); ++ * PCRE2_CASELESS even though it wasn't explicitly given for compilation. */ ++ pcre2_pattern_info (re, PCRE2_INFO_ALLOPTIONS, &pcre_compile_options); + compile_options = pcre_compile_options & G_REGEX_COMPILE_PCRE_MASK; + +- /* Don't leak PCRE_NEWLINE_ANY, which is part of PCRE_NEWLINE_ANYCRLF */ +- if ((pcre_compile_options & PCRE_NEWLINE_ANYCRLF) != PCRE_NEWLINE_ANYCRLF) +- compile_options &= ~PCRE_NEWLINE_ANY; ++ /* Don't leak PCRE2_NEWLINE_ANY, which is part of PCRE2_NEWLINE_ANYCRLF */ ++ if ((pcre_compile_options & PCRE2_NEWLINE_ANYCRLF) != PCRE2_NEWLINE_ANYCRLF) ++ compile_options &= ~PCRE2_NEWLINE_ANY; + + compile_options |= nonpcre_compile_options; + +- if (!(compile_options & G_REGEX_DUPNAMES)) ++ if (!(compile_options & PCRE2_DUPNAMES)) + { + gboolean jchanged = FALSE; +- pcre_fullinfo (re, NULL, PCRE_INFO_JCHANGED, &jchanged); ++ pcre2_pattern_info (re, PCRE2_INFO_JCHANGED, &jchanged); + if (jchanged) +- compile_options |= G_REGEX_DUPNAMES; ++ compile_options |= PCRE2_DUPNAMES; + } + + if (compile_options_out != 0) +@@ -1509,8 +1738,7 @@ g_regex_get_max_backref (const GRegex *regex) + { + gint value; + +- pcre_fullinfo (regex->pcre_re, regex->extra, +- PCRE_INFO_BACKREFMAX, &value); ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BACKREFMAX, &value); + + return value; + } +@@ -1530,8 +1758,7 @@ g_regex_get_capture_count (const GRegex *regex) + { + gint value; + +- pcre_fullinfo (regex->pcre_re, regex->extra, +- PCRE_INFO_CAPTURECOUNT, &value); ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, &value); + + return value; + } +@@ -1551,8 +1778,7 @@ g_regex_get_has_cr_or_lf (const GRegex *regex) + { + gint value; + +- pcre_fullinfo (regex->pcre_re, regex->extra, +- PCRE_INFO_HASCRORLF, &value); ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_HASCRORLF, &value); + + return !!value; + } +@@ -1574,8 +1800,8 @@ g_regex_get_max_lookbehind (const GRegex *regex) + { + gint max_lookbehind; + +- pcre_fullinfo (regex->pcre_re, regex->extra, +- PCRE_INFO_MAXLOOKBEHIND, &max_lookbehind); ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_MAXLOOKBEHIND, ++ &max_lookbehind); + + return max_lookbehind; + } +@@ -1597,9 +1823,47 @@ g_regex_get_max_lookbehind (const GRegex *regex) + GRegexCompileFlags + g_regex_get_compile_flags (const GRegex *regex) + { ++ gint extra_flags, info_value; ++ + g_return_val_if_fail (regex != NULL, 0); + +- return regex->compile_opts; ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS ++ /* Preserve original G_REGEX_OPTIMIZE */ ++ extra_flags = (regex->orig_compile_opts & G_REGEX_OPTIMIZE); ++G_GNUC_END_IGNORE_DEPRECATIONS ++ ++ /* Also include the newline options */ ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_NEWLINE, &info_value); ++ switch (info_value) ++ { ++ case PCRE2_NEWLINE_ANYCRLF: ++ extra_flags |= G_REGEX_NEWLINE_ANYCRLF; ++ break; ++ case PCRE2_NEWLINE_CRLF: ++ extra_flags |= G_REGEX_NEWLINE_CRLF; ++ break; ++ case PCRE2_NEWLINE_LF: ++ extra_flags |= G_REGEX_NEWLINE_LF; ++ break; ++ case PCRE2_NEWLINE_CR: ++ extra_flags |= G_REGEX_NEWLINE_CR; ++ break; ++ default: ++ break; ++ } ++ ++ /* Also include the bsr options */ ++ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_BSR, &info_value); ++ switch (info_value) ++ { ++ case PCRE2_BSR_ANYCRLF: ++ extra_flags |= G_REGEX_BSR_ANYCRLF; ++ break; ++ default: ++ break; ++ } ++ ++ return map_to_pcre1_compile_flags (regex->compile_opts) | extra_flags; + } + + /** +@@ -1617,7 +1881,7 @@ g_regex_get_match_flags (const GRegex *regex) + { + g_return_val_if_fail (regex != NULL, 0); + +- return regex->match_opts & G_REGEX_MATCH_MASK; ++ return map_to_pcre1_match_flags (regex->match_opts & G_REGEX_MATCH_MASK); + } + + /** +@@ -1651,6 +1915,9 @@ g_regex_match_simple (const gchar *pattern, + GRegex *regex; + gboolean result; + ++ compile_options = map_to_pcre2_compile_flags (compile_options); ++ match_options = map_to_pcre2_match_flags (match_options); ++ + regex = g_regex_new (pattern, compile_options, G_REGEX_MATCH_DEFAULT, NULL); + if (!regex) + return FALSE; +@@ -1718,6 +1985,8 @@ g_regex_match (const GRegex *regex, + GRegexMatchFlags match_options, + GMatchInfo **match_info) + { ++ match_options = map_to_pcre2_match_flags (match_options); ++ + return g_regex_match_full (regex, string, -1, 0, match_options, + match_info, NULL); + } +@@ -1801,6 +2070,8 @@ g_regex_match_full (const GRegex *regex, + GMatchInfo *info; + gboolean match_ok; + ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (start_position >= 0, FALSE); +@@ -1851,6 +2122,8 @@ g_regex_match_all (const GRegex *regex, + GRegexMatchFlags match_options, + GMatchInfo **match_info) + { ++ match_options = map_to_pcre2_match_flags (match_options); ++ + return g_regex_match_all_full (regex, string, -1, 0, match_options, + match_info, NULL); + } +@@ -1920,39 +2193,29 @@ g_regex_match_all_full (const GRegex *regex, + { + GMatchInfo *info; + gboolean done; +- pcre *pcre_re; +- pcre_extra *extra; ++ pcre2_code *pcre_re; + gboolean retval; + ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (start_position >= 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE); + +-#ifdef PCRE_NO_AUTO_POSSESS +- /* For PCRE >= 8.34 we need to turn off PCRE_NO_AUTO_POSSESS, which +- * is an optimization for normal regex matching, but results in omitting +- * some shorter matches here, and an observable behaviour change. ++ /* For PCRE2 we need to turn off PCRE2_NO_AUTO_POSSESS, which is an ++ * optimization for normal regex matching, but results in omitting some ++ * shorter matches here, and an observable behaviour change. + * + * DFA matching is rather niche, and very rarely used according to + * codesearch.debian.net, so don't bother caching the recompiled RE. */ + pcre_re = regex_compile (regex->pattern, +- regex->compile_opts | PCRE_NO_AUTO_POSSESS, ++ regex->compile_opts | PCRE2_NO_AUTO_POSSESS, + NULL, NULL, error); +- + if (pcre_re == NULL) + return FALSE; + +- /* Not bothering to cache the optimization data either, with similar +- * reasoning */ +- extra = NULL; +-#else +- /* For PCRE < 8.33 the precompiled regex is fine. */ +- pcre_re = regex->pcre_re; +- extra = regex->extra; +-#endif +- + info = match_info_new (regex, string, string_len, start_position, + match_options, TRUE); + +@@ -1960,29 +2223,38 @@ g_regex_match_all_full (const GRegex *regex, + while (!done) + { + done = TRUE; +- info->matches = pcre_dfa_exec (pcre_re, extra, +- info->string, info->string_len, +- info->pos, +- regex->match_opts | match_options, +- info->offsets, info->n_offsets, +- info->workspace, info->n_workspace); +- if (info->matches == PCRE_ERROR_DFA_WSSIZE) ++ info->matches = pcre2_dfa_match (pcre_re, ++ (PCRE2_SPTR8) info->string, info->string_len, ++ info->pos, ++ (regex->match_opts | match_options | PCRE2_NO_UTF_CHECK) & ~G_REGEX_FLAGS_CONVERTED, ++ info->match_data, ++ info->match_context, ++ info->workspace, info->n_workspace); ++ ++ if (!recalc_match_offsets (info, error)) ++ return FALSE; ++ ++ if (info->matches == PCRE2_ERROR_DFA_WSSIZE) + { + /* info->workspace is too small. */ + info->n_workspace *= 2; +- info->workspace = g_realloc (info->workspace, +- info->n_workspace * sizeof (gint)); ++ info->workspace = g_realloc_n (info->workspace, ++ info->n_workspace, ++ sizeof (gint)); + done = FALSE; + } + else if (info->matches == 0) + { + /* info->offsets is too small. */ + info->n_offsets *= 2; +- info->offsets = g_realloc (info->offsets, +- info->n_offsets * sizeof (gint)); ++ info->offsets = g_realloc_n (info->offsets, ++ info->n_offsets, ++ sizeof (gint)); ++ pcre2_match_data_free (info->match_data); ++ info->match_data = pcre2_match_data_create (info->n_offsets, NULL); + done = FALSE; + } +- else if (IS_PCRE_ERROR (info->matches)) ++ else if (IS_PCRE2_ERROR (info->matches)) + { + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, + _("Error while matching regular expression %s: %s"), +@@ -1990,9 +2262,7 @@ g_regex_match_all_full (const GRegex *regex, + } + } + +-#ifdef PCRE_NO_AUTO_POSSESS +- pcre_free (pcre_re); +-#endif ++ pcre2_code_free (pcre_re); + + /* don’t assert that (info->matches <= info->n_subpatterns + 1) as that only + * holds true for a single match, rather than matching all */ +@@ -2030,8 +2300,8 @@ g_regex_get_string_number (const GRegex *regex, + g_return_val_if_fail (regex != NULL, -1); + g_return_val_if_fail (name != NULL, -1); + +- num = pcre_get_stringnumber (regex->pcre_re, name); +- if (num == PCRE_ERROR_NOSUBSTRING) ++ num = pcre2_substring_number_from_name (regex->pcre_re, (PCRE2_SPTR8) name); ++ if (num == PCRE2_ERROR_NOSUBSTRING) + num = -1; + + return num; +@@ -2086,6 +2356,9 @@ g_regex_split_simple (const gchar *pattern, + GRegex *regex; + gchar **result; + ++ compile_options = map_to_pcre2_compile_flags (compile_options); ++ match_options = map_to_pcre2_match_flags (match_options); ++ + regex = g_regex_new (pattern, compile_options, 0, NULL); + if (!regex) + return NULL; +@@ -2129,6 +2402,8 @@ g_regex_split (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options) + { ++ match_options = map_to_pcre2_match_flags (match_options); ++ + return g_regex_split_full (regex, string, -1, 0, + match_options, 0, NULL); + } +@@ -2193,6 +2468,8 @@ g_regex_split_full (const GRegex *regex, + /* the returned array of char **s */ + gchar **string_list; + ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +@@ -2817,6 +3094,8 @@ g_regex_replace (const GRegex *regex, + GList *list; + GError *tmp_error = NULL; + ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +@@ -2886,6 +3165,8 @@ g_regex_replace_literal (const GRegex *regex, + GRegexMatchFlags match_options, + GError **error) + { ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (replacement != NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + +@@ -2974,6 +3255,8 @@ g_regex_replace_eval (const GRegex *regex, + gboolean done = FALSE; + GError *tmp_error = NULL; + ++ match_options = map_to_pcre2_match_flags (match_options); ++ + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); +diff --git a/glib/gregex.h b/glib/gregex.h +index 817f667..11b419d 100644 +--- a/glib/gregex.h ++++ b/glib/gregex.h +@@ -262,7 +262,9 @@ GQuark g_regex_error_quark (void); + * in the usual way). + * @G_REGEX_OPTIMIZE: Optimize the regular expression. If the pattern will + * be used many times, then it may be worth the effort to optimize it +- * to improve the speed of matches. ++ * to improve the speed of matches. Deprecated in GLib 2.74 which now uses ++ * libpcre2, which doesn’t require separate optimization of queries. This ++ * option is now a no-op. Deprecated: 2.74 + * @G_REGEX_FIRSTLINE: Limits an unanchored pattern to match before (or at) the + * first newline. Since: 2.34 + * @G_REGEX_DUPNAMES: Names used to identify capturing subpatterns need not +@@ -285,7 +287,8 @@ GQuark g_regex_error_quark (void); + * is recognised. If this option is set, then "\R" only recognizes the newline + * characters '\r', '\n' and '\r\n'. Since: 2.34 + * @G_REGEX_JAVASCRIPT_COMPAT: Changes behaviour so that it is compatible with +- * JavaScript rather than PCRE. Since: 2.34 ++ * JavaScript rather than PCRE. Since GLib 2.74 this is no longer supported, ++ * as libpcre2 does not support it. Since: 2.34 Deprecated: 2.74 + * + * Flags specifying compile-time options. + * +@@ -306,7 +309,7 @@ typedef enum + G_REGEX_UNGREEDY = 1 << 9, + G_REGEX_RAW = 1 << 11, + G_REGEX_NO_AUTO_CAPTURE = 1 << 12, +- G_REGEX_OPTIMIZE = 1 << 13, ++ G_REGEX_OPTIMIZE GLIB_DEPRECATED_ENUMERATOR_IN_2_74 = 1 << 13, + G_REGEX_FIRSTLINE = 1 << 18, + G_REGEX_DUPNAMES = 1 << 19, + G_REGEX_NEWLINE_CR = 1 << 20, +@@ -314,7 +317,7 @@ typedef enum + G_REGEX_NEWLINE_CRLF = G_REGEX_NEWLINE_CR | G_REGEX_NEWLINE_LF, + G_REGEX_NEWLINE_ANYCRLF = G_REGEX_NEWLINE_CR | 1 << 22, + G_REGEX_BSR_ANYCRLF = 1 << 23, +- G_REGEX_JAVASCRIPT_COMPAT = 1 << 25 ++ G_REGEX_JAVASCRIPT_COMPAT GLIB_DEPRECATED_ENUMERATOR_IN_2_74 = 1 << 25 + } GRegexCompileFlags; + + /** +diff --git a/glib/meson.build b/glib/meson.build +index 93fa504..5bf82da 100644 +--- a/glib/meson.build ++++ b/glib/meson.build +@@ -357,13 +357,13 @@ else + glib_dtrace_hdr = [] + endif + +-pcre_static_args = [] ++pcre2_static_args = [] + +-if use_pcre_static_flag +- pcre_static_args = ['-DPCRE_STATIC'] ++if use_pcre2_static_flag ++ pcre2_static_args = ['-DPCRE2_STATIC'] + endif + +-glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre_static_args + glib_hidden_visibility_args ++glib_c_args = ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION'] + pcre2_static_args + glib_hidden_visibility_args + libglib = library('glib-2.0', + glib_dtrace_obj, glib_dtrace_hdr, + sources : [deprecated_sources, glib_sources], +@@ -375,7 +375,7 @@ libglib = library('glib-2.0', + link_args : [noseh_link_args, glib_link_flags, win32_ldflags], + include_directories : configinc, + link_with: [charset_lib, gnulib_lib], +- dependencies : [pcre, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], ++ dependencies : [pcre2, thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], + c_args : glib_c_args, + objc_args : glib_c_args, + ) +diff --git a/glib/tests/meson.build b/glib/tests/meson.build +index 301158e..c1a9ceb 100644 +--- a/glib/tests/meson.build ++++ b/glib/tests/meson.build +@@ -86,8 +86,8 @@ glib_tests = { + }, + 'refstring' : {}, + 'regex' : { +- 'dependencies' : [pcre], +- 'c_args' : use_pcre_static_flag ? ['-DPCRE_STATIC'] : [], ++ 'dependencies' : [pcre2], ++ 'c_args' : use_pcre2_static_flag ? ['-DPCRE2_STATIC'] : [], + }, + 'relation' : {}, + 'rwlock' : {}, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 50fd9c6..36982fb 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -25,7 +25,8 @@ + #include + #include "glib.h" + +-#include ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include + + /* U+20AC EURO SIGN (symbol, currency) */ + #define EURO "\xe2\x82\xac" +@@ -1501,7 +1502,7 @@ test_properties (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\p{L}\\p{Ll}\\p{Lu}\\p{L&}\\p{N}\\p{Nd}", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "ppPP01", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1522,7 +1523,7 @@ test_class (void) + gchar *str; + + error = NULL; +- regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("[abc\\x{0B1E}\\p{Mn}\\x{0391}-\\x{03A9}]", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + res = g_regex_match (regex, "a:b:\340\254\236:\333\253:\316\240", 0, &match); + g_assert (res); + str = g_match_info_fetch (match, 0); +@@ -1568,7 +1569,7 @@ test_lookahead (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("\\w+(?=;)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\w+(?=;)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "word1 word2: word3;", 0, &match); +@@ -1582,7 +1583,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("foo(?!bar)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("foo(?!bar)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1597,7 +1598,7 @@ test_lookahead (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("(?!bar)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("(?!bar)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "foobar foobaz", 0, &match); +@@ -1630,7 +1631,7 @@ test_lookbehind (void) + gint start, end; + + error = NULL; +- regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("(?Mon|Fri|Sun)(?:day)?|(?Tue)(?:sday)?|(?Wed)(?:nesday)?|(?Thu)(?:rsday)?|(?Sat)(?:urday)?", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "Mon Tuesday Wed Saturday", 0, &match); +@@ -1894,7 +1895,7 @@ test_subpattern (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a|b\\1)+$", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "aaaaaaaaaaaaaaaa", 0, &match); +@@ -1918,7 +1919,7 @@ test_condition (void) + gboolean res; + + error = NULL; +- regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(\\()?[^()]+(?(-1)\\))(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1932,7 +1933,7 @@ test_condition (void) + g_regex_unref (regex); + + error = NULL; +- regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(?\\()?[^()]+(?()\\))(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a(zzzzzz)b", 0, &match); +@@ -1945,7 +1946,7 @@ test_condition (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(a+)(?(+1)\\[|\\<)?[^()]+(\\])?(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "a[zzzzzz]b", 0, &match); +@@ -1960,7 +1961,7 @@ test_condition (void) + + regex = g_regex_new ("(?(DEFINE) (? 2[0-4]\\d | 25[0-5] | 1\\d\\d | [1-9]?\\d) )" + "\\b (?&byte) (\\.(?&byte)){3} \\b", +- G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "128.0.0.1", 0, &match); +@@ -1979,7 +1980,7 @@ test_condition (void) + + regex = g_regex_new ("^(?(?=[^a-z]*[a-z])" + "\\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} )$", +- G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error); ++ G_REGEX_EXTENDED, 0, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "01-abc-24", 0, &match); +@@ -2012,7 +2013,7 @@ test_recursion (void) + gint start; + + error = NULL; +- regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("\\( ( [^()]++ | (?R) )* \\)", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "(middle)", 0, &match); +@@ -2029,7 +2030,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^( \\( ( [^()]++ | (?1) )* \\) )$", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "((((((((((((((((middle))))))))))))))))", 0, &match); +@@ -2042,7 +2043,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(? \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + g_regex_match (regex, "(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()", 0, &match); +@@ -2051,7 +2052,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, ">>>", 0, &match); +@@ -2070,7 +2071,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^((.)(?1)\\2|.)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2083,7 +2084,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^(?:((.)(?1)\\2|)|((.)(?3)\\4|.))$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2096,7 +2097,7 @@ test_recursion (void) + g_match_info_free (match); + g_regex_unref (regex); + +- regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_OPTIMIZE|G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error); ++ regex = g_regex_new ("^\\W*+(?:((.)\\W*+(?1)\\W*+\\2|)|((.)\\W*+(?3)\\W*+\\4|\\W*+.\\W*+))\\W*+$", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT, &error); + g_assert (regex); + g_assert_no_error (error); + res = g_regex_match (regex, "abcdcba", 0, &match); +@@ -2167,21 +2168,21 @@ test_max_lookbehind (void) + } + + static gboolean +-pcre_ge (guint64 major, guint64 minor) ++pcre2_ge (guint64 major, guint64 minor) + { +- const char *version; +- gchar *ptr; +- guint64 pcre_major, pcre_minor; ++ gchar version[32]; ++ const gchar *ptr; ++ guint64 pcre2_major, pcre2_minor; + +- /* e.g. 8.35 2014-04-04 */ +- version = pcre_version (); ++ /* e.g. 10.36 2020-12-04 */ ++ pcre2_config (PCRE2_CONFIG_VERSION, version); + +- pcre_major = g_ascii_strtoull (version, &ptr, 10); ++ pcre2_major = g_ascii_strtoull (version, (gchar **) &ptr, 10); + /* ptr points to ".MINOR (release date)" */ + g_assert (ptr[0] == '.'); +- pcre_minor = g_ascii_strtoull (ptr + 1, NULL, 10); ++ pcre2_minor = g_ascii_strtoull (ptr + 1, NULL, 10); + +- return (pcre_major > major) || (pcre_major == major && pcre_minor >= minor); ++ return (pcre2_major > major) || (pcre2_major == major && pcre2_minor >= minor); + } + + int +@@ -2203,18 +2204,26 @@ main (int argc, char *argv[]) + g_test_add_func ("/regex/max-lookbehind", test_max_lookbehind); + + /* TEST_NEW(pattern, compile_opts, match_opts) */ ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("[A-Z]+", G_REGEX_CASELESS | G_REGEX_EXTENDED | G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTBOL | G_REGEX_MATCH_PARTIAL); ++G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW("", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW(".*", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); ++G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW(".*", G_REGEX_MULTILINE, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_DEFAULT); + TEST_NEW(".*", G_REGEX_DOTALL, G_REGEX_MATCH_NOTBOL); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT); ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("(123\\d*)[a-zA-Z]+(?P.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); ++G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT); ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW("(?Px)|(?Py)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT); ++G_GNUC_END_IGNORE_DEPRECATIONS + /* This gives "internal error: code overflow" with pcre 6.0 */ + TEST_NEW("(?i)(?-i)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + TEST_NEW ("(?i)a", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); +@@ -2225,9 +2234,10 @@ main (int argc, char *argv[]) + TEST_NEW ("(?U)[a-z]+", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT); + + /* TEST_NEW_CHECK_FLAGS(pattern, compile_opts, match_ops, real_compile_opts, real_match_opts) */ ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_OPTIMIZE, 0, G_REGEX_OPTIMIZE, 0); ++G_GNUC_END_IGNORE_DEPRECATIONS + TEST_NEW_CHECK_FLAGS ("a", G_REGEX_RAW, 0, G_REGEX_RAW, 0); +- TEST_NEW_CHECK_FLAGS ("(?X)a", 0, 0, 0 /* not exposed by GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("^.*", 0, 0, G_REGEX_ANCHORED, 0); + TEST_NEW_CHECK_FLAGS ("(*UTF8)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*UCP)a", 0, 0, 0 /* this always on in GRegex */, 0); +@@ -2255,16 +2265,16 @@ main (int argc, char *argv[]) + TEST_NEW_FAIL ("a{4,2}", 0, G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER); + TEST_NEW_FAIL ("a{999999,}", 0, G_REGEX_ERROR_QUANTIFIER_TOO_BIG); + TEST_NEW_FAIL ("[a-z", 0, G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS); +- TEST_NEW_FAIL ("(?X)[\\B]", 0, G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS); ++ TEST_NEW_FAIL ("[\\B]", 0, G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS); + TEST_NEW_FAIL ("[z-a]", 0, G_REGEX_ERROR_RANGE_OUT_OF_ORDER); + TEST_NEW_FAIL ("{2,4}", 0, G_REGEX_ERROR_NOTHING_TO_REPEAT); + TEST_NEW_FAIL ("a(?u)", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER); +- TEST_NEW_FAIL ("a(?<$foo)bar", 0, G_REGEX_ERROR_UNRECOGNIZED_CHARACTER); ++ TEST_NEW_FAIL ("a(?<$foo)bar", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME); + TEST_NEW_FAIL ("a[:alpha:]b", 0, G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS); + TEST_NEW_FAIL ("a(b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("a)b", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); + TEST_NEW_FAIL ("a(?R", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); +- TEST_NEW_FAIL ("a(?-54", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); ++ TEST_NEW_FAIL ("a(?-54", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE); + TEST_NEW_FAIL ("(ab\\2)", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE); + TEST_NEW_FAIL ("a(?#abc", 0, G_REGEX_ERROR_UNTERMINATED_COMMENT); + TEST_NEW_FAIL ("(?<=a+)b", 0, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND); +@@ -2274,51 +2284,31 @@ main (int argc, char *argv[]) + TEST_NEW_FAIL ("a[[:fubar:]]b", 0, G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME); + TEST_NEW_FAIL ("[[.ch.]]", 0, G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED); + TEST_NEW_FAIL ("\\x{110000}", 0, G_REGEX_ERROR_HEX_CODE_TOO_LARGE); +- TEST_NEW_FAIL ("^(?(0)f|b)oo", 0, G_REGEX_ERROR_INVALID_CONDITION); ++ TEST_NEW_FAIL ("^(?(0)f|b)oo", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE); + TEST_NEW_FAIL ("(?<=\\C)X", 0, G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND); +- TEST_NEW_FAIL ("(?!\\w)(?R)", 0, G_REGEX_ERROR_INFINITE_LOOP); +- if (pcre_ge (8, 37)) +- { +- /* The expected errors changed here. */ +- TEST_NEW_FAIL ("(?(?foo)\\gfoo)\\gfoo)\\geks)(?Peccs)", 0, G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME); +-#if 0 +- TEST_NEW_FAIL (?, 0, G_REGEX_ERROR_MALFORMED_PROPERTY); +- TEST_NEW_FAIL (?, 0, G_REGEX_ERROR_UNKNOWN_PROPERTY); +-#endif + TEST_NEW_FAIL ("\\666", G_REGEX_RAW, G_REGEX_ERROR_INVALID_OCTAL_VALUE); + TEST_NEW_FAIL ("^(?(DEFINE) abc | xyz ) ", 0, G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE); + TEST_NEW_FAIL ("a", G_REGEX_NEWLINE_CRLF | G_REGEX_NEWLINE_ANYCRLF, G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS); + TEST_NEW_FAIL ("^(a)\\g{3", 0, G_REGEX_ERROR_MISSING_BACK_REFERENCE); +- TEST_NEW_FAIL ("^(a)\\g{0}", 0, G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE); +- TEST_NEW_FAIL ("abc(*FAIL:123)xyz", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN); ++ TEST_NEW_FAIL ("^(a)\\g{0}", 0, G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE); ++ TEST_NEW ("abc(*FAIL:123)xyz", 0, 0); + TEST_NEW_FAIL ("a(*FOOBAR)b", 0, G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB); +- TEST_NEW_FAIL ("(?i:A{1,}\\6666666666)", 0, G_REGEX_ERROR_NUMBER_TOO_BIG); ++ if (pcre2_ge (10, 37)) ++ { ++ TEST_NEW ("(?i:A{1,}\\6666666666)", 0, 0); ++ } + TEST_NEW_FAIL ("(?)(?&)", 0, G_REGEX_ERROR_MISSING_SUBPATTERN_NAME); +- TEST_NEW_FAIL ("(?+-a)", 0, G_REGEX_ERROR_MISSING_DIGIT); +- TEST_NEW_FAIL ("TA]", G_REGEX_JAVASCRIPT_COMPAT, G_REGEX_ERROR_INVALID_DATA_CHARACTER); ++ TEST_NEW_FAIL ("(?+-a)", 0, G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE); + TEST_NEW_FAIL ("(?|(?A)|(?B))", 0, G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME); + TEST_NEW_FAIL ("a(*MARK)b", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED); + TEST_NEW_FAIL ("^\\c€", 0, G_REGEX_ERROR_INVALID_CONTROL_CHAR); + 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); +- TEST_NEW_FAIL ("\\u0100", G_REGEX_RAW | G_REGEX_JAVASCRIPT_COMPAT, G_REGEX_ERROR_CHARACTER_VALUE_TOO_LARGE); + + /* These errors can't really be tested easily: + * G_REGEX_ERROR_EXPRESSION_TOO_LARGE +@@ -2474,7 +2464,15 @@ main (int argc, char *argv[]) + TEST_MATCH("a#\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\r\nb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); + TEST_MATCH("a#\rb", G_REGEX_EXTENDED, 0, "a", -1, 0, 0, FALSE); +- TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, FALSE); ++ /* Due to PCRE2 only supporting newline settings passed to pcre2_compile (and ++ * not to pcre2_match also), we have to compile the pattern with the ++ * effective (combined from compile and match options) newline setting. ++ * However, this setting also affects how newlines are interpreted *inside* ++ * the pattern. With G_REGEX_EXTENDED, this changes where the comment ++ * (started with `#`) ends. ++ */ ++ /* On PCRE1, this test expected no match; on PCRE2 it matches because of the above. */ ++ TEST_MATCH("a#\nb", G_REGEX_EXTENDED, G_REGEX_MATCH_NEWLINE_CR, "a", -1, 0, 0, TRUE /*FALSE*/); + TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE); + + TEST_MATCH("line\nbreak", G_REGEX_MULTILINE, 0, "this is a line\nbreak", -1, 0, 0, TRUE); +@@ -2487,21 +2485,19 @@ main (int argc, char *argv[]) + * with pcre's internal tables. Bug #678273 */ + TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "DŽ", -1, 0, 0, TRUE); + TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "dž", -1, 0, 0, TRUE); +-#if PCRE_MAJOR > 8 || (PCRE_MAJOR == 8 && PCRE_MINOR >= 32) +- /* This would incorrectly fail to match in pcre < 8.32, so only assert +- * this for known-good pcre. */ + TEST_MATCH("[DŽ]", G_REGEX_CASELESS, 0, "Dž", -1, 0, 0, TRUE); +-#endif + + /* TEST_MATCH_NEXT#(pattern, string, string_len, start_position, ...) */ + TEST_MATCH_NEXT0("a", "x", -1, 0); + TEST_MATCH_NEXT0("a", "ax", -1, 1); + TEST_MATCH_NEXT0("a", "xa", 1, 0); + TEST_MATCH_NEXT0("a", "axa", 1, 2); ++ TEST_MATCH_NEXT1("", "", -1, 0, "", 0, 0); + TEST_MATCH_NEXT1("a", "a", -1, 0, "a", 0, 1); + TEST_MATCH_NEXT1("a", "xax", -1, 0, "a", 1, 2); + TEST_MATCH_NEXT1(EURO, ENG EURO, -1, 0, EURO, 2, 5); + TEST_MATCH_NEXT1("a*", "", -1, 0, "", 0, 0); ++ TEST_MATCH_NEXT2("", "a", -1, 0, "", 0, 0, "", 1, 1); + TEST_MATCH_NEXT2("a*", "aa", -1, 0, "aa", 0, 2, "", 2, 2); + TEST_MATCH_NEXT2(EURO "*", EURO EURO, -1, 0, EURO EURO, 0, 6, "", 6, 6); + TEST_MATCH_NEXT2("a", "axa", -1, 0, "a", 0, 1, "a", 2, 3); +@@ -2675,11 +2671,6 @@ main (int argc, char *argv[]) + TEST_EXPAND("a", "a", "\\0130", FALSE, "X"); + TEST_EXPAND("a", "a", "\\\\\\0", FALSE, "\\a"); + TEST_EXPAND("a(?P.)c", "xabcy", "X\\gX", FALSE, "XbX"); +-#if !(PCRE_MAJOR > 8 || (PCRE_MAJOR == 8 && PCRE_MINOR >= 34)) +- /* PCRE >= 8.34 no longer allows this usage. */ +- TEST_EXPAND("(.)(?P<1>.)", "ab", "\\1", FALSE, "a"); +- TEST_EXPAND("(.)(?P<1>.)", "ab", "\\g<1>", FALSE, "a"); +-#endif + TEST_EXPAND(".", EURO, "\\0", FALSE, EURO); + TEST_EXPAND("(.)", EURO, "\\1", FALSE, EURO); + TEST_EXPAND("(?P.)", EURO, "\\g", FALSE, EURO); +@@ -2798,6 +2789,10 @@ main (int argc, char *argv[]) + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "A", 1); + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "B", 2); + TEST_GET_STRING_NUMBER("(?P.)(?Pa)", "C", -1); ++ TEST_GET_STRING_NUMBER("(?P.)(?Pa)(?Pb)", "A", 1); ++ TEST_GET_STRING_NUMBER("(?P.)(?Pa)(?Pb)", "B", 2); ++ TEST_GET_STRING_NUMBER("(?P.)(?Pa)(?Pb)", "C", 3); ++ TEST_GET_STRING_NUMBER("(?P.)(?Pa)(?Pb)", "D", -1); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "A", 1); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "B", 3); + TEST_GET_STRING_NUMBER("(?P.)(.)(?Pa)", "C", -1); +diff --git a/meson.build b/meson.build +index 882049c..657e9f6 100644 +--- a/meson.build ++++ b/meson.build +@@ -2024,37 +2024,38 @@ else + endif + endif + +-pcre = dependency('libpcre', version: '>= 8.31', required : false) # Should check for Unicode support, too. FIXME +-if not pcre.found() ++pcre2 = dependency('libpcre2-8', version: '>= 10.32', required : false) ++if not pcre2.found() + if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl' +- # MSVC: Search for the PCRE library by the configuration, which corresponds +- # to the output of CMake builds of PCRE. Note that debugoptimized ++ # MSVC: Search for the PCRE2 library by the configuration, which corresponds ++ # to the output of CMake builds of PCRE2. Note that debugoptimized + # is really a Release build with .PDB files. + if vs_crt == 'debug' +- pcre = cc.find_library('pcred', required : false) ++ pcre2 = cc.find_library('pcre2d-8', required : false) + else +- pcre = cc.find_library('pcre', required : false) ++ pcre2 = cc.find_library('pcre2-8', required : false) + endif + endif + endif + + # Try again with the fallback +-if not pcre.found() +- pcre = dependency('libpcre', required : true, fallback : ['pcre', 'pcre_dep']) +- use_pcre_static_flag = true ++if not pcre2.found() ++ pcre2 = dependency('libpcre2-8', required : true, fallback : ['pcre2', 'libpcre2_8']) ++ use_pcre2_static_flag = true + elif host_system == 'windows' +- pcre_static = cc.links('''#define PCRE_STATIC +- #include +- int main() { +- void *p = NULL; +- pcre_free(p); +- return 0; +- }''', +- dependencies: pcre, +- name : 'Windows system PCRE is a static build') +- use_pcre_static_flag = pcre_static ++ pcre2_static = cc.links('''#define PCRE2_STATIC ++ #define PCRE2_CODE_UNIT_WIDTH 8 ++ #include ++ int main() { ++ void *p = NULL; ++ pcre2_code_free(p); ++ return 0; ++ }''', ++ dependencies: pcre2, ++ name : 'Windows system PCRE2 is a static build') ++ use_pcre2_static_flag = pcre2_static + else +- use_pcre_static_flag = false ++ use_pcre2_static_flag = false + endif + + libm = cc.find_library('m', required : false) +diff --git a/po/sk.po b/po/sk.po +index 8d6a1ce..747ad27 100644 +--- a/po/sk.po ++++ b/po/sk.po +@@ -5630,7 +5630,7 @@ msgstr "zlý ofset" + msgid "short utf8" + msgstr "krátke utf8" + +-# Ide o omyl programátora: case PCRE_ERROR_RECURSELOOP: return _("recursion loop"); ++# Ide o omyl programátora: case PCRE2_ERROR_RECURSELOOP: return _("recursion loop"); + #: glib/gregex.c:303 + msgid "recursion loop" + msgstr "rekurzívna slučka" +diff --git a/subprojects/pcre.wrap b/subprojects/pcre.wrap +deleted file mode 100644 +index a6b07b9..0000000 +--- a/subprojects/pcre.wrap ++++ /dev/null +@@ -1,11 +0,0 @@ +-[wrap-file] +-directory = pcre-8.37 +-source_url = https://sourceforge.net/projects/pcre/files/pcre/8.37/pcre-8.37.tar.bz2 +-source_filename = pcre-8.37.tar.bz2 +-source_hash = 51679ea8006ce31379fb0860e46dd86665d864b5020fc9cd19e71260eef4789d +-patch_filename = pcre_8.37-4_patch.zip +-patch_url = https://wrapdb.mesonbuild.com/v2/pcre_8.37-4/get_patch +-patch_hash = c957f42da6f6378300eb8a18f4a5cccdb8e2aada51a703cac842982f9f785399 +- +-[provide] +-libpcre = pcre_dep +-- +2.33.0 + diff --git a/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch b/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch new file mode 100644 index 0000000000000000000000000000000000000000..b82fc7f37d783367304eac95c97980e0a1e09d29 --- /dev/null +++ b/backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch @@ -0,0 +1,119 @@ +From 511627b7356af527c85c049e2020a36694d7de54 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +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 + diff --git a/backport-xdgmime-fix-double-free.patch b/backport-xdgmime-fix-double-free.patch new file mode 100644 index 0000000000000000000000000000000000000000..8aa6991fb30c94662c71b5f7a99dc6dd7af74446 --- /dev/null +++ b/backport-xdgmime-fix-double-free.patch @@ -0,0 +1,36 @@ +From f95ca6cb713383548f16f9a8ba2f6c51a4d25e25 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +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 + diff --git a/glib-2.68.1.tar.xz b/glib-2.72.2.tar.xz similarity index 40% rename from glib-2.68.1.tar.xz rename to glib-2.72.2.tar.xz index d1389734f1a9acffe1d7275783f2535e24d869dc..f240f9910081e441786ef7a8427f940d1326684f 100644 Binary files a/glib-2.68.1.tar.xz and b/glib-2.72.2.tar.xz differ diff --git a/glib2.spec b/glib2.spec index dad7e28941ce58977d5074b68d3cbb81bc63401d..668436abf18091f7e0741107e78d0859f95d87c4 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,30 +1,57 @@ Name: glib2 -Version: 2.68.1 -Release: 12 +Version: 2.72.2 +Release: 5 Summary: The core library that forms the basis for projects such as GTK+ and GNOME License: LGPLv2+ URL: http://www.gtk.org -Source0: http://download.gnome.org/sources/glib/2.68/glib-%{version}.tar.xz - -Patch6000: backport-correctly-use-3-parameters-for-clise-range.patch -Patch6001: backport-fix-a-memory-leak.patch -Patch6002: backport-gfileenumerator-fix-leak-in-error-path.patch -Patch6003: backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch -Patch6004: backport-gdbusauth-fix-error-leak.patch -Patch6005: backport-gapplication-fix-arguments-leak-in-error-path.patch -Patch6006: backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch -Patch6007: backport-application-Unset-the-registered-state-after-shutting-down.patch -Patch6008: backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch -Patch6009: backport-gthread-posix-Free-a-memory-leak-on-error-path.patch -Patch6010: backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch -Patch6011: backport-glocalfileinfo-Fix-atime-mtime-mix.patch -Patch6012: backport-gopenuriportal-Fix-GVariantBuilder-and-string-leakage.patch -Patch6013: backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch -Patch6014: backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch -Patch6015: backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch -Patch6016: backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch -Patch6017: backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch -Patch6018: backport-add-OOM-handling-in-mimemagic.patch +Source0: https://download.gnome.org/sources/glib/2.71/glib-%{version}.tar.xz + +Patch6000: backport-add-version-macros-for-GLib-2.74.patch +Patch6001: backport-gtype-Add-G_TYPE_FLAG_NONE.patch +Patch6002: backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch +Patch6003: backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch +Patch6004: backport-gsignal-Add-G_CONNECT_DEFAULT.patch +Patch6005: backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch +Patch6006: backport-giochannel-Add-G_IO_FLAG_NONE.patch +Patch6007: backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch +Patch6008: backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch +Patch6009: backport-replace-pcre1-with-pcre2.patch +Patch6010: backport-gregex-format-specifier-for-localized-error-message.patch +Patch6011: backport-gregex-ensure-we-translate-the-errcode.patch +Patch6012: backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch +Patch6013: backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch +Patch6014: backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-not-available.patch +Patch6015: backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch +Patch6016: backport-gregex-add-original-test-case.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: glibc-devel libattr-devel libselinux-devel meson @@ -38,13 +65,17 @@ BuildRequires: pkgconfig(sysprof-capture-4) %endif %endif -Provides: %{name}-fam = %{version}-%{release} -Obsoletes: %{name}-fam < %{version}-%{release} +Provides: %{name}-fam = %{version}-%{release} +Obsoletes: %{name}-fam < %{version}-%{release} Recommends: shared-mime-info - Conflicts: gcr < 3.28.1 +Provides: bundled(gnulib) +Provides: bundled(gvdb) +Provides: bundled(libcharset) +Provides: bundled(xdgmime) + %description GLib is a bundle of three (formerly five) low-level system libraries written in C and developed mainly by GNOME. GLib's code was separated @@ -52,17 +83,31 @@ from GTK, so it can be used by software other than GNOME and has been developed in parallel ever since. %package devel -Summary: Development and test files for the GLib library +Summary: Development for the GLib library Requires: %{name} = %{version}-%{release} Requires: gdb-headless +%description devel +Development for the GLib library. + +%package static +Summary: glib static +Requires: %{name}-devel = %{version}-%{release} Provides: %{name}-static = %{version}-%{release} -Provides: %{name}-tests = %{version}-%{release} Obsoletes: %{name}-static < %{version}-%{release} + +%description static +The %{name}-static subpackage contains libraries for %{name}. + +%package tests +Summary: Tests for the glib2 package +Requires: %{name}-devel = %{version}-%{release} +Provides: %{name}-tests = %{version}-%{release} Obsoletes: %{name}-tests < %{version}-%{release} -%description devel -Development and test files for the GLib library. +%description tests +The glib2-tests package contains tests that can be used to verify +the functionality of the installed package. %ifnarch i686 %package help @@ -79,7 +124,8 @@ help document for the glib2 package. %autosetup -n glib-%{version} -p1 %build -rm glib/pcre/*.[ch] +rm -rf glib/pcre/*.[ch] + %meson --default-library=both -Ddtrace=true \ %ifnarch i686 %if %{?openEuler:1}0 @@ -93,20 +139,23 @@ rm glib/pcre/*.[ch] -Dglib_debug=disabled %meson_build +find . -name *.dtrace-temp.c -exec rm -f {} \; %check %meson_test %install %meson_install +%global py_reproducible_pyc_path %{buildroot}%{_datadir} touch -r gio/gdbus-2.0/codegen/config.py.in %{buildroot}%{_datadir}/glib-2.0/codegen/*.py chrpath --delete %{buildroot}%{_libdir}/*.so export PYTHONHASHSEED=0 %py_byte_compile %{__python3} %{buildroot}%{_datadir} -mv %{buildroot}%{_bindir}/gio-querymodules %{buildroot}%{_bindir}/gio-querymodules-%{__isa_bits} -mkdir -p %{buildroot}%{_libdir}/gio/modules/ +mv %{buildroot}%{_bindir}/gio-querymodules %{buildroot}%{_bindir}/gio-querymodules-%{__isa_bits} +sed -i -e "/^gio_querymodules=/s/gio-querymodules/gio-querymodules-%{__isa_bits}/" %{buildroot}%{_libdir}/pkgconfig/gio-2.0.pc +mkdir -p %{buildroot}%{_libdir}/gio/modules touch %{buildroot}%{_libdir}/gio/modules/giomodule.cache # remove pycache @@ -157,11 +206,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_libdir}/lib*.so %{_libdir}/glib-2.0 %{_libdir}/pkgconfig/* -%{_libdir}/*.a %{_includedir}/* -%{_libexecdir}/installed-tests -%exclude %{_libexecdir}/installed-tests/glib/cert-tests -%exclude %{_libexecdir}/installed-tests/glib/tls-certificate %{_datadir}/aclocal/* %{_datadir}/glib-2.0/* @@ -169,8 +214,6 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_datadir}/gdb/auto-load/%{_libdir}/*-gdb.py %{_datadir}/gettext/ %{_datadir}/systemtap/ -%{_datadir}/installed-tests -%exclude %{_datadir}/installed-tests/glib/tls-certificate.test %{_bindir}/glib-genmarshal %{_bindir}/glib-gettextize @@ -182,6 +225,17 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_bindir}/gresource %attr (0755, root, root) %{_bindir}/gtester-report +%files static +%{_libdir}/*.a + +%files tests +%{_libexecdir}/installed-tests +%exclude %{_libexecdir}/installed-tests/glib/cert-tests +%exclude %{_libexecdir}/installed-tests/glib/tls-certificate + +%{_datadir}/installed-tests +%exclude %{_datadir}/installed-tests/glib/tls-certificate.test + %ifnarch i686 %files help %defattr(-,root,root) @@ -190,6 +244,24 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %endif %changelog +* Wed Nov 9 2022 hanhuihui - 2.72.2-5 +- separate the test and static package from devel package + +* Sat Oct 15 2022 hanhuihui - 2.72.2-4 +- backport some patches from community + +* Mon Sep 5 2022 hanhuihui - 2.72.2-3 +- replace pcre1 with pcre2 + +* Sat Jun 18 2022 zhujunhao - 2.72.2-2 +- remove gnutls require + +* Mon Jun 6 2022 lin zhang - 2.72.2-1 +- Update to 2.72.2 + +* Thu Jun 2 2022 lin zhang - 2.72.0-1 +- Update to 2.72.0 + * Thu Apr 28 2022 yanan - 2.68.1-12 - Type:bugfix - DESC:fix issues found by svace static code analyzer diff --git a/glib2.yaml b/glib2.yaml index 67fb2b53cbdd866f6a218b94ea91b1d097e31da8..d3945cee5a88e0e0b0905cf3a76b37093c3aeced 100644 --- a/glib2.yaml +++ b/glib2.yaml @@ -1,4 +1,4 @@ version_control: github src_repo: GNOME/glib tag_prefix: "^" -seperator: "." +separator: "."