diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 52f17b1d9de732644e002745595c624aa28b4919..ba8039d4c339b93407fb9cff5fefbb37ffd4c632 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -256,7 +256,7 @@ to avoid unnecessary breakage, and to take advantage of the knowledge about GLib that has been built up over the years, we’d like to ask people contributing to GLib to follow a few rules: -0. Never push to the `master` branch, or any stable branches, directly; you +0. Never push to the `main` branch, or any stable branches, directly; you should always go through a merge request, to ensure that the code is tested on the CI infrastructure at the very least. A merge request is also the proper place to get a comprehensive code review from the core diff --git a/OAT.xml b/OAT.xml index a2068880e03dee4966c55bb8fba19896155d2699..58129191f7a8efd02be26dab23710c8fb3581827 100644 --- a/OAT.xml +++ b/OAT.xml @@ -138,7 +138,7 @@ Note:If the text contains special characters, please escape them according to th - + @@ -158,7 +158,7 @@ Note:If the text contains special characters, please escape them according to th - + diff --git a/README.OpenSource b/README.OpenSource index 9bebd2f243539add781949091b27fbbb1354db15..7aaec4d637d8cd882e6a81d884862757afa223e3 100644 --- a/README.OpenSource +++ b/README.OpenSource @@ -3,7 +3,7 @@ "Name": "openEuler:glib2", "License": "LGPL V2.1", "License File": "COPYING", - "Version Number": "2.68.1-10.oe2203", + "Version Number": "2.72.2-5.oe2203sp1", "Upstream URL": "https://www.gtk.org/", "Description": "GLib is the low-level core library that forms the basis for projects such as GTK and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system." } diff --git a/README.md b/README.md index 9ef3b3d6b057cebe195a78e2156e2d59422a9a72..7b436b5625e85709a84fab0c93f90d6e10a99825 100644 --- a/README.md +++ b/README.md @@ -15,13 +15,39 @@ The official web site is: See the file '[INSTALL.in](INSTALL.in)' -## How to report bugs +## Supported versions -Bugs should be reported to the GNOME issue tracking system. -(). You will need -to create an account for yourself. +Only the most recent unstable and stable release series are supported. All +older versions are not supported upstream and may contain bugs, some of +which may be exploitable security vulnerabilities. -In the bug report please include: +See [SECURITY.md](SECURITY.md) for more details. + +## Documentation + +API documentation is available online for GLib for the: + * [GLib](https://docs.gtk.org/glib/) + * [GObject](https://docs.gtk.org/gobject/) + * [GModule](https://docs.gtk.org/gmodule/) + * [GIO](https://docs.gtk.org/gio/) + +## Discussion + +If you have a question about how to use GLib, seek help on [GNOME’s Discourse +instance](https://discourse.gnome.org/tags/glib). Alternatively, ask a question +on [StackOverflow and tag it `glib`](https://stackoverflow.com/questions/tagged/glib). + +## Reporting bugs + +Bugs should be [reported to the GNOME issue tracking system](https://gitlab.gnome.org/GNOME/glib/issues/new). +You will need to create an account for yourself. You may also submit bugs by +e-mail (without an account) by e-mailing , +but this will give you a degraded experience. + +Bugs are for reporting problems in GLib itself, not for asking questions about +how to use it. To ask questions, use one of our [discussion forums](#discussion). + +In bug reports please include: * Information about your system. For instance: * What operating system and version @@ -29,7 +55,7 @@ In the bug report please include: * And anything else you think is relevant. * How to reproduce the bug. * If you can reproduce it with one of the test programs that are built - in the tests/ subdirectory, that will be most convenient. Otherwise, + in the `tests/` subdirectory, that will be most convenient. Otherwise, please include a short test program that exhibits the behavior. As a last resort, you can also provide a pointer to a larger piece of software that can be downloaded. @@ -38,12 +64,30 @@ In the bug report please include: * Further information such as stack traces may be useful, but is not necessary. -## Patches +## Contributing to GLib + +Please follow the [contribution guide](./CONTRIBUTING.md) to know how to +start contributing to GLib. -Patches should also be submitted as merge requests to gitlab.gnome.org. If the -patch fixes an existing issue, please refer to the issue in your commit message -with the following notation (for issue 123): +Patches should be [submitted as merge requests](https://gitlab.gnome.org/GNOME/glib/-/merge_requests/new) +to gitlab.gnome.org. If the patch fixes an existing issue, please refer to the +issue in your commit message with the following notation (for issue 123): +``` Closes: #123 +``` -Otherwise, create a new merge request that introduces the change, filing a +Otherwise, create a new merge request that introduces the change. Filing a separate issue is not required. + +## Default branch renamed to `main` + +The default development branch of GLib has been renamed to `main`. To update +your local checkout, use: +```sh +git checkout master +git branch -m master main +git fetch +git branch --unset-upstream +git branch -u origin/main +git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main +``` diff --git a/README.rationale b/README.rationale index 85a3dfd59bf3802b182de78e739eac482a152b66..e1d459376d29e7b18794e7e6dfd5f1390f91377a 100644 --- a/README.rationale +++ b/README.rationale @@ -8,3 +8,9 @@ giving a brief rationale of each decision, plus a link to further discussion. already supported by GLib and GNOME tools, and accomplish the same task as compiler attributes. GLib does not provide macros for attributes like nonnull because it would not use them. + + * Main loop API: + + The ID-based mainloop APIs (g_idle_add, g_timeout_add, etc) are considered + legacy, and new features (such as g_source_set_static_name) will only be + added to the explicit GSource APIs. diff --git a/README.win32.md b/README.win32.md index e67552270654aadad5450c3621391c0193d89a9e..17b36acbf6ea089827ba1ca53c6ba7f40e5dae47 100644 --- a/README.win32.md +++ b/README.win32.md @@ -163,71 +163,7 @@ normally. ### Support for pre-2012 Visual Studio -This release of GLib requires at least the Windows 8.0 SDK in order to be built -successfully using Visual Studio, which means that building with Visual Studio -2008 or 2010 is possible only with a special setup and must be done in the -command line with Ninja. Please see -https://devblogs.microsoft.com/cppblog/using-the-windows-software-development-kit-sdk-for-windows-8-consumer-preview-with-visual-studio-2010/ -for references; basically, assuming that your Windows 8.0 SDK is installed in -`C:\Program Files (x86)\Windows Kits\8.0` (`$(WIN8SDKDIR)` in short), you need -to ensure the following before invoking Meson to configure the build: - -- Your `%INCLUDE%` must not include the Windows 7.0/7.1 SDK include directories, - and `$(WIN8SDKDIR)\include\um`, `$(WIN8SDKDIR)\include\um\share` and - `$(WIN8SDKDIR)\include\winrt` (in this order) must be before your stock - Visual Studio 2008/2010 header directories. If you have the DirectX SDK installed, - you should remove its include directory from your `%INCLUDE%` as well. -- You must replace the Windows 7.0/7.1 SDK library directory in `%LIB%` with the - Windows 8.0 SDK library directory, i.e. `$(WIN8SDKDIR)\lib\win8\um\[x86|x64]`. - If you have the DirectX SDK installed, you should remove its library directory - from your `%INCLUDE%` as well. -- You must replace the Windows 7.0/7.1 SDK tools directory from your `%PATH%` with - the Windows 8.0 SDK tools directory, i.e. `$(WIN8SDKDIR)\bin\[x86|x64]`. - If you have the DirectX SDK installed, you should remove its utility directory - from your `%PATH%` as well. - -The Windows 8.0 SDK headers may contain an `roapi.h` that cannot be used under plain -C, so to remedy that, change the following lines (around lines 55-57): - -``` -// RegisterActivationFactory/RevokeActivationFactory registration cookie -typedef struct {} *RO_REGISTRATION_COOKIE; -// RegisterActivationFactory/DllGetActivationFactory callback -``` - -to - -``` -// RegisterActivationFactory/RevokeActivationFactory registration cookie -#ifdef __cplusplus -typedef struct {} *RO_REGISTRATION_COOKIE; -#else -typedef struct _RO_REGISTRATION_COOKIE *RO_REGISTRATION_COOKIE; /* make this header includable in C files */ -#endif -// RegisterActivationFactory/DllGetActivationFactory callback -``` - -This follows what is done in the Windows 8.1 SDK, which contains an `roapi.h` -that is usable under plain C. Please note that you might need to copy that file -into a location that is in your `%INCLUDE%` which precedes the include path for the -Windows 8.0 SDK headers, if you do not have administrative privileges. - -### Visual Studio 2008 hacks - -- You need to run the following lines from your build directory, to embed the - manifests that are generated during the build, assuming the built binaries - are installed to `$(PREFIX)`, after a successful build/installation: - -```cmd -> for /r %f in (*.dll.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;2 -> for /r %f in (*.exe.manifest) do if exist $(PREFIX)\bin\%~nf mt /manifest %f (PREFIX)\bin\%~nf;1 -``` - - -- If building for amd64/x86_64/x64, sometimes the compilation of sources may seem to hang, which - is caused by an optimization issue in the 2008 x64 compiler. You need to use Task Manager to - remove all running instances of `cl.exe`, which will cause the build process to terminate. Update - the build flags of the sources that hang on compilation by changing its `"/O2"` flag to `"/O1"` - in `build.ninja`, and retry the build, where things should continue to build normally. At the - time of writing, this is needed for compiling `glib/gtestutils.c`, `gio/gsettings.c`, - `gio/gsettingsschema.c`, `glib/tests/fileutils.c` and `gio/tests/gsubprocess-testprog.c` +This release of GLib requires at least the Windows 8 SDK in order to be built +successfully using Visual Studio, which means that it is no longer supported to +build GLib with Visual Studio 2008 nor 2010. People that still need to use +Visual Studio 2008 or 2010 should continue to use glib-2.66.x. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000000000000000000000000000000000..e49460a1f046ca03430d8b5622e3af5847b0b51f --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,78 @@ +# Security policy for GLib + + * [Supported Versions](#Supported-Versions) + * [Reporting a Vulnerability](#Reporting-a-Vulnerability) + * [Security Announcements](#Security-Announcements) + * [Acknowledgements](#Acknowledgements) + +## Supported Versions + +Upstream GLib only supports the most recent stable release series, and the +current development release series. Any older stable release series are no +longer supported, although they may still receive backported security updates +in long-term support distributions. Such support is up to the distributions, +though. + +Under GLib’s versioning scheme, stable release series have an *even* minor +component (for example, 2.66.0, 2.66.1, 2.68.3), and development release series +have an *odd* minor component (2.67.1, 2.69.0). + +## Signed Releases + +The git tags for all releases ≥2.58.0 are signed by a maintainer using +[git-evtag](https://github.com/cgwalters/git-evtag). The maintainer will use +their personal GPG key; there is currently not necessarily a formal chain of +trust for these keys. Please [create an issue](https://gitlab.gnome.org/GNOME/glib/-/issues/new) +if you would like to work on improving this. + +Unsigned releases ≥2.58.0 should not be trusted. Releases prior to 2.58.0 were +not signed. + +## Reporting a Vulnerability + +If you think you've identified a security issue in GLib, GObject or GIO, please +**do not** report the issue publicly via a mailing list, IRC, a public issue on +the GitLab issue tracker, a merge request, or any other public venue. + +Instead, report a +[*confidential* issue in the GitLab issue tracker](https://gitlab.gnome.org/GNOME/glib/-/issues/new?issue[confidential]=1), +with the “This issue is confidential” box checked. Please include as many +details as possible, including a minimal reproducible example of the issue, and +an idea of how exploitable/severe you think it is. + +**Do not** provide a merge request to fix the issue, as there is currently no +way to make confidential merge requests on gitlab.gnome.org. If you have patches +which fix the security issue, please attach them to your confidential issue as +patch files. + +Confidential issues are only visible to the reporter and the GLib maintainers. + +As per the [GNOME security policy](https://security.gnome.org/), the next steps +are then: + * The report is triaged. + * Code is audited to find any potential similar problems. + * If it is determined, in consultation with the submitter, that a CVE is + required, the submitter obtains one via [cveform.mitre.org](https://cveform.mitre.org/). + * The fix is prepared for the development branch, and for the most recent + stable branch. + * The fix is submitted to the public repository. + * On the day the issue and fix are made public, an announcement is made on the + [public channels listed below](#Security-Announcements). + * A new release containing the fix is issued. + +## Security Announcements + +Security announcements are made publicly via the +[`distributor` tag on discourse.gnome.org](https://discourse.gnome.org/tag/distributor) +and cross-posted to the +[distributor-list](https://mail.gnome.org/mailman/listinfo/distributor-list). + +Announcements for security issues with wide applicability or high impact may +additionally be made via +[oss-security@lists.openwall.com](https://www.openwall.com/lists/oss-security/). + +## Acknowledgements + +This text was partially based on the +[github.com/containers security policy](https://github.com/containers/common/blob/HEAD/SECURITY.md), +and partially based on the [flatpak security policy](https://github.com/flatpak/flatpak/blob/HEAD/SECURITY.md). diff --git a/backport-patch.log b/backport-patch.log index a4c3ca12f42442bec8ae0c94d9125316c7b4e2a0..7a47401970bcea7a0f25fafa7daa6888654d9a6c 100644 --- a/backport-patch.log +++ b/backport-patch.log @@ -1,62 +1,71 @@ -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 -Patch6019: backport-garray-buffer-overflow-fix.patch -Patch6020: backport-gdbusconnection-Move-ExportedSubtree-definition.patch -Patch6021: backport-gdbusconnection-Add-some-ownership-annotations.patch -Patch6022: backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch -Patch6023: backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch -Patch6024: backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch -Patch6025: backport-Add-D-Bus-object-subtree-unregistration-tests.patch -Patch6026: backport-gutf8-add-string-length-check.patch -Patch6027: backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch -Patch6028: backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch -Patch6029: backport-gvariant-serialiser-Prevent-unbounded-recursion.patch -Patch6030: backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch -Patch6031: backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch -Patch6032: backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch -Patch6033: backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch -Patch6034: backport-tests-Add-some-tests-for-g_string_append_vprintf.patch -Patch6035: backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch -Patch6036: backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch -Patch6037: backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch -Patch6038: backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch -Patch6039: backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch -Patch6040: backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch -Patch6041: backport-gio-tool-Fix-a-minor-memory-leak.patch -Patch6042: backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch -Patch6043: backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch -Patch6044: backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch -Patch6045: backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch -Patch6046: backport-xdgmime-fix-double-free.patch -Patch6047: backport-Implement-GFileIface.set_display_name-for-resource-files.patch -Patch6048: backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch -Patch6049: backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch -Patch6050: backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch -Patch6051: backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch -Patch6052: backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch -Patch6053: backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch -Patch6054: backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch -Patch6055: backport-tests-Make-the-642026-test-take-100x-less-time.patch -Patch6056: backport-gmessages-Add-missing-trailing-newline-in-fallback-log-hander.patch -Patch6057: backport-Revert-Handling-collision-between-standard-i-o-filedescriptors-and-newly-created-ones.patch -patch6058: backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch -patch6059: backport-CVE-2023-24593_CVE-2023-25180-1.patch -patch6060: backport-CVE-2023-24593_CVE-2023-25180-2.patch -patch9000: backport-lib-openharmony-glib.patch +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 +Patch6046: backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch +Patch6047: backport-regex-Use-critical-messages-if-an-unexpected-NULL-parameter-is-provided.patch +Patch6048: backport-gregex-Allow-G_REGEX_JAVASCRIPT_COMPAT-in-compile-mask-for-g_regex_new.patch +Patch6049: backport-gregex-Drop-explanation-G_REGEX_JAVASCRIPT_COMPAT.patch +Patch6050: backport-gregex-Remove-an-unreachable-return-statement.patch +Patch6051: backport-gmessages-Add-missing-trailing-newline-in-fallback-log-hander.patch +Patch6052: backport-Revert-Handling-collision-between-standard-i-o-filedescriptors-and-newly-created-ones.patch +patch6053: backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch +patch6054: backport-CVE-2023-24593_CVE-2023-25180-1.patch +patch6055: backport-CVE-2023-24593_CVE-2023-25180-2.patch +patch6056: backport-gdbusconnection-Fix-double-unref-on-timeout-cancel-sending-a-message.patch +patch6057: backport-add-g_free_sized-and-g_aligned_free_sized.patch +patch6058: backport-gkeyfile-Fix-group-comment-management.patch +patch6059: backport-gkeyfile-Ensure-we-don-t-add-extra-blank-line-above-new-group.patch +patch6060: backport-gkeyfile-Skip-group-comment-when-adding-a-new-key-to-a-group.patch +patch6061: backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-event-thread.patch +patch6062: backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch +patch6063: backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch +Patch6064: backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch +Patch6065: backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch +Patch6066: backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch +Patch6067: backport-gmessages-fix-dropping-irrelevant-log-domains.patch +Patch6068: backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch +Patch6069: backport-openharmony-adapt.patch +Patch6070: backport-openharmony-dummy.patch \ No newline at end of file diff --git a/bundle.json b/bundle.json index ee1aca051b73e86676b4eadb266e3d26389d9fdb..0c480c550b80d5ea49b3c384e6b158beb2e4ce7a 100644 --- a/bundle.json +++ b/bundle.json @@ -1,7 +1,7 @@ { "name": "@ohos/glib", "description": "GLib is the low-level core library that forms the basis for projects such as GTK and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system.", - "version": "2.68.1", + "version": "2.72.2", "license": "LGPL V2.1", "publishAs": "code-segment", "segment": { 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 53a344c7a51859e09742426dd18dcf013db81d5a..08995dfdbdda48eea71decd493c84031252c68f5 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,78 +1,88 @@ Name: glib2 -Version: 2.68.1 -Release: 10 +Version: 2.72.2 +Release: 13 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 -Patch6019: backport-garray-buffer-overflow-fix.patch -Patch6020: backport-gdbusconnection-Move-ExportedSubtree-definition.patch -Patch6021: backport-gdbusconnection-Add-some-ownership-annotations.patch -Patch6022: backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch -Patch6023: backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch -Patch6024: backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch -Patch6025: backport-Add-D-Bus-object-subtree-unregistration-tests.patch -Patch6026: backport-gutf8-add-string-length-check.patch -Patch6027: backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch -Patch6028: backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch -Patch6029: backport-gvariant-serialiser-Prevent-unbounded-recursion.patch -Patch6030: backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch -Patch6031: backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch -Patch6032: backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch -Patch6033: backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch -Patch6034: backport-tests-Add-some-tests-for-g_string_append_vprintf.patch -Patch6035: backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch -Patch6036: backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch -Patch6037: backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch -Patch6038: backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch -Patch6039: backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch -Patch6040: backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch -Patch6041: backport-gio-tool-Fix-a-minor-memory-leak.patch -Patch6042: backport-gsocketclient-Fix-still-reachable-references-to-cancellables.patch -Patch6043: backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch -Patch6044: backport-Add-lock-in-_g_get_unix_mount_points-around-fsent-functions.patch -Patch6045: backport-g_get_unix_mount_points-reduce-syscalls-inside-loop.patch -Patch6046: backport-xdgmime-fix-double-free.patch -Patch6047: backport-Implement-GFileIface.set_display_name-for-resource-files.patch -Patch6048: backport-tests-dbus-appinfo-Add-test-case-for-flatpak-opening-an-invalid-file.patch -Patch6049: backport-documentportal-Fix-small-leak-in-add_documents-with-empty-URI-list.patch -Patch6050: backport-gio-tests-gdbus-proxy-threads-Unref-GVariant-s-that-we-own.patch -Patch6051: backport-gio-tests-gdbus-peer-Unref-cached-property-GVariant-value.patch -Patch6052: backport-gdesktopappinfo-Unref-the-GDBus-call-results.patch -Patch6053: backport-Handling-collision-between-standard-i-o-file-descriptors-and-newly-created-ones.patch -Patch6054: backport-glocalfileoutputstream-Do-not-double-close-an-fd-on-unlink-error.patch -Patch6055: backport-tests-Make-the-642026-test-take-100x-less-time.patch -Patch6056: backport-gmessages-Add-missing-trailing-newline-in-fallback-log-hander.patch -Patch6057: backport-Revert-Handling-collision-between-standard-i-o-filedescriptors-and-newly-created-ones.patch -patch6058: backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch -patch6059: backport-CVE-2023-24593_CVE-2023-25180-1.patch -patch6060: backport-CVE-2023-24593_CVE-2023-25180-2.patch -patch9000: backport-lib-openharmony-glib.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 +Patch6046: backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch +Patch6047: backport-regex-Use-critical-messages-if-an-unexpected-NULL-parameter-is-provided.patch +Patch6048: backport-gregex-Allow-G_REGEX_JAVASCRIPT_COMPAT-in-compile-mask-for-g_regex_new.patch +Patch6049: backport-gregex-Drop-explanation-G_REGEX_JAVASCRIPT_COMPAT.patch +Patch6050: backport-gregex-Remove-an-unreachable-return-statement.patch +Patch6051: backport-gmessages-Add-missing-trailing-newline-in-fallback-log-hander.patch +Patch6052: backport-Revert-Handling-collision-between-standard-i-o-filedescriptors-and-newly-created-ones.patch +patch6053: backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch +patch6054: backport-CVE-2023-24593_CVE-2023-25180-1.patch +patch6055: backport-CVE-2023-24593_CVE-2023-25180-2.patch +patch6056: backport-gdbusconnection-Fix-double-unref-on-timeout-cancel-sending-a-message.patch +patch6057: backport-add-g_free_sized-and-g_aligned_free_sized.patch +patch6058: backport-gkeyfile-Fix-group-comment-management.patch +patch6059: backport-gkeyfile-Ensure-we-don-t-add-extra-blank-line-above-new-group.patch +patch6060: backport-gkeyfile-Skip-group-comment-when-adding-a-new-key-to-a-group.patch +patch6061: backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-event-thread.patch +patch6062: backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch +patch6063: backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch + +Patch6064: backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch +Patch6065: backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch +Patch6066: backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch +Patch6067: backport-gmessages-fix-dropping-irrelevant-log-domains.patch +Patch6068: backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch +Patch6069: backport-openharmony-adapt.patch +Patch6070: backport-openharmony-dummy.patch BuildRequires: chrpath gcc gcc-c++ gettext perl-interpreter BUildRequires: glibc-devel libattr-devel libselinux-devel meson BuildRequires: systemtap-sdt-devel pkgconfig(libelf) pkgconfig(libffi) -BuildRequires: pkgconfig(libpcre) pkgconfig(mount) pkgconfig(zlib) +BuildRequires: pkgconfig(libpcre2-8) pkgconfig(mount) pkgconfig(zlib) BuildRequires: python3-devel %ifnarch i686 BuildRequires: desktop-file-utils shared-mime-info gtk-doc @@ -81,13 +91,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 @@ -95,17 +109,35 @@ 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: pcre2-static +%if %{?openEuler:1}0 +Requires: sysprof-capture-static +%endif +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 @@ -122,7 +154,7 @@ help document for the glib2 package. %autosetup -n glib-%{version} -p1 %build -rm glib/pcre/*.[ch] + %meson --default-library=both -Ddtrace=true \ %ifnarch i686 %if %{?openEuler:1}0 @@ -136,7 +168,6 @@ rm glib/pcre/*.[ch] -Dglib_debug=disabled %meson_build - find . -name *.dtrace-temp.c -exec rm -f {} \; %check @@ -144,14 +175,16 @@ find . -name *.dtrace-temp.c -exec rm -f {} \; %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 @@ -202,11 +235,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/* @@ -214,8 +243,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 @@ -227,6 +254,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) @@ -235,6 +273,56 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %endif %changelog +* Thu Jan 11 2024 hanhuihui - 2.72.2-13 +- fix pcre2 error , memory leak and log domains error + +* Mon Sep 25 2023 liningjie - 2.72.2-12 +- glocalfilemonitor: Avoid file monitor destruction from event thread + +* Sat Aug 19 2023 hanhuihui - 2.72.2-11 +- fix double unref and fix group comment management + +* Sat Apr 1 2023 hanhuihui - 2.72.2-10 +- fix CVE-2023-24593 and CVE-2023-25180 + +* Tue Mar 14 2023 hanhuihui - 2.72.2-9 +- fix a use-after-free of GDBusMethodInvocation + +* Thu Feb 16 2023 hanhuihui - 2.72.2-8 +- backport some patches from community + +* Tue Jan 10 2023 hanhuihui - 2.72.2-7 +- adjust pcre2 requires + +* Tue Dec 27 2022 hanhuihui - 2.72.2-6 +- fix some pcre2 error + +* 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 + fix segfault,memory leak,EOF,arguments leak + +* Wed Apr 6 2022 hanhui - 2.68.1-11 +- DESC:fix gfileenumerator/gdbusobjectmanagerservice/gdbusauth of memory leak + * Fri Mar 11 2022 weijin deng - 2.68.1-10 - Type:bugfix - DESC:solve glib2 enable "glib2_debug" option causes gnome-calendar reopen diff --git a/install.sh b/install.sh index 3c1da2e00d5488f9dcc897a7cb4e901b5753722e..444bbe6e0b0e87a7c60a831d7308d2f8b2066f85 100755 --- a/install.sh +++ b/install.sh @@ -3,7 +3,7 @@ set -e cd $1 -find . ! -path "*/\.*" ! -path "./patch*" ! \( -name glib-2.68.1.tar.xz\ +find . ! -path "*/\.*" ! -path "./patch*" ! \( -name glib-2.72.2.tar.xz\ -o -name BUILD.gn\ -o -name config.gni\ -o -name install.sh\ @@ -14,12 +14,14 @@ find . ! -path "*/\.*" ! -path "./patch*" ! \( -name glib-2.68.1.tar.xz\ -o -name COPYING\ -o -name backport-patch.log\ -o -name "README*"\ + -o -name "NEWS*"\ + -o -name SECURITY.md\ -o -name CONTRIBUTING.md\ -o -name ".*" \)\ -prune -print -exec rm -rf {} \; -tar -xvf glib-2.68.1.tar.xz -mv glib-2.68.1/* . -rm -rf glib-2.68.1 +tar -xvf glib-2.72.2.tar.xz +mv glib-2.72.2/* . +rm -rf glib-2.72.2 echo "reset working dir success" file="backport-patch.log" exec < $file diff --git a/patch.tar.gz b/patch.tar.gz index 8392bcc1d8a05ec6954031da485cb35a79aa8e85..d8745add26310c94145862ace14164a436f55260 100644 Binary files a/patch.tar.gz and b/patch.tar.gz differ diff --git a/patch/backport-Add-D-Bus-object-subtree-unregistration-tests.patch b/patch/backport-Add-D-Bus-object-subtree-unregistration-tests.patch deleted file mode 100644 index 75d959191e9785f8c1a6a635453aee21ae2ad6d5..0000000000000000000000000000000000000000 --- a/patch/backport-Add-D-Bus-object-subtree-unregistration-tests.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 34ce204fd758e2ce0ab6bf152051534f46cdb336 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 10:57:20 +0100 -Subject: [PATCH] tests: Add D-Bus object/subtree unregistration tests - -These tests cover the fixes from the previous two commits. - -Signed-off-by: Philip Withnall - -Helps: #2400 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/34ce204fd758e2ce0ab6bf152051534f46cdb336 - ---- - gio/tests/gdbus-export.c | 180 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 180 insertions(+) - -diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c -index aec21d7d0b..4cdc244924 100644 ---- a/gio/tests/gdbus-export.c -+++ b/gio/tests/gdbus-export.c -@@ -1792,6 +1792,184 @@ test_async_properties (void) - g_object_unref (c); - } - -+typedef struct -+{ -+ GDBusConnection *connection; /* (owned) */ -+ guint registration_id; -+ guint subtree_registration_id; -+} ThreadedUnregistrationData; -+ -+static gpointer -+unregister_thread_cb (gpointer user_data) -+{ -+ ThreadedUnregistrationData *data = user_data; -+ -+ /* Sleeping here makes the race more likely to be hit, as it balances the -+ * time taken to set up the thread and unregister, with the time taken to -+ * make and handle the D-Bus call. This will likely change with future kernel -+ * versions, but there isn’t a more deterministic synchronisation point that -+ * I can think of to use instead. */ -+ usleep (330); -+ -+ if (data->registration_id > 0) -+ g_assert_true (g_dbus_connection_unregister_object (data->connection, data->registration_id)); -+ -+ if (data->subtree_registration_id > 0) -+ g_assert_true (g_dbus_connection_unregister_subtree (data->connection, data->subtree_registration_id)); -+ -+ return NULL; -+} -+ -+static void -+async_result_cb (GObject *source_object, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ GAsyncResult **result_out = user_data; -+ -+ *result_out = g_object_ref (result); -+ g_main_context_wakeup (NULL); -+} -+ -+/* Returns %TRUE if this iteration resolved the race with the unregistration -+ * first, %FALSE if the call handler was invoked first. */ -+static gboolean -+test_threaded_unregistration_iteration (gboolean subtree) -+{ -+ ThreadedUnregistrationData data = { NULL, 0, 0 }; -+ ObjectRegistrationData object_registration_data = { 0, 0, 2 }; -+ GError *local_error = NULL; -+ GThread *unregister_thread = NULL; -+ const gchar *object_path; -+ GVariant *value = NULL; -+ const gchar *value_str; -+ GAsyncResult *call_result = NULL; -+ gboolean unregistration_was_first; -+ -+ data.connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); -+ g_assert_no_error (local_error); -+ g_assert_nonnull (data.connection); -+ -+ /* Register an object or a subtree */ -+ if (!subtree) -+ { -+ data.registration_id = g_dbus_connection_register_object (data.connection, -+ "/foo/boss", -+ (GDBusInterfaceInfo *) &foo_interface_info, -+ &foo_vtable, -+ &object_registration_data, -+ on_object_unregistered, -+ &local_error); -+ g_assert_no_error (local_error); -+ g_assert_cmpint (data.registration_id, >, 0); -+ -+ object_path = "/foo/boss"; -+ } -+ else -+ { -+ data.subtree_registration_id = g_dbus_connection_register_subtree (data.connection, -+ "/foo/boss/executives", -+ &subtree_vtable, -+ G_DBUS_SUBTREE_FLAGS_NONE, -+ &object_registration_data, -+ on_subtree_unregistered, -+ &local_error); -+ g_assert_no_error (local_error); -+ g_assert_cmpint (data.subtree_registration_id, >, 0); -+ -+ object_path = "/foo/boss/executives/vp0"; -+ } -+ -+ /* Allow the registrations to go through. */ -+ g_main_context_iteration (NULL, FALSE); -+ -+ /* Spawn a thread to unregister the object/subtree. This will race with -+ * the call we subsequently make. */ -+ unregister_thread = g_thread_new ("unregister-object", -+ unregister_thread_cb, &data); -+ -+ /* Call a method on the object (or an object in the subtree). The callback -+ * will be invoked in this main context. */ -+ g_dbus_connection_call (data.connection, -+ g_dbus_connection_get_unique_name (data.connection), -+ object_path, -+ "org.example.Foo", -+ "Method1", -+ g_variant_new ("(s)", "winwinwin"), -+ NULL, -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ async_result_cb, -+ &call_result); -+ -+ while (call_result == NULL) -+ g_main_context_iteration (NULL, TRUE); -+ -+ value = g_dbus_connection_call_finish (data.connection, call_result, &local_error); -+ -+ /* The result of the method could either be an error (that the object doesn’t -+ * exist) or a valid result, depending on how the thread was scheduled -+ * relative to the call. */ -+ unregistration_was_first = (value == NULL); -+ if (value != NULL) -+ { -+ g_assert_no_error (local_error); -+ g_assert_true (g_variant_is_of_type (value, G_VARIANT_TYPE ("(s)"))); -+ g_variant_get (value, "(&s)", &value_str); -+ g_assert_cmpstr (value_str, ==, "You passed the string 'winwinwin'. Jolly good!"); -+ } -+ else -+ { -+ g_assert_null (value); -+ g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); -+ } -+ -+ g_clear_pointer (&value, g_variant_unref); -+ g_clear_error (&local_error); -+ -+ /* Tidy up. */ -+ g_thread_join (g_steal_pointer (&unregister_thread)); -+ -+ g_clear_object (&call_result); -+ g_clear_object (&data.connection); -+ -+ return unregistration_was_first; -+} -+ -+static void -+test_threaded_unregistration (gconstpointer test_data) -+{ -+ gboolean subtree = GPOINTER_TO_INT (test_data); -+ guint i; -+ guint n_iterations_unregistration_first = 0; -+ guint n_iterations_call_first = 0; -+ -+ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2400"); -+ g_test_summary ("Test that object/subtree unregistration from one thread " -+ "doesn’t cause problems when racing with method callbacks " -+ "in another thread for that object or subtree"); -+ -+ /* Run iterations of the test until it’s likely we’ve hit the race. Limit the -+ * number of iterations so the test doesn’t run forever if not. The choice of -+ * 100 is arbitrary. */ -+ for (i = 0; i < 1000 && (n_iterations_unregistration_first < 100 || n_iterations_call_first < 100); i++) -+ { -+ if (test_threaded_unregistration_iteration (subtree)) -+ n_iterations_unregistration_first++; -+ else -+ n_iterations_call_first++; -+ } -+ -+ /* If the condition below is met, we probably failed to reproduce the race. -+ * Don’t fail the test, though, as we can’t always control whether we hit the -+ * race, and spurious test failures are annoying. */ -+ if (n_iterations_unregistration_first < 100 || -+ n_iterations_call_first < 100) -+ g_strdup_printf ("Failed to reproduce race (%u iterations with unregistration first, %u with call first); skipping test", -+ n_iterations_unregistration_first, n_iterations_call_first); -+} -+ - /* ---------------------------------------------------------------------------------------------------- */ - - int -@@ -1809,6 +1987,8 @@ main (int argc, - g_test_add_func ("/gdbus/object-registration-with-closures", test_object_registration_with_closures); - g_test_add_func ("/gdbus/registered-interfaces", test_registered_interfaces); - g_test_add_func ("/gdbus/async-properties", test_async_properties); -+ g_test_add_data_func ("/gdbus/threaded-unregistration/object", GINT_TO_POINTER (FALSE), test_threaded_unregistration); -+ g_test_add_data_func ("/gdbus/threaded-unregistration/subtree", GINT_TO_POINTER (TRUE), test_threaded_unregistration); - - /* TODO: check that we spit out correct introspection data */ - /* TODO: check that registering a whole subtree works */ --- -GitLab - diff --git a/patch/backport-CVE-2023-24593_CVE-2023-25180-1.patch b/patch/backport-CVE-2023-24593_CVE-2023-25180-1.patch index 8143ad9bb7f134e942dce6729cdaef300469a725..15db1b301e9e60d2f190c0851d46659213daee73 100644 --- a/patch/backport-CVE-2023-24593_CVE-2023-25180-1.patch +++ b/patch/backport-CVE-2023-24593_CVE-2023-25180-1.patch @@ -737,7 +737,7 @@ index 6ced7e3d6c..a1bccb834b 100644 + gsize ordered_offsets_up_to; } GVariantSerialised; - /* deserialisation */ + /* deserialization */ diff --git a/glib/tests/gvariant.c b/glib/tests/gvariant.c index 18fa855aeb..45e302c926 100644 --- a/glib/tests/gvariant.c @@ -1552,7 +1552,7 @@ index 263b74048c..69baeeb395 100644 +++ b/glib/gvariant-serialiser.c @@ -122,6 +122,8 @@ * - * @depth has no restrictions; the depth of a top-level serialised #GVariant is + * @depth has no restrictions; the depth of a top-level serialized #GVariant is * zero, and it increases for each level of nested child. + * + * @checked_offsets_up_to is always ≥ @ordered_offsets_up_to @@ -1735,7 +1735,7 @@ index 661bd8fd1b..eb74fe7804 100644 + gsize checked_offsets_up_to; } GVariantSerialised; - /* deserialisation */ + /* deserialization */ diff --git a/glib/gvariant.c b/glib/gvariant.c index 4f0d6b83c6..fd066f1732 100644 --- a/glib/gvariant.c @@ -1969,7 +1969,7 @@ index fd066f1732..a98f10b57a 100644 + * normal form. * * It makes sense to call this function if you've received #GVariant - * data from untrusted sources and you want to ensure your serialised + * data from untrusted sources and you want to ensure your serialized -- GitLab @@ -2066,7 +2066,7 @@ index f660e2d578..3fa97f91eb 100644 + * + * Returns: (transfer full): the child at the specified index + * -+ * Since: 2.68 ++ * Since: 2.74 + */ +GVariant * +g_variant_maybe_get_child_value (GVariant *value, @@ -2721,7 +2721,7 @@ index f7b2e97036..5fef88d58d 100644 +++ b/glib/gvariant.c @@ -5852,7 +5852,8 @@ g_variant_iter_loop (GVariantIter *iter, - /* Serialised data {{{1 */ + /* Serialized data {{{1 */ static GVariant * -g_variant_deep_copy (GVariant *value) +g_variant_deep_copy (GVariant *value, diff --git a/patch/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch b/patch/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch deleted file mode 100644 index 39caff89bebb6b3c5cf6f59fe474bca25ff6deb9..0000000000000000000000000000000000000000 --- a/patch/backport-Fix-memory-leak-in-gdbusauthmechanismsha1.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 6ec432386ef98e26e5079b060ad823277e10f41f Mon Sep 17 00:00:00 2001 -From: Loic Le Page -Date: Wed, 26 Jan 2022 14:20:08 +0100 -Subject: [PATCH] Fix memory leak in gio/gdbusauthmechanismsha1.c - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6ec432386ef98e26e5079b060ad823277e10f41f - ---- - gio/gdbusauthmechanismsha1.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gio/gdbusauthmechanismsha1.c b/gio/gdbusauthmechanismsha1.c -index a82dddf839..8137b6352d 100644 ---- a/gio/gdbusauthmechanismsha1.c -+++ b/gio/gdbusauthmechanismsha1.c -@@ -909,6 +909,7 @@ keyring_generate_entry (const gchar *cookie_context, - _("(Additionally, releasing the lock for “%s” also failed: %s) "), - path, - local_error->message); -+ g_error_free (local_error); - } - } - else --- -GitLab diff --git a/patch/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch b/patch/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch new file mode 100644 index 0000000000000000000000000000000000000000..a551880aa188f16c5fa879a2efbec2eaeb807a29 --- /dev/null +++ b/patch/backport-Make-sure-the-GTask-is-freed-on-a-graceful-disconnect.patch @@ -0,0 +1,39 @@ +From cabc49407371800733ada202fab721c9091b6fe6 Mon Sep 17 00:00:00 2001 +From: Pavel Sobolev +Date: Thu, 14 Sep 2023 15:42:24 +0300 +Subject: [PATCH] Make sure the `GTask` is freed on a graceful disconnect + +This fixes the memory leak in the case the connection has been +successfully closed by the peer. + + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/cabc49407371800733ada202fab721c9091b6fe6 + +--- + gio/gtcpconnection.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/gio/gtcpconnection.c b/gio/gtcpconnection.c +index 422b3dea52..e0865d859b 100644 +--- a/gio/gtcpconnection.c ++++ b/gio/gtcpconnection.c +@@ -206,6 +206,8 @@ async_close_finish (GTask *task, + g_task_return_error (task, error); + else + g_task_return_boolean (task, TRUE); ++ ++ g_object_unref (task); + } + + +@@ -231,7 +233,6 @@ close_read_ready (GSocket *socket, + else + { + async_close_finish (task, error); +- g_object_unref (task); + return FALSE; + } + } +-- +GitLab \ No newline at end of file diff --git a/patch/backport-add-OOM-handling-in-mimemagic.patch b/patch/backport-add-OOM-handling-in-mimemagic.patch deleted file mode 100644 index 3b69c4eaf39d14f385313d5cd383b8932db004da..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-add-g_free_sized-and-g_aligned_free_sized.patch b/patch/backport-add-g_free_sized-and-g_aligned_free_sized.patch new file mode 100644 index 0000000000000000000000000000000000000000..67de9e0e72a6f8b0529d7d905b1764d5746a8fb5 --- /dev/null +++ b/patch/backport-add-g_free_sized-and-g_aligned_free_sized.patch @@ -0,0 +1,227 @@ +From 329843f682d1216d4f41aab7b5711f21ef280b71 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 25 Jan 2023 14:12:20 +0000 +Subject: [PATCH] gmem: Add g_free_sized() and g_aligned_free_sized() + +These wrap `free_sized()` and `free_aligned_sized()`, which are present +in C23[1]. This means that user code can start to use them without checking +for C23 support everywhere first. + +It also means we can use them internally in GSlice to get a bit of +performance for the code which still uses it. + +See https://en.cppreference.com/w/c/memory/free_aligned_sized and +https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2699.htm. + +[1]: Specifically, section 7.24.3.4 of the latest C23 draft at +https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3088.pdf. + +Signed-off-by: Philip Withnall + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/329843f682d1216d4f41aab7b5711f21ef280b71 + +diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt +index 3532d28..ac93ae6 100644 +--- a/docs/reference/glib/glib-sections.txt ++++ b/docs/reference/glib/glib-sections.txt +@@ -1397,6 +1397,7 @@ g_try_realloc_n + + + g_free ++g_free_sized + g_clear_pointer + g_steal_pointer + g_mem_gc_friendly +@@ -1411,6 +1412,7 @@ g_newa0 + g_aligned_alloc + g_aligned_alloc0 + g_aligned_free ++g_aligned_free_sized + + + g_memmove +diff --git a/glib/gmem.c b/glib/gmem.c +index 060e91a..e94268a 100644 +--- a/glib/gmem.c ++++ b/glib/gmem.c +@@ -209,6 +209,9 @@ g_realloc (gpointer mem, + * + * Frees the memory pointed to by @mem. + * ++ * If you know the allocated size of @mem, calling g_free_sized() may be faster, ++ * depending on the libc implementation in use. ++ * + * If @mem is %NULL it simply returns, so there is no need to check @mem + * against %NULL before calling this function. + */ +@@ -219,6 +222,33 @@ g_free (gpointer mem) + TRACE(GLIB_MEM_FREE((void*) mem)); + } + ++/** ++ * g_free_sized: ++ * @mem: (nullable): the memory to free ++ * @size: size of @mem, in bytes ++ * ++ * Frees the memory pointed to by @mem, assuming it is has the given @size. ++ * ++ * If @mem is %NULL this is a no-op (and @size is ignored). ++ * ++ * It is an error if @size doesn鈥檛 match the size passed when @mem was ++ * allocated. @size is passed to this function to allow optimizations in the ++ * allocator. If you don鈥檛 know the allocation size, use g_free() instead. ++ * ++ * Since: 2.72 ++ */ ++void ++g_free_sized (void *mem, ++ size_t size) ++{ ++#ifdef HAVE_FREE_SIZED ++ free_sized (mem, size); ++#else ++ free (mem); ++#endif ++ TRACE (GLIB_MEM_FREE ((void*) mem)); ++} ++ + /** + * g_clear_pointer: (skip) + * @pp: (not nullable): a pointer to a variable, struct member etc. holding a +@@ -555,7 +585,7 @@ g_mem_profile (void) + * multiplication. + * + * Aligned memory allocations returned by this function can only be +- * freed using g_aligned_free(). ++ * freed using g_aligned_free_sized() or g_aligned_free(). + * + * Returns: (transfer full): the allocated memory + * +@@ -679,3 +709,33 @@ g_aligned_free (gpointer mem) + { + aligned_free (mem); + } ++ ++/** ++ * g_aligned_free_sized: ++ * @mem: (nullable): the memory to free ++ * @alignment: alignment of @mem ++ * @size: size of @mem, in bytes ++ * ++ * Frees the memory pointed to by @mem, assuming it is has the given @size and ++ * @alignment. ++ * ++ * If @mem is %NULL this is a no-op (and @size is ignored). ++ * ++ * It is an error if @size doesn鈥檛 match the size, or @alignment doesn鈥檛 match ++ * the alignment, passed when @mem was allocated. @size and @alignment are ++ * passed to this function to allow optimizations in the allocator. If you ++ * don鈥檛 know either of them, use g_aligned_free() instead. ++ * ++ * Since: 2.72 ++ */ ++void ++g_aligned_free_sized (void *mem, ++ size_t alignment, ++ size_t size) ++{ ++#ifdef HAVE_FREE_ALIGNED_SIZED ++ free_aligned_sized (mem, alignment, size); ++#else ++ aligned_free (mem); ++#endif ++} +diff --git a/glib/gmem.h b/glib/gmem.h +index d29907a..7b306b3 100644 +--- a/glib/gmem.h ++++ b/glib/gmem.h +@@ -70,6 +70,9 @@ typedef struct _GMemVTable GMemVTable; + + GLIB_AVAILABLE_IN_ALL + void g_free (gpointer mem); ++GLIB_AVAILABLE_IN_2_72 ++void g_free_sized (gpointer mem, ++ size_t size); + + GLIB_AVAILABLE_IN_2_34 + void g_clear_pointer (gpointer *pp, +@@ -121,6 +124,10 @@ gpointer g_aligned_alloc0 (gsize n_blocks, + gsize alignment) G_GNUC_WARN_UNUSED_RESULT G_GNUC_ALLOC_SIZE2(1,2); + GLIB_AVAILABLE_IN_2_72 + void g_aligned_free (gpointer mem); ++GLIB_AVAILABLE_IN_2_72 ++void g_aligned_free_sized (gpointer mem, ++ size_t alignment, ++ size_t size); + + #if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 + #define g_clear_pointer(pp, destroy) \ +diff --git a/glib/tests/utils.c b/glib/tests/utils.c +index dcdc5a6..602abe1 100644 +--- a/glib/tests/utils.c ++++ b/glib/tests/utils.c +@@ -1000,6 +1000,39 @@ test_aligned_mem_zeroed (void) + g_aligned_free (p); + } + ++static void ++test_aligned_mem_free_sized (void) ++{ ++ gsize n_blocks = 10; ++ guint *p; ++ ++ g_test_summary ("Check that g_aligned_free_sized() works"); ++ ++ p = g_aligned_alloc (n_blocks, sizeof (*p), 16); ++ g_assert_nonnull (p); ++ ++ g_aligned_free_sized (p, sizeof (*p), n_blocks * 16); ++ ++ /* NULL should be ignored */ ++ g_aligned_free_sized (NULL, sizeof (*p), n_blocks * 16); ++} ++ ++static void ++test_free_sized (void) ++{ ++ gpointer p; ++ ++ g_test_summary ("Check that g_free_sized() works"); ++ ++ p = g_malloc (123); ++ g_assert_nonnull (p); ++ ++ g_free_sized (p, 123); ++ ++ /* NULL should be ignored */ ++ g_free_sized (NULL, 123); ++} ++ + static void + test_nullify (void) + { +@@ -1174,6 +1207,8 @@ main (int argc, + g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov); + g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment); + g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed); ++ g_test_add_func ("/utils/aligned-mem/free-sized", test_aligned_mem_free_sized); ++ g_test_add_func ("/utils/free-sized", test_free_sized); + g_test_add_func ("/utils/nullify", test_nullify); + g_test_add_func ("/utils/atexit", test_atexit); + g_test_add_func ("/utils/check-setuid", test_check_setuid); +diff --git a/meson.build b/meson.build +index 657e9f6..3f32ef7 100644 +--- a/meson.build ++++ b/meson.build +@@ -535,6 +535,8 @@ functions = [ + 'fchmod', + 'fchown', + 'fdwalk', ++ 'free_aligned_sized', ++ 'free_sized', + 'fsync', + 'getauxval', + 'getc_unlocked', +-- +2.33.0 \ No newline at end of file diff --git a/patch/backport-add-version-macros-for-GLib-2.74.patch b/patch/backport-add-version-macros-for-GLib-2.74.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca2bbd5d6a4a062abba725137b3f882a0b320c26 --- /dev/null +++ b/patch/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_72 ++# define GLIB_AVAILABLE_IN_2_74 GLIB_UNAVAILABLE(2, 72) ++# define GLIB_AVAILABLE_STATIC_INLINE_IN_2_74 GLIB_UNAVAILABLE_STATIC_INLINE(2, 72) ++# define GLIB_AVAILABLE_MACRO_IN_2_74 GLIB_UNAVAILABLE_MACRO(2, 72) ++# define GLIB_AVAILABLE_ENUMERATOR_IN_2_74 GLIB_UNAVAILABLE_ENUMERATOR(2, 72) ++# define GLIB_AVAILABLE_TYPE_IN_2_74 GLIB_UNAVAILABLE_TYPE(2, 72) ++#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/patch/backport-application-Unset-the-registered-state-after-shutting-down.patch b/patch/backport-application-Unset-the-registered-state-after-shutting-down.patch deleted file mode 100644 index 7101ea9ea3a92b0a6a016e9e674a37f9c378b9cf..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-correctly-use-3-parameters-for-clise-range.patch b/patch/backport-correctly-use-3-parameters-for-clise-range.patch deleted file mode 100644 index d9f366c275465eb8e341b3762e83b04cd1b856b6..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-fix-a-memory-leak.patch b/patch/backport-fix-a-memory-leak.patch deleted file mode 100644 index e303568f5c2b06d0bf5c0a448d459305c2ca15d1..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gapplication-fix-arguments-leak-in-error-path.patch b/patch/backport-gapplication-fix-arguments-leak-in-error-path.patch deleted file mode 100644 index 6d833df6f6567d37162770176d4b5f05b3fae1c7..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch b/patch/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch deleted file mode 100644 index 10b9e402a8f01ac37468e8f05ac3731973229346..0000000000000000000000000000000000000000 --- a/patch/backport-garray-Fix-integer-overflows-in-element-capacity-calculations.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 374a1895b62b2504d0b6ae1c404237802e73ddb6 Mon Sep 17 00:00:00 2001 -From: Tobias Stoeckmann -Date: Tue, 18 Jan 2022 13:45:13 +0000 -Subject: [PATCH] garray: Fix integer overflows in element capacity - calculations - -Integer overflows in size calculations of buffers (GArray and GPtrArray) -allow subsequent buffer overflows. This happens due to conversions -between gsize and guint. - -Proof of concept demonstrations of the overflows can be found in issue -2578. They are not being added as unit tests as they require too much -memory to test. - -This will affect `GArray`s which are 4GB in size, or `GPtrArray`s which -are 48GB in size. - -Fixes: #2578 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/374a1895b62b2504d0b6ae1c404237802e73ddb6 - ---- - glib/garray.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/glib/garray.c b/glib/garray.c -index 3803fee037..b441562154 100644 ---- a/glib/garray.c -+++ b/glib/garray.c -@@ -1001,7 +1001,7 @@ g_array_maybe_expand (GRealArray *array, - memset (g_array_elt_pos (array, array->elt_capacity), 0, - g_array_elt_len (array, want_len - array->elt_capacity)); - -- array->elt_capacity = want_alloc / array->elt_size; -+ array->elt_capacity = MIN (want_alloc / array->elt_size, G_MAXUINT); - } - } - -@@ -1518,9 +1518,10 @@ g_ptr_array_maybe_expand (GRealPtrArray *array, - if ((array->len + len) > array->alloc) - { - guint old_alloc = array->alloc; -- array->alloc = g_nearest_pow (array->len + len); -- array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); -- array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc); -+ gsize want_alloc = g_nearest_pow (sizeof (gpointer) * (array->len + len)); -+ want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); -+ array->alloc = MIN (want_alloc / sizeof (gpointer), G_MAXUINT); -+ array->pdata = g_realloc (array->pdata, want_alloc); - if (G_UNLIKELY (g_mem_gc_friendly)) - for ( ; old_alloc < array->alloc; old_alloc++) - array->pdata [old_alloc] = NULL; --- -GitLab diff --git a/patch/backport-garray-buffer-overflow-fix.patch b/patch/backport-garray-buffer-overflow-fix.patch deleted file mode 100644 index f6ec4ebf0715b195f44b44e05658bcc3fa1f65ee..0000000000000000000000000000000000000000 --- a/patch/backport-garray-buffer-overflow-fix.patch +++ /dev/null @@ -1,279 +0,0 @@ -From 995823b9d9e866ffb133cf3ff53e7e09da9f13d6 Mon Sep 17 00:00:00 2001 -From: Mark Weaver -Date: Tue, 19 Oct 2021 15:38:13 +0000 -Subject: [PATCH] #1331: buffer overflow fix - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/995823b9d9e866ffb133cf3ff53e7e09da9f13d6 - ---- - glib/garray.c | 57 ++++++++++++++++++++----------------- - glib/tests/array-test.c | 62 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 94 insertions(+), 25 deletions(-) - -diff --git a/glib/garray.c b/glib/garray.c -index 025747ee56..d072441906 100644 ---- a/glib/garray.c -+++ b/glib/garray.c -@@ -107,7 +107,7 @@ struct _GRealArray - { - guint8 *data; - guint len; -- guint alloc; -+ guint elt_capacity; - guint elt_size; - guint zero_terminated : 1; - guint clear : 1; -@@ -150,7 +150,7 @@ struct _GRealArray - * Returns: the element of the #GArray at the index given by @i - */ - --#define g_array_elt_len(array,i) ((array)->elt_size * (i)) -+#define g_array_elt_len(array,i) ((gsize)(array)->elt_size * (i)) - #define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i))) - #define g_array_elt_zero(array, pos, len) \ - (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len))) -@@ -159,7 +159,7 @@ struct _GRealArray - g_array_elt_zero ((array), (array)->len, 1); \ - }G_STMT_END - --static guint g_nearest_pow (guint num) G_GNUC_CONST; -+static gsize g_nearest_pow (gsize num) G_GNUC_CONST; - static void g_array_maybe_expand (GRealArray *array, - guint len); - -@@ -181,6 +181,7 @@ g_array_new (gboolean zero_terminated, - guint elt_size) - { - g_return_val_if_fail (elt_size > 0, NULL); -+ g_return_val_if_fail (elt_size <= G_MAXUINT / 2 - 1, NULL); - - return g_array_sized_new (zero_terminated, clear, elt_size, 0); - } -@@ -232,7 +233,7 @@ g_array_steal (GArray *array, - - rarray->data = NULL; - rarray->len = 0; -- rarray->alloc = 0; -+ rarray->elt_capacity = 0; - return segment; - } - -@@ -261,12 +262,13 @@ g_array_sized_new (gboolean zero_terminated, - GRealArray *array; - - g_return_val_if_fail (elt_size > 0, NULL); -+ g_return_val_if_fail (elt_size <= G_MAXUINT, NULL); - - array = g_slice_new (GRealArray); - - array->data = NULL; - array->len = 0; -- array->alloc = 0; -+ array->elt_capacity = 0; - array->zero_terminated = (zero_terminated ? 1 : 0); - array->clear = (clear ? 1 : 0); - array->elt_size = elt_size; -@@ -471,7 +473,7 @@ array_free (GRealArray *array, - { - array->data = NULL; - array->len = 0; -- array->alloc = 0; -+ array->elt_capacity = 0; - } - else - { -@@ -966,22 +968,22 @@ g_array_binary_search (GArray *array, - return result; - } - --/* Returns the smallest power of 2 greater than n, or n if -- * such power does not fit in a guint -+/* Returns the smallest power of 2 greater than or equal to n, -+ * or 0 if such power does not fit in a gsize - */ --static guint --g_nearest_pow (guint num) -+static gsize -+g_nearest_pow (gsize num) - { -- guint n = num - 1; -+ gsize n = num - 1; - -- g_assert (num > 0); -+ g_assert (num > 0 && num <= G_MAXSIZE / 2); - - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; --#if SIZEOF_INT == 8 -+#if GLIB_SIZEOF_SIZE_T == 8 - n |= n >> 32; - #endif - -@@ -992,26 +994,32 @@ static void - g_array_maybe_expand (GRealArray *array, - guint len) - { -- guint want_alloc; -+ guint max_len, want_len; -+ -+ /* The maximum array length is derived from following constraints: -+ * - The number of bytes must fit into a gsize / 2. -+ * - The number of elements must fit into guint. -+ * - zero terminated arrays must leave space for the terminating element -+ */ -+ max_len = MIN (G_MAXSIZE / 2 / array->elt_size, G_MAXUINT) - array->zero_terminated; - - /* Detect potential overflow */ -- if G_UNLIKELY ((G_MAXUINT - array->len) < len) -+ if G_UNLIKELY ((max_len - array->len) < len) - g_error ("adding %u to array would overflow", len); - -- want_alloc = g_array_elt_len (array, array->len + len + -- array->zero_terminated); -- -- if (want_alloc > array->alloc) -+ want_len = array->len + len + array->zero_terminated; -+ if (want_len > array->elt_capacity) - { -- want_alloc = g_nearest_pow (want_alloc); -+ gsize want_alloc = g_nearest_pow (g_array_elt_len (array, want_len)); - want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); - - array->data = g_realloc (array->data, want_alloc); - - if (G_UNLIKELY (g_mem_gc_friendly)) -- memset (array->data + array->alloc, 0, want_alloc - array->alloc); -+ memset (g_array_elt_pos (array, array->elt_capacity), 0, -+ g_array_elt_len (array, want_len - array->elt_capacity)); - -- array->alloc = want_alloc; -+ array->elt_capacity = want_alloc / array->elt_size; - } - } - -@@ -1297,7 +1305,7 @@ g_array_copy (GArray *array) - - new_rarray = - (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear, -- rarray->elt_size, rarray->alloc / rarray->elt_size); -+ rarray->elt_size, rarray->elt_capacity); - new_rarray->len = rarray->len; - if (rarray->len > 0) - memcpy (new_rarray->data, rarray->data, rarray->len * rarray->elt_size); -@@ -2298,7 +2306,6 @@ g_byte_array_new_take (guint8 *data, - GRealArray *real; - - g_return_val_if_fail (len <= G_MAXUINT, NULL); -- - array = g_byte_array_new (); - real = (GRealArray *)array; - g_assert (real->data == NULL); -@@ -2306,7 +2313,7 @@ g_byte_array_new_take (guint8 *data, - - real->data = data; - real->len = len; -- real->alloc = len; -+ real->elt_capacity = len; - - return array; - } -diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c -index 471f6171dc..79c5c31c32 100644 ---- a/glib/tests/array-test.c -+++ b/glib/tests/array-test.c -@@ -845,6 +845,45 @@ test_array_copy_sized (void) - g_array_unref (array1); - } - -+static void -+array_overflow_append_vals (void) -+{ -+ if (!g_test_undefined ()) -+ return; -+ -+ if (g_test_subprocess ()) -+ { -+ GArray *array = g_array_new (TRUE, FALSE, 1); -+ /* Check for overflow should happen before data is accessed. */ -+ g_array_append_vals (array, NULL, G_MAXUINT); -+ } -+ else -+ { -+ g_test_trap_subprocess (NULL, 0, 0); -+ g_test_trap_assert_failed (); -+ g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*"); -+ } -+} -+ -+static void -+array_overflow_set_size (void) -+{ -+ if (!g_test_undefined ()) -+ return; -+ -+ if (g_test_subprocess ()) -+ { -+ GArray *array = g_array_new (TRUE, FALSE, 1); -+ g_array_set_size (array, G_MAXUINT); -+ } -+ else -+ { -+ g_test_trap_subprocess (NULL, 0, 0); -+ g_test_trap_assert_failed (); -+ g_test_trap_assert_stderr ("*adding 4294967295 to array would overflow*"); -+ } -+} -+ - /* Check g_ptr_array_steal() function */ - static void - pointer_array_steal (void) -@@ -1643,6 +1682,26 @@ pointer_array_steal_index (void) - g_assert_cmpuint (i4, ==, 1); - } - -+static void -+byte_array_new_take_overflow (void) -+{ -+#if G_MAXSIZE <= G_MAXUINT -+ g_test_skip ("Overflow test requires G_MAXSIZE > G_MAXUINT."); -+#else -+ GByteArray* arr; -+ -+ if (!g_test_undefined ()) -+ return; -+ -+ /* Check for overflow should happen before data is accessed. */ -+ g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, -+ "*assertion 'len <= G_MAXUINT' failed"); -+ arr = g_byte_array_new_take (NULL, (gsize)G_MAXUINT + 1); -+ g_assert_null (arr); -+ g_test_assert_expected_messages (); -+#endif -+} -+ - static void - byte_array_steal (void) - { -@@ -1998,6 +2057,8 @@ main (int argc, char *argv[]) - g_test_add_func ("/array/clear-func", array_clear_func); - g_test_add_func ("/array/binary-search", test_array_binary_search); - g_test_add_func ("/array/copy-sized", test_array_copy_sized); -+ g_test_add_func ("/array/overflow-append-vals", array_overflow_append_vals); -+ g_test_add_func ("/array/overflow-set-size", array_overflow_set_size); - - for (i = 0; i < G_N_ELEMENTS (array_configurations); i++) - { -@@ -2043,6 +2104,7 @@ main (int argc, char *argv[]) - g_test_add_func ("/bytearray/sort", byte_array_sort); - g_test_add_func ("/bytearray/sort-with-data", byte_array_sort_with_data); - g_test_add_func ("/bytearray/new-take", byte_array_new_take); -+ g_test_add_func ("/bytearray/new-take-overflow", byte_array_new_take_overflow); - g_test_add_func ("/bytearray/free-to-bytes", byte_array_free_to_bytes); - - return g_test_run (); --- -GitLab diff --git a/patch/backport-gdbusauth-fix-error-leak.patch b/patch/backport-gdbusauth-fix-error-leak.patch deleted file mode 100644 index 709b71e1bc3783f365bc016a8b015d56f11c35b2..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gdbusconnection-Add-some-ownership-annotations.patch b/patch/backport-gdbusconnection-Add-some-ownership-annotations.patch deleted file mode 100644 index 0b279447ab4271a8103e1b4679ceca7f97aac0ba..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusconnection-Add-some-ownership-annotations.patch +++ /dev/null @@ -1,54 +0,0 @@ -From a497fdf302bf67e4df2e1474389c0ff2152f1e99 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 08:58:42 +0100 -Subject: [PATCH] gdbusconnection: Add some ownership annotations - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a497fdf302bf67e4df2e1474389c0ff2152f1e99 - ---- - gio/gdbusconnection.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 24a50fcf20..40ce1b6fc7 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -4086,11 +4086,11 @@ typedef struct - ExportedObject *eo; - - guint id; -- gchar *interface_name; -- GDBusInterfaceVTable *vtable; -- GDBusInterfaceInfo *interface_info; -+ gchar *interface_name; /* (owned) */ -+ GDBusInterfaceVTable *vtable; /* (owned) */ -+ GDBusInterfaceInfo *interface_info; /* (owned) */ - -- GMainContext *context; -+ GMainContext *context; /* (owned) */ - gpointer user_data; - GDestroyNotify user_data_free_func; - } ExportedInterface; -@@ -4116,12 +4116,12 @@ exported_interface_free (ExportedInterface *ei) - struct ExportedSubtree - { - guint id; -- gchar *object_path; -- GDBusConnection *connection; -- GDBusSubtreeVTable *vtable; -+ gchar *object_path; /* (owned) */ -+ GDBusConnection *connection; /* (unowned) */ -+ GDBusSubtreeVTable *vtable; /* (owned) */ - GDBusSubtreeFlags flags; - -- GMainContext *context; -+ GMainContext *context; /* (owned) */ - gpointer user_data; - GDestroyNotify user_data_free_func; - }; --- -GitLab - diff --git a/patch/backport-gdbusconnection-Fix-double-unref-on-timeout-cancel-sending-a-message.patch b/patch/backport-gdbusconnection-Fix-double-unref-on-timeout-cancel-sending-a-message.patch new file mode 100644 index 0000000000000000000000000000000000000000..912f371fbdc362a0b224ba14d26f67afc89cde73 --- /dev/null +++ b/patch/backport-gdbusconnection-Fix-double-unref-on-timeout-cancel-sending-a-message.patch @@ -0,0 +1,877 @@ +From 4900ea5215e329fbfe893be7975cf05ff153ef81 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:40:35 +0000 +Subject: [PATCH 1/9] gdbusconnection: Fix double unref on timeout/cancel + sending a message + +This appears to fix an intermittent failure seen when sending a D-Bus +message with either of a cancellable or a timeout set. + +In particular, I can reliably reproduce it with: +``` +meson test gdbus-test-codegen-min-required-2-64 --repeat 10000 +``` + +It can be caught easily with asan when reproduced. Tracking down the +location of the refcount mismatch was a little tricky, but was +simplified by replacing a load of `g_object_ref (message)` calls with +`g_dbus_message_copy (message, NULL)` to switch `GDBusMessage` handling +to using copy semantics. This allowed asan to home in on where the +refcount mismatch was happening. + +The problem was that `send_message_data_deliver_error()` takes ownership +of the `GTask` passed to it, but the +`send_message_with_replace_cancelled_idle_cb()` and +`send_message_with_reply_timeout_cb()` functions which were calling it, +were not passing in a strong reference as they should have. + +Another approach to fixing this would have been to change the transfer +semantics of `send_message_data_deliver_error()` so it was `(transfer +none)` on its `GTask`. That would probably have resulted in cleaner +code, but would have been a lot harder to verify/review the fix, and +easier to inadvertently introduce new bugs. + +The fact that the bug was only triggered by the cancellation and timeout +callbacks explains why it was intermittent: these code paths are +typically never hit, but the timeout path may sometimes be hit on a very +slow test run. + +Signed-off-by: Philip Withnall + +Fixes: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/4900ea5215e329fbfe893be7975cf05ff153ef81 + +--- + gio/gdbusconnection.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index d938f71b99..06c8a6141f 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -1822,7 +1822,7 @@ send_message_data_deliver_reply_unlocked (GTask *task, + ; + } + +-/* Called from a user thread, lock is not held */ ++/* Called from a user thread, lock is not held; @task is (transfer full) */ + static void + send_message_data_deliver_error (GTask *task, + GQuark domain, +@@ -1849,13 +1849,14 @@ send_message_data_deliver_error (GTask *task, + + /* ---------------------------------------------------------------------------------------------------- */ + +-/* Called from a user thread, lock is not held; @task is (transfer full) */ ++/* Called from a user thread, lock is not held; @task is (transfer none) */ + static gboolean + send_message_with_reply_cancelled_idle_cb (gpointer user_data) + { + GTask *task = user_data; + +- send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, ++ g_object_ref (task); ++ send_message_data_deliver_error (g_steal_pointer (&task), G_IO_ERROR, G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + return FALSE; + } +@@ -1879,13 +1880,14 @@ send_message_with_reply_cancelled_cb (GCancellable *cancellable, + + /* ---------------------------------------------------------------------------------------------------- */ + +-/* Called from a user thread, lock is not held; @task is (transfer full) */ ++/* Called from a user thread, lock is not held; @task is (transfer none) */ + static gboolean + send_message_with_reply_timeout_cb (gpointer user_data) + { + GTask *task = user_data; + +- send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, ++ g_object_ref (task); ++ send_message_data_deliver_error (g_steal_pointer (&task), G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Timeout was reached")); + return FALSE; + } +-- +GitLab + + +From 127c899a2e727d10eb88b8fae196add11a6c053f Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:45:15 +0000 +Subject: [PATCH 2/9] gdbusconnection: Fix the type of a free function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This didn’t actually cause any observable bugs, since the structures of +`PropertyData` and `PropertyGetAllData` were equivalent for the members +which the free function touches. + +Definitely should be fixed though. + +Signed-off-by: Philip Withnall + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/127c899a2e727d10eb88b8fae196add11a6c053f + +--- + gio/gdbusconnection.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index 06c8a6141f..6a0d67a8ee 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -4584,7 +4584,7 @@ typedef struct + } PropertyGetAllData; + + static void +-property_get_all_data_free (PropertyData *data) ++property_get_all_data_free (PropertyGetAllData *data) + { + g_object_unref (data->connection); + g_object_unref (data->message); +-- +GitLab + + +From 90af20d9505a11d02e81a4f8fa09ee15faba96b8 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:46:55 +0000 +Subject: [PATCH 3/9] gdbusconnection: Improve docs of message ownership in + closures + +This introduces no functional changes, but makes it a little clearer how +the ownership of these `GDBusMessage` instances works. The free function +is changed to `g_clear_object()` to avoid the possibility of somehow +using the messages after freeing them. + +Basically just some drive-by docs improvements while trying to debug +issue #1264. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/90af20d9505a11d02e81a4f8fa09ee15faba96b8 + +--- + gio/gdbusconnection.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index 6a0d67a8ee..0cbfc66c13 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -3743,7 +3743,7 @@ g_dbus_connection_signal_unsubscribe (GDBusConnection *connection, + typedef struct + { + SignalSubscriber *subscriber; /* (owned) */ +- GDBusMessage *message; ++ GDBusMessage *message; /* (owned) */ + GDBusConnection *connection; + const gchar *sender; /* (nullable) for peer-to-peer connections */ + const gchar *path; +@@ -3807,7 +3807,7 @@ emit_signal_instance_in_idle_cb (gpointer data) + static void + signal_instance_free (SignalInstance *signal_instance) + { +- g_object_unref (signal_instance->message); ++ g_clear_object (&signal_instance->message); + g_object_unref (signal_instance->connection); + signal_subscriber_unref (signal_instance->subscriber); + g_free (signal_instance); +@@ -4219,7 +4219,7 @@ has_object_been_unregistered (GDBusConnection *connection, + typedef struct + { + GDBusConnection *connection; +- GDBusMessage *message; ++ GDBusMessage *message; /* (owned) */ + gpointer user_data; + const gchar *property_name; + const GDBusInterfaceVTable *vtable; +@@ -4233,7 +4233,7 @@ static void + property_data_free (PropertyData *data) + { + g_object_unref (data->connection); +- g_object_unref (data->message); ++ g_clear_object (&data->message); + g_free (data); + } + +@@ -4575,7 +4575,7 @@ handle_getset_property (GDBusConnection *connection, + typedef struct + { + GDBusConnection *connection; +- GDBusMessage *message; ++ GDBusMessage *message; /* (owned) */ + gpointer user_data; + const GDBusInterfaceVTable *vtable; + GDBusInterfaceInfo *interface_info; +@@ -4587,7 +4587,7 @@ static void + property_get_all_data_free (PropertyGetAllData *data) + { + g_object_unref (data->connection); +- g_object_unref (data->message); ++ g_clear_object (&data->message); + g_free (data); + } + +@@ -6815,7 +6815,7 @@ typedef struct + static void + subtree_deferred_data_free (SubtreeDeferredData *data) + { +- g_object_unref (data->message); ++ g_clear_object (&data->message); + exported_subtree_unref (data->es); + g_free (data); + } +-- +GitLab + + +From ed7044b5f383cf8b77df751578e184d4ad7a134f Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:49:29 +0000 +Subject: [PATCH 4/9] gdbusprivate: Improve docs on message ownership in + MessageToWriteData +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This doesn’t introduce any functional changes, but should make the code +a little clearer. + +Drive-by improvements while trying to debug #1264. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/ed7044b5f383cf8b77df751578e184d4ad7a134f + +--- + gio/gdbusprivate.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index 762afcee46..bd776a4214 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -889,7 +889,7 @@ _g_dbus_worker_do_initial_read (gpointer data) + struct _MessageToWriteData + { + GDBusWorker *worker; +- GDBusMessage *message; ++ GDBusMessage *message; /* (owned) */ + gchar *blob; + gsize blob_size; + +@@ -901,8 +901,7 @@ static void + message_to_write_data_free (MessageToWriteData *data) + { + _g_dbus_worker_unref (data->worker); +- if (data->message) +- g_object_unref (data->message); ++ g_clear_object (&data->message); + g_free (data->blob); + g_slice_free (MessageToWriteData, data); + } +-- +GitLab + + +From 861741ef4bff1a3ee15175e189136563b74fe790 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:50:47 +0000 +Subject: [PATCH 5/9] gdbusprivate: Ensure data->task is cleared when it + returns +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The existing comment in the code was correct that `data` is freed when +the task callback is called, because `data` is also pointed to by the +`user_data` for the task, and that’s freed at the end of the callback. + +So the existing code was correct to take a copy of `data->task` before +calling `g_task_return_*()`. + +After calling `g_task_return_*()`, the existing code unreffed the task +(which is correct), but then didn’t clear the `data->task` pointer, +leaving `data->task` dangling. That could cause a use-after-free or a +double-unref. + +Avoid that risk by explicitly clearing `data->task` before calling +`g_task_return_*()`. + +After some testing, it turns out this doesn’t actually fix any bugs, but +it’s still a good robustness improvement. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/861741ef4bff1a3ee15175e189136563b74fe790 + +--- + gio/gdbusprivate.c | 54 ++++++++++++++++++++++++++++------------------ + 1 file changed, 33 insertions(+), 21 deletions(-) + +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index bd776a4214..0b4806f524 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -894,7 +894,7 @@ struct _MessageToWriteData + gsize blob_size; + + gsize total_written; +- GTask *task; ++ GTask *task; /* (owned) and (nullable) before writing starts and after g_task_return_*() is called */ + }; + + static void +@@ -903,6 +903,11 @@ message_to_write_data_free (MessageToWriteData *data) + _g_dbus_worker_unref (data->worker); + g_clear_object (&data->message); + g_free (data->blob); ++ ++ /* The task must either not have been created, or have been created, returned ++ * and finalised by now. */ ++ g_assert (data->task == NULL); ++ + g_slice_free (MessageToWriteData, data); + } + +@@ -921,14 +926,14 @@ write_message_async_cb (GObject *source_object, + gpointer user_data) + { + MessageToWriteData *data = user_data; +- GTask *task; + gssize bytes_written; + GError *error; + +- /* Note: we can't access data->task after calling g_task_return_* () because the +- * callback can free @data and we're not completing in idle. So use a copy of the pointer. +- */ +- task = data->task; ++ /* The ownership of @data is a bit odd in this function: it’s (transfer full) ++ * when the function is called, but the code paths which call g_task_return_*() ++ * on @data->task will indirectly cause it to be freed, because @data is ++ * always guaranteed to be the user_data in the #GTask. So that’s why it looks ++ * like @data is not always freed on every code path in this function. */ + + error = NULL; + bytes_written = g_output_stream_write_finish (G_OUTPUT_STREAM (source_object), +@@ -936,8 +941,9 @@ write_message_async_cb (GObject *source_object, + &error); + if (bytes_written == -1) + { ++ GTask *task = g_steal_pointer (&data->task); + g_task_return_error (task, error); +- g_object_unref (task); ++ g_clear_object (&task); + goto out; + } + g_assert (bytes_written > 0); /* zero is never returned */ +@@ -948,8 +954,9 @@ write_message_async_cb (GObject *source_object, + g_assert (data->total_written <= data->blob_size); + if (data->total_written == data->blob_size) + { ++ GTask *task = g_steal_pointer (&data->task); + g_task_return_boolean (task, TRUE); +- g_object_unref (task); ++ g_clear_object (&task); + goto out; + } + +@@ -986,16 +993,14 @@ write_message_continue_writing (MessageToWriteData *data) + { + GOutputStream *ostream; + #ifdef G_OS_UNIX +- GTask *task; + GUnixFDList *fd_list; + #endif + +-#ifdef G_OS_UNIX +- /* Note: we can't access data->task after calling g_task_return_* () because the +- * callback can free @data and we're not completing in idle. So use a copy of the pointer. +- */ +- task = data->task; +-#endif ++ /* The ownership of @data is a bit odd in this function: it’s (transfer full) ++ * when the function is called, but the code paths which call g_task_return_*() ++ * on @data->task will indirectly cause it to be freed, because @data is ++ * always guaranteed to be the user_data in the #GTask. So that’s why it looks ++ * like @data is not always freed on every code path in this function. */ + + ostream = g_io_stream_get_output_stream (data->worker->stream); + #ifdef G_OS_UNIX +@@ -1024,11 +1029,12 @@ write_message_continue_writing (MessageToWriteData *data) + { + if (!(data->worker->capabilities & G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)) + { ++ GTask *task = g_steal_pointer (&data->task); + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Tried sending a file descriptor but remote peer does not support this capability"); +- g_object_unref (task); ++ g_clear_object (&task); + goto out; + } + control_message = g_unix_fd_message_new_with_fd_list (fd_list); +@@ -1065,9 +1071,13 @@ write_message_continue_writing (MessageToWriteData *data) + g_error_free (error); + goto out; + } +- g_task_return_error (task, error); +- g_object_unref (task); +- goto out; ++ else ++ { ++ GTask *task = g_steal_pointer (&data->task); ++ g_task_return_error (task, error); ++ g_clear_object (&task); ++ goto out; ++ } + } + g_assert (bytes_written > 0); /* zero is never returned */ + +@@ -1077,8 +1087,9 @@ write_message_continue_writing (MessageToWriteData *data) + g_assert (data->total_written <= data->blob_size); + if (data->total_written == data->blob_size) + { ++ GTask *task = g_steal_pointer (&data->task); + g_task_return_boolean (task, TRUE); +- g_object_unref (task); ++ g_clear_object (&task); + goto out; + } + +@@ -1093,12 +1104,13 @@ write_message_continue_writing (MessageToWriteData *data) + /* We were trying to write byte 0 of the message, which needs + * the fd list to be attached to it, but this connection doesn't + * support doing that. */ ++ GTask *task = g_steal_pointer (&data->task); + g_task_return_new_error (task, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Tried sending a file descriptor on unsupported stream of type %s", + g_type_name (G_TYPE_FROM_INSTANCE (ostream))); +- g_object_unref (task); ++ g_clear_object (&task); + goto out; + } + #endif +-- +GitLab + + +From d7c813cf5b6148c18184e4f1af23d234e73aafb8 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:56:56 +0000 +Subject: [PATCH 6/9] gdbusprivate: Improve ownership docs for + write_message_async() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The ownership transfers in this code are a bit complex, so adding some +extra documentation and `g_steal_pointer()` calls should hopefully help +clarify things. + +This doesn’t introduce any functional changes, just code documentation. + +Another drive-by improvement in the quest for #1264. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d7c813cf5b6148c18184e4f1af23d234e73aafb8 + +--- + gio/gdbusprivate.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index 0b4806f524..5aa141a60e 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -919,13 +919,14 @@ static void write_message_continue_writing (MessageToWriteData *data); + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry ++ * @user_data is (transfer full) + */ + static void + write_message_async_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) + { +- MessageToWriteData *data = user_data; ++ MessageToWriteData *data = g_steal_pointer (&user_data); + gssize bytes_written; + GError *error; + +@@ -960,7 +961,7 @@ write_message_async_cb (GObject *source_object, + goto out; + } + +- write_message_continue_writing (data); ++ write_message_continue_writing (g_steal_pointer (&data)); + + out: + ; +@@ -977,8 +978,8 @@ on_socket_ready (GSocket *socket, + GIOCondition condition, + gpointer user_data) + { +- MessageToWriteData *data = user_data; +- write_message_continue_writing (data); ++ MessageToWriteData *data = g_steal_pointer (&user_data); ++ write_message_continue_writing (g_steal_pointer (&data)); + return FALSE; /* remove source */ + } + #endif +@@ -987,6 +988,7 @@ on_socket_ready (GSocket *socket, + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry ++ * @data is (transfer full) + */ + static void + write_message_continue_writing (MessageToWriteData *data) +@@ -1064,7 +1066,7 @@ write_message_continue_writing (MessageToWriteData *data) + data->worker->cancellable); + g_source_set_callback (source, + (GSourceFunc) on_socket_ready, +- data, ++ g_steal_pointer (&data), + NULL); /* GDestroyNotify */ + g_source_attach (source, g_main_context_get_thread_default ()); + g_source_unref (source); +@@ -1093,7 +1095,7 @@ write_message_continue_writing (MessageToWriteData *data) + goto out; + } + +- write_message_continue_writing (data); ++ write_message_continue_writing (g_steal_pointer (&data)); + } + #endif + else +@@ -1121,7 +1123,7 @@ write_message_continue_writing (MessageToWriteData *data) + G_PRIORITY_DEFAULT, + data->worker->cancellable, + write_message_async_cb, +- data); ++ data); /* steal @data */ + } + #ifdef G_OS_UNIX + out: +@@ -1144,7 +1146,7 @@ write_message_async (GDBusWorker *worker, + g_task_set_source_tag (data->task, write_message_async); + g_task_set_name (data->task, "[gio] D-Bus write message"); + data->total_written = 0; +- write_message_continue_writing (data); ++ write_message_continue_writing (g_steal_pointer (&data)); + } + + /* called in private thread shared by all GDBusConnection instances (with write-lock held) */ +@@ -1333,6 +1335,7 @@ prepare_flush_unlocked (GDBusWorker *worker) + * + * write-lock is not held on entry + * output_pending is PENDING_WRITE on entry ++ * @user_data is (transfer full) + */ + static void + write_message_cb (GObject *source_object, +@@ -1551,7 +1554,7 @@ continue_writing (GDBusWorker *worker) + write_message_async (worker, + data, + write_message_cb, +- data); ++ data); /* takes ownership of @data as user_data */ + } + } + +-- +GitLab + + +From 08a4387678346caaa42b69e5e6e5995d48cd61c4 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 02:58:05 +0000 +Subject: [PATCH 7/9] gdbusprivate: Use G_SOURCE_REMOVE in a source callback + +This is equivalent to the current behaviour, but a little clearer in its +meaning. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/08a4387678346caaa42b69e5e6e5995d48cd61c4 + +--- + gio/gdbusprivate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gio/gdbusprivate.c b/gio/gdbusprivate.c +index 5aa141a60e..2c9238c638 100644 +--- a/gio/gdbusprivate.c ++++ b/gio/gdbusprivate.c +@@ -980,7 +980,7 @@ on_socket_ready (GSocket *socket, + { + MessageToWriteData *data = g_steal_pointer (&user_data); + write_message_continue_writing (g_steal_pointer (&data)); +- return FALSE; /* remove source */ ++ return G_SOURCE_REMOVE; + } + #endif + +-- +GitLab + + +From b84ec21f9c4c57990309e691206582c589f59770 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 12:19:16 +0000 +Subject: [PATCH 8/9] gdbusconnection: Rearrange refcount handling of + map_method_serial_to_task +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It already implicitly held a strong ref on its `GTask` values, but +didn’t have a free function set so that they would be automatically +unreffed on removal from the map. + +This meant that the functions handling removals from the map, +`on_worker_closed()` (via `cancel_method_on_close()`) and +`send_message_with_reply_cleanup()` had to call unref once more than +they would otherwise. + +In `send_message_with_reply_cleanup()`, this behaviour depended on +whether it was called with `remove == TRUE`. If not, it was `(transfer +none)` not `(transfer full)`. This led to bugs in its callers. + +For example, this led to a direct leak in `cancel_method_on_close()`, as +it needed to remove tasks from `map_method_serial_to_task`, but called +`send_message_with_reply_cleanup(remove = FALSE)` and erroneously didn’t +call unref an additional time. + +Try and simplify it all by setting a `GDestroyNotify` on +`map_method_serial_to_task`’s values, and making the refcount handling +of `send_message_with_reply_cleanup()` not be conditional on its +arguments. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/b84ec21f9c4c57990309e691206582c589f59770 + +--- + gio/gdbusconnection.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index 0cbfc66c13..f4bc21bb37 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -409,7 +409,7 @@ struct _GDBusConnection + GDBusConnectionFlags flags; + + /* Map used for managing method replies, protected by @lock */ +- GHashTable *map_method_serial_to_task; /* guint32 -> GTask* */ ++ GHashTable *map_method_serial_to_task; /* guint32 -> owned GTask* */ + + /* Maps used for managing signal subscription, protected by @lock */ + GHashTable *map_rule_to_signal_data; /* match rule (gchar*) -> SignalData */ +@@ -1061,7 +1061,7 @@ g_dbus_connection_init (GDBusConnection *connection) + g_mutex_init (&connection->lock); + g_mutex_init (&connection->init_lock); + +- connection->map_method_serial_to_task = g_hash_table_new (g_direct_hash, g_direct_equal); ++ connection->map_method_serial_to_task = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + + connection->map_rule_to_signal_data = g_hash_table_new (g_str_hash, + g_str_equal); +@@ -1768,7 +1768,7 @@ send_message_data_free (SendMessageData *data) + + /* ---------------------------------------------------------------------------------------------------- */ + +-/* can be called from any thread with lock held; @task is (transfer full) */ ++/* can be called from any thread with lock held; @task is (transfer none) */ + static void + send_message_with_reply_cleanup (GTask *task, gboolean remove) + { +@@ -1798,13 +1798,11 @@ send_message_with_reply_cleanup (GTask *task, gboolean remove) + GUINT_TO_POINTER (data->serial)); + g_warn_if_fail (removed); + } +- +- g_object_unref (task); + } + + /* ---------------------------------------------------------------------------------------------------- */ + +-/* Called from GDBus worker thread with lock held; @task is (transfer full). */ ++/* Called from GDBus worker thread with lock held; @task is (transfer none). */ + static void + send_message_data_deliver_reply_unlocked (GTask *task, + GDBusMessage *reply) +@@ -1822,7 +1820,7 @@ send_message_data_deliver_reply_unlocked (GTask *task, + ; + } + +-/* Called from a user thread, lock is not held; @task is (transfer full) */ ++/* Called from a user thread, lock is not held; @task is (transfer none) */ + static void + send_message_data_deliver_error (GTask *task, + GQuark domain, +@@ -1839,7 +1837,10 @@ send_message_data_deliver_error (GTask *task, + return; + } + ++ /* Hold a ref on @task as send_message_with_reply_cleanup() will remove it ++ * from the task map and could end up dropping the last reference */ + g_object_ref (task); ++ + send_message_with_reply_cleanup (task, TRUE); + CONNECTION_UNLOCK (connection); + +@@ -1855,8 +1856,7 @@ send_message_with_reply_cancelled_idle_cb (gpointer user_data) + { + GTask *task = user_data; + +- g_object_ref (task); +- send_message_data_deliver_error (g_steal_pointer (&task), G_IO_ERROR, G_IO_ERROR_CANCELLED, ++ send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_CANCELLED, + _("Operation was cancelled")); + return FALSE; + } +@@ -1886,8 +1886,7 @@ send_message_with_reply_timeout_cb (gpointer user_data) + { + GTask *task = user_data; + +- g_object_ref (task); +- send_message_data_deliver_error (g_steal_pointer (&task), G_IO_ERROR, G_IO_ERROR_TIMED_OUT, ++ send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Timeout was reached")); + return FALSE; + } +@@ -2391,7 +2390,8 @@ on_worker_message_about_to_be_sent (GDBusWorker *worker, + return message; + } + +-/* called with connection lock held, in GDBusWorker thread */ ++/* called with connection lock held, in GDBusWorker thread ++ * @key, @value and @user_data are (transfer none) */ + static gboolean + cancel_method_on_close (gpointer key, gpointer value, gpointer user_data) + { +-- +GitLab + + +From 0a84c182e28f50be2263e42e0bc21074dd523701 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Wed, 22 Feb 2023 14:55:40 +0000 +Subject: [PATCH 9/9] gdbusconnection: Improve refcount handling of timeout + source +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The ref on the timeout source owned by `SendMessageData` was being +dropped just after attaching the source to the main context, leaving it +unowned in that struct. That meant the only ref on the source was held +by the `GMainContext` it was attached to. + +This ref was dropped when returning `G_SOURCE_REMOVE` from +`send_message_with_reply_timeout_cb()`. Before that happens, +`send_message_data_deliver_error()` is called, which normally calls +`send_message_with_reply_cleanup()` and destroys the source. + +However, if `send_message_data_deliver_error()` is called when the +message has already been delivered, calling +`send_message_with_reply_cleanup()` will be skipped. This leaves the +source pointer in `SendMessageData` dangling, which will cause problems +when `g_source_destroy()` is subsequently called on it. + +I’m not sure if it’s possible in practice for this situation to occur, +but the code certainly does nothing to prevent it, and it’s easy enough +to avoid by keeping a strong ref on the source in `SendMessageData`. + +Signed-off-by: Philip Withnall + +Helps: #1264 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/0a84c182e28f50be2263e42e0bc21074dd523701 + +--- + gio/gdbusconnection.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c +index f4bc21bb37..bed1ff2841 100644 +--- a/gio/gdbusconnection.c ++++ b/gio/gdbusconnection.c +@@ -1751,7 +1751,7 @@ typedef struct + + gulong cancellable_handler_id; + +- GSource *timeout_source; ++ GSource *timeout_source; /* (owned) (nullable) */ + + gboolean delivered; + } SendMessageData; +@@ -1760,6 +1760,7 @@ typedef struct + static void + send_message_data_free (SendMessageData *data) + { ++ /* These should already have been cleared by send_message_with_reply_cleanup(). */ + g_assert (data->timeout_source == NULL); + g_assert (data->cancellable_handler_id == 0); + +@@ -1784,7 +1785,7 @@ send_message_with_reply_cleanup (GTask *task, gboolean remove) + if (data->timeout_source != NULL) + { + g_source_destroy (data->timeout_source); +- data->timeout_source = NULL; ++ g_clear_pointer (&data->timeout_source, g_source_unref); + } + if (data->cancellable_handler_id > 0) + { +@@ -1888,7 +1889,7 @@ send_message_with_reply_timeout_cb (gpointer user_data) + + send_message_data_deliver_error (task, G_IO_ERROR, G_IO_ERROR_TIMED_OUT, + _("Timeout was reached")); +- return FALSE; ++ return G_SOURCE_REMOVE; + } + + /* ---------------------------------------------------------------------------------------------------- */ +@@ -1949,7 +1950,6 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connect + data->timeout_source = g_timeout_source_new (timeout_msec); + g_task_attach_source (task, data->timeout_source, + (GSourceFunc) send_message_with_reply_timeout_cb); +- g_source_unref (data->timeout_source); + } + + g_hash_table_insert (connection->map_method_serial_to_task, +-- +GitLab \ No newline at end of file diff --git a/patch/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch b/patch/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch deleted file mode 100644 index 7f3a61025871b215c9fa213bb7586debd364b80e..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusconnection-Fix-race-between-method-calls-and-object-unregistration.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 50fbf05d61db500df9052bb682d9c01e0bf51ffb Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 10:52:41 +0100 -Subject: [PATCH] gdbusconnection: Fix race between method calls and object - unregistration - -If `g_dbus_connection_unregister_object()` (or `unregister_subtree()`) -was called from one thread, while an idle callback for a method call (or -a property get or set) was being invoked in another, it was possible for -the two to race after the idle callback had checked that the -object/subtree was registered, but before it had finished dereferencing -all the data related to that object/subtree. - -Unregistering the object/subtree would immediately free the data, -leading the idle callback to cause a use-after-free error. - -Fix that by giving the idle callback a strong reference to the data from -inside the locked section where it checks whether the object/subtree is -still registered. - -Signed-off-by: Philip Withnall - -Fixes: #2400 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/50fbf05d61db500df9052bb682d9c01e0bf51ffb - ---- - gio/gdbusconnection.c | 66 +++++++++++++++++++++++++++++++++++-------- - 1 file changed, 54 insertions(+), 12 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 71913c1ec1..e6c0b70b4e 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -4116,6 +4116,9 @@ exported_interface_unref (ExportedInterface *ei) - g_dbus_interface_info_cache_release (ei->interface_info); - g_dbus_interface_info_unref ((GDBusInterfaceInfo *) ei->interface_info); - -+ /* All uses of ei->vtable from callbacks scheduled in idle functions must -+ * have completed by this call_destroy_notify() call, as language bindings -+ * may destroy function closures in this callback. */ - call_destroy_notify (ei->context, - ei->user_data_free_func, - ei->user_data); -@@ -4157,6 +4160,9 @@ exported_subtree_unref (ExportedSubtree *es) - if (!g_atomic_int_dec_and_test (&es->refcount)) - return; - -+ /* All uses of es->vtable from callbacks scheduled in idle functions must -+ * have completed by this call_destroy_notify() call, as language bindings -+ * may destroy function closures in this callback. */ - call_destroy_notify (es->context, - es->user_data_free_func, - es->user_data); -@@ -4174,30 +4180,45 @@ exported_subtree_unref (ExportedSubtree *es) - * @subtree_registration_id (if not zero) has been unregistered. If - * so, returns %TRUE. - * -+ * If not, sets @out_ei and/or @out_es to a strong reference to the relevant -+ * #ExportedInterface/#ExportedSubtree and returns %FALSE. -+ * - * May be called by any thread. Caller must *not* hold lock. - */ - static gboolean --has_object_been_unregistered (GDBusConnection *connection, -- guint registration_id, -- guint subtree_registration_id) -+has_object_been_unregistered (GDBusConnection *connection, -+ guint registration_id, -+ ExportedInterface **out_ei, -+ guint subtree_registration_id, -+ ExportedSubtree **out_es) - { - gboolean ret; -+ ExportedInterface *ei = NULL; -+ gpointer es = NULL; - - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); - - ret = FALSE; - - CONNECTION_LOCK (connection); -- if (registration_id != 0 && g_hash_table_lookup (connection->map_id_to_ei, -- GUINT_TO_POINTER (registration_id)) == NULL) -+ -+ if (registration_id != 0) - { -- ret = TRUE; -+ ei = g_hash_table_lookup (connection->map_id_to_ei, GUINT_TO_POINTER (registration_id)); -+ if (ei == NULL) -+ ret = TRUE; -+ else if (out_ei != NULL) -+ *out_ei = exported_interface_ref (ei); - } -- else if (subtree_registration_id != 0 && g_hash_table_lookup (connection->map_id_to_es, -- GUINT_TO_POINTER (subtree_registration_id)) == NULL) -+ if (subtree_registration_id != 0) - { -- ret = TRUE; -+ es = g_hash_table_lookup (connection->map_id_to_es, GUINT_TO_POINTER (subtree_registration_id)); -+ if (es == NULL) -+ ret = TRUE; -+ else if (out_es != NULL) -+ *out_es = exported_subtree_ref (es); - } -+ - CONNECTION_UNLOCK (connection); - - return ret; -@@ -4234,10 +4255,14 @@ invoke_get_property_in_idle_cb (gpointer _data) - GVariant *value; - GError *error; - GDBusMessage *reply; -+ ExportedInterface *ei = NULL; -+ ExportedSubtree *es = NULL; - - if (has_object_been_unregistered (data->connection, - data->registration_id, -- data->subtree_registration_id)) -+ &ei, -+ data->subtree_registration_id, -+ &es)) - { - reply = g_dbus_message_new_method_error (data->message, - "org.freedesktop.DBus.Error.UnknownMethod", -@@ -4284,6 +4309,9 @@ invoke_get_property_in_idle_cb (gpointer _data) - } - - out: -+ g_clear_pointer (&ei, exported_interface_unref); -+ g_clear_pointer (&es, exported_subtree_unref); -+ - return FALSE; - } - -@@ -4581,10 +4609,14 @@ invoke_get_all_properties_in_idle_cb (gpointer _data) - GVariantBuilder builder; - GDBusMessage *reply; - guint n; -+ ExportedInterface *ei = NULL; -+ ExportedSubtree *es = NULL; - - if (has_object_been_unregistered (data->connection, - data->registration_id, -- data->subtree_registration_id)) -+ &ei, -+ data->subtree_registration_id, -+ &es)) - { - reply = g_dbus_message_new_method_error (data->message, - "org.freedesktop.DBus.Error.UnknownMethod", -@@ -4637,6 +4669,9 @@ invoke_get_all_properties_in_idle_cb (gpointer _data) - g_object_unref (reply); - - out: -+ g_clear_pointer (&ei, exported_interface_unref); -+ g_clear_pointer (&es, exported_subtree_unref); -+ - return FALSE; - } - -@@ -4946,13 +4981,17 @@ call_in_idle_cb (gpointer user_data) - GDBusInterfaceVTable *vtable; - guint registration_id; - guint subtree_registration_id; -+ ExportedInterface *ei = NULL; -+ ExportedSubtree *es = NULL; - - registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-registration-id")); - subtree_registration_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (invocation), "g-dbus-subtree-registration-id")); - - if (has_object_been_unregistered (g_dbus_method_invocation_get_connection (invocation), - registration_id, -- subtree_registration_id)) -+ &ei, -+ subtree_registration_id, -+ &es)) - { - GDBusMessage *reply; - reply = g_dbus_message_new_method_error (g_dbus_method_invocation_get_message (invocation), -@@ -4978,6 +5017,9 @@ call_in_idle_cb (gpointer user_data) - g_dbus_method_invocation_get_user_data (invocation)); - - out: -+ g_clear_pointer (&ei, exported_interface_unref); -+ g_clear_pointer (&es, exported_subtree_unref); -+ - return FALSE; - } - --- -GitLab - diff --git a/patch/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch b/patch/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch deleted file mode 100644 index 645faeb540fc7ac17e9d07ddd646d64c247c04d3..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusconnection-Fix-race-between-subtree-method-call-and-unregistration.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 117b748e44e0ec930fcb9641e3f808572d4a41f2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 10:55:10 +0100 -Subject: [PATCH] gdbusconnection: Fix race between subtree method call and - unregistration -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Fix another variant of the previous commit, this time specific to the -idle callback of a method call on a subtree object, racing with -unregistration of that subtree. - -In this case, the `process_subtree_vtable_message_in_idle_cb()` idle -callback already has a pointer to the right `ExportedSubtree` struct, -but again doesn鈥檛 have a strong reference to it. - -Signed-off-by: Philip Withnall - -Helps: #2400 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/117b748e44e0ec930fcb9641e3f808572d4a41f2 - ---- - gio/gdbusconnection.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index e6c0b70b4e..73b5b309a2 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -6824,14 +6824,15 @@ handle_subtree_method_invocation (GDBusConnection *connection, - - typedef struct - { -- GDBusMessage *message; -- ExportedSubtree *es; -+ GDBusMessage *message; /* (owned) */ -+ ExportedSubtree *es; /* (owned) */ - } SubtreeDeferredData; - - static void - subtree_deferred_data_free (SubtreeDeferredData *data) - { - g_object_unref (data->message); -+ exported_subtree_unref (data->es); - g_free (data); - } - -@@ -6890,7 +6891,7 @@ subtree_message_func (GDBusConnection *connection, - - data = g_new0 (SubtreeDeferredData, 1); - data->message = g_object_ref (message); -- data->es = es; -+ data->es = exported_subtree_ref (es); - - /* defer this call to an idle handler in the right thread */ - idle_source = g_idle_source_new (); --- -GitLab - diff --git a/patch/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch b/patch/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch deleted file mode 100644 index cbd3b3c02304469690ca58f46d1cc0ec4ae081fb..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusconnection-Make-ExportedInterface-ExportedSubtree-refcounted.patch +++ /dev/null @@ -1,136 +0,0 @@ -From c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 09:03:40 +0100 -Subject: [PATCH] gdbusconnection: Make ExportedInterface/ExportedSubtree - refcounted - -This is needed for an upcoming change which decouples their lifecycle -from their presence in the `map_id_to_ei` and `map_id_to_es` hash -tables. - -Signed-off-by: Philip Withnall - -Helps: #2400 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70 - ---- - gio/gdbusconnection.c | 42 ++++++++++++++++++++++++++++++++++++------ - 1 file changed, 36 insertions(+), 6 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index 40ce1b6fc7..71913c1ec1 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -466,7 +466,8 @@ typedef struct ExportedObject ExportedObject; - static void exported_object_free (ExportedObject *eo); - - typedef struct ExportedSubtree ExportedSubtree; --static void exported_subtree_free (ExportedSubtree *es); -+static ExportedSubtree *exported_subtree_ref (ExportedSubtree *es); -+static void exported_subtree_unref (ExportedSubtree *es); - - enum - { -@@ -1096,7 +1097,7 @@ g_dbus_connection_init (GDBusConnection *connection) - connection->map_object_path_to_es = g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, -- (GDestroyNotify) exported_subtree_free); -+ (GDestroyNotify) exported_subtree_unref); - - connection->map_id_to_es = g_hash_table_new (g_direct_hash, - g_direct_equal); -@@ -4085,6 +4086,8 @@ typedef struct - { - ExportedObject *eo; - -+ gint refcount; /* (atomic) */ -+ - guint id; - gchar *interface_name; /* (owned) */ - GDBusInterfaceVTable *vtable; /* (owned) */ -@@ -4095,10 +4098,21 @@ typedef struct - GDestroyNotify user_data_free_func; - } ExportedInterface; - --/* called with lock held */ -+static ExportedInterface * -+exported_interface_ref (ExportedInterface *ei) -+{ -+ g_atomic_int_inc (&ei->refcount); -+ -+ return ei; -+} -+ -+/* May be called with lock held */ - static void --exported_interface_free (ExportedInterface *ei) -+exported_interface_unref (ExportedInterface *ei) - { -+ if (!g_atomic_int_dec_and_test (&ei->refcount)) -+ return; -+ - g_dbus_interface_info_cache_release (ei->interface_info); - g_dbus_interface_info_unref ((GDBusInterfaceInfo *) ei->interface_info); - -@@ -4115,6 +4129,8 @@ exported_interface_free (ExportedInterface *ei) - - struct ExportedSubtree - { -+ gint refcount; /* (atomic) */ -+ - guint id; - gchar *object_path; /* (owned) */ - GDBusConnection *connection; /* (unowned) */ -@@ -4126,9 +4142,21 @@ struct ExportedSubtree - GDestroyNotify user_data_free_func; - }; - -+static ExportedSubtree * -+exported_subtree_ref (ExportedSubtree *es) -+{ -+ g_atomic_int_inc (&es->refcount); -+ -+ return es; -+} -+ -+/* May be called with lock held */ - static void --exported_subtree_free (ExportedSubtree *es) -+exported_subtree_unref (ExportedSubtree *es) - { -+ if (!g_atomic_int_dec_and_test (&es->refcount)) -+ return; -+ - call_destroy_notify (es->context, - es->user_data_free_func, - es->user_data); -@@ -5251,7 +5279,7 @@ g_dbus_connection_register_object (GDBusConnection *connection, - eo->map_if_name_to_ei = g_hash_table_new_full (g_str_hash, - g_str_equal, - NULL, -- (GDestroyNotify) exported_interface_free); -+ (GDestroyNotify) exported_interface_unref); - g_hash_table_insert (connection->map_object_path_to_eo, eo->object_path, eo); - } - -@@ -5268,6 +5296,7 @@ g_dbus_connection_register_object (GDBusConnection *connection, - } - - ei = g_new0 (ExportedInterface, 1); -+ ei->refcount = 1; - ei->id = (guint) g_atomic_int_add (&_global_registration_id, 1); /* TODO: overflow etc. */ - ei->eo = eo; - ei->user_data = user_data; -@@ -6924,6 +6953,7 @@ g_dbus_connection_register_subtree (GDBusConnection *connection, - } - - es = g_new0 (ExportedSubtree, 1); -+ es->refcount = 1; - es->object_path = g_strdup (object_path); - es->connection = connection; - --- -GitLab diff --git a/patch/backport-gdbusconnection-Move-ExportedSubtree-definition.patch b/patch/backport-gdbusconnection-Move-ExportedSubtree-definition.patch deleted file mode 100644 index cb8b926fcf4af2c729d82fdf54bb7304d44595c2..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusconnection-Move-ExportedSubtree-definition.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 310f2c1632e05c4f32be033c009642012741d876 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 24 Sep 2021 08:28:19 +0100 -Subject: [PATCH] gdbusconnection: Move ExportedSubtree definition - -Move it further up the file, but make no changes to it. This will help -with a subsequent commit. - -Signed-off-by: Philip Withnall - -Helps: #2400 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/310f2c1632e05c4f32be033c009642012741d876 - ---- - gio/gdbusconnection.c | 54 +++++++++++++++++++++---------------------- - 1 file changed, 27 insertions(+), 27 deletions(-) - -diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c -index d730111f8b..24a50fcf20 100644 ---- a/gio/gdbusconnection.c -+++ b/gio/gdbusconnection.c -@@ -4113,6 +4113,33 @@ exported_interface_free (ExportedInterface *ei) - g_free (ei); - } - -+struct ExportedSubtree -+{ -+ guint id; -+ gchar *object_path; -+ GDBusConnection *connection; -+ GDBusSubtreeVTable *vtable; -+ GDBusSubtreeFlags flags; -+ -+ GMainContext *context; -+ gpointer user_data; -+ GDestroyNotify user_data_free_func; -+}; -+ -+static void -+exported_subtree_free (ExportedSubtree *es) -+{ -+ call_destroy_notify (es->context, -+ es->user_data_free_func, -+ es->user_data); -+ -+ g_main_context_unref (es->context); -+ -+ _g_dbus_subtree_vtable_free (es->vtable); -+ g_free (es->object_path); -+ g_free (es); -+} -+ - /* ---------------------------------------------------------------------------------------------------- */ - - /* Convenience function to check if @registration_id (if not zero) or -@@ -6401,33 +6428,6 @@ g_dbus_connection_call_with_unix_fd_list_sync (GDBusConnection *connection, - - /* ---------------------------------------------------------------------------------------------------- */ - --struct ExportedSubtree --{ -- guint id; -- gchar *object_path; -- GDBusConnection *connection; -- GDBusSubtreeVTable *vtable; -- GDBusSubtreeFlags flags; -- -- GMainContext *context; -- gpointer user_data; -- GDestroyNotify user_data_free_func; --}; -- --static void --exported_subtree_free (ExportedSubtree *es) --{ -- call_destroy_notify (es->context, -- es->user_data_free_func, -- es->user_data); -- -- g_main_context_unref (es->context); -- -- _g_dbus_subtree_vtable_free (es->vtable); -- g_free (es->object_path); -- g_free (es); --} -- - /* called without lock held in the thread where the caller registered - * the subtree - */ --- -GitLab - diff --git a/patch/backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch b/patch/backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch index 7ef0b757ca27bdb63fc8058dd9a0d14e7f729bea..666153caefedb3cadf414e1913610789edc0f708 100644 --- a/patch/backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch +++ b/patch/backport-gdbusinterfaceskeleton-Fix-a-use-after-free-of-a-GDBusMethodInvocation.patch @@ -175,7 +175,7 @@ index d938f71b99..da6b66f2ec 100644 - invocation, + g_steal_pointer (&invocation), g_object_unref); - g_source_set_name (idle_source, "[gio, " __FILE__ "] call_in_idle_cb"); + g_source_set_static_name (idle_source, "[gio, " __FILE__ "] call_in_idle_cb"); g_source_attach (idle_source, main_context); -- GitLab diff --git a/patch/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch b/patch/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch deleted file mode 100644 index 5e1a82d2dfd632acbf03080fa7b7fc6408d7a94e..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusmessage-Disallow-zero-length-elements-in-arrays.patch +++ /dev/null @@ -1,53 +0,0 @@ -From c74177337dae7b06383261b2bedabf1f12d816b5 Mon Sep 17 00:00:00 2001 -From: Sebastian Wilhelmi -Date: Thu, 6 Jan 2022 20:57:49 +0000 -Subject: [PATCH] gdbusmessage: Disallow zero-length elements in arrays -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -They are not allowed in the specification, and can lead to infinite -loops when parsing. - -That鈥檚 a security issue if your application is accepting D-Bus messages -from untrusted peers (perhaps in a peer-to-peer connection). It鈥檚 not -exploitable when your application is connected to a bus (such as the -system or session buses), as the bus daemons (dbus-daemon or -dbus-broker) filter out such broken messages and don鈥檛 forward them. - -Arrays of zero-length elements are disallowed in the D-Bus -specification: https://dbus.freedesktop.org/doc/dbus-specification.html#container-types - -oss-fuzz#41428, #41435 -Fixes: #2557 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c74177337dae7b06383261b2bedabf1f12d816b5 - ---- - gio/gdbusmessage.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c -index 4056bc2c4a..ecef6cd3c5 100644 ---- a/gio/gdbusmessage.c -+++ b/gio/gdbusmessage.c -@@ -1839,6 +1839,16 @@ parse_value_from_blob (GMemoryBuffer *buf, - } - g_variant_builder_add_value (&builder, item); - g_variant_unref (item); -+ -+ /* Array elements must not be zero-length. There are no -+ * valid zero-length serialisations of any types which -+ * can be array elements in the D-Bus wire format, so this -+ * assertion should always hold. -+ * -+ * See https://gitlab.gnome.org/GNOME/glib/-/issues/2557 -+ */ -+ g_assert (buf->pos > (gsize) offset); -+ - offset = buf->pos; - } - } --- -GitLab diff --git a/patch/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch b/patch/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch deleted file mode 100644 index 937835b09a42675e8d93e921022d3c57cd8eace8..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusmethodinvocation-Drop-redundant-quote-from-warning.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7143457076d6469f76185a2f1d7071aca40a591e Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 17 Mar 2022 19:03:15 +0000 -Subject: [PATCH] gdbusmethodinvocation: Drop redundant quote from warning - message - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7143457076d6469f76185a2f1d7071aca40a591e - ---- - gio/gdbusmethodinvocation.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c -index 8e7abc83c4..705af079f4 100644 ---- a/gio/gdbusmethodinvocation.c -+++ b/gio/gdbusmethodinvocation.c -@@ -413,7 +413,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - { - gchar *type_string = g_variant_type_dup_string (type); - -- g_warning ("Type of return value is incorrect: expected '%s', got '%s''", -+ g_warning ("Type of return value is incorrect: expected '%s', got '%s'", - type_string, g_variant_get_type_string (parameters)); - g_variant_type_free (type); - g_free (type_string); --- -GitLab diff --git a/patch/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch b/patch/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch deleted file mode 100644 index 4259891e45308bb2998f14cd9af07a465e23bc24..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusmethodinvocation-Fix-a-leak-on-an-early-return-path.patch +++ /dev/null @@ -1,66 +0,0 @@ -From a3b8846e54c7132056411605f815b67e831833d2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 17 Mar 2022 19:04:42 +0000 -Subject: [PATCH] gdbusmethodinvocation: Fix a leak on an early return path - -When doing an early return from `g_dbus_method_invocation_return_*()` -due to passing in the wrong type (or no return value when one was -expected), the parameters were not correctly sunk and were leaked. - -Fix that. A unit test will be added in a following commit. - -Signed-off-by: Philip Withnall - -Coverity CID: #1474536 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a3b8846e54c7132056411605f815b67e831833d2 - ---- - gio/gdbusmethodinvocation.c | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c -index c22e19ef0d..c15d83ec84 100644 ---- a/gio/gdbusmethodinvocation.c -+++ b/gio/gdbusmethodinvocation.c -@@ -397,14 +397,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - g_return_if_fail ((parameters == NULL) || g_variant_is_of_type (parameters, G_VARIANT_TYPE_TUPLE)); - - if (g_dbus_message_get_flags (invocation->message) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED) -- { -- if (parameters != NULL) -- { -- g_variant_ref_sink (parameters); -- g_variant_unref (parameters); -- } -- goto out; -- } -+ goto out; - - if (parameters == NULL) - parameters = g_variant_new_tuple (NULL, 0); -@@ -508,7 +501,7 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - } - - reply = g_dbus_message_new_method_reply (invocation->message); -- g_dbus_message_set_body (reply, parameters); -+ g_dbus_message_set_body (reply, g_steal_pointer (¶meters)); - - #ifdef G_OS_UNIX - if (fd_list != NULL) -@@ -525,6 +518,12 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - g_object_unref (reply); - - out: -+ if (parameters != NULL) -+ { -+ g_variant_ref_sink (parameters); -+ g_variant_unref (parameters); -+ } -+ - g_object_unref (invocation); - } - --- -GitLab diff --git a/patch/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch b/patch/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch deleted file mode 100644 index 6994562567c7c5b2a24bd66ad0235cf37d6ffbf6..0000000000000000000000000000000000000000 --- a/patch/backport-gdbusmethodinvocation-Fix-dead-code-for-type-checking-GetAll.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 76f5460107c86a44be6387c159b34ae50aa1e623 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 17 Mar 2022 18:32:46 +0000 -Subject: [PATCH] gdbusmethodinvocation: Fix dead code for type checking GetAll - -`property_info` is only ever set for `Get` and `Set` calls, not for -`GetAll`, as it only represents a single property. So this code was -never reachable. - -Move it out so that it is reachable. - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/76f5460107c86a44be6387c159b34ae50aa1e623 - ---- - gio/gdbusmethodinvocation.c | 34 ++++++++++++++++++---------------- - 1 file changed, 18 insertions(+), 16 deletions(-) - -diff --git a/gio/gdbusmethodinvocation.c b/gio/gdbusmethodinvocation.c -index c15d83ec84..8e7abc83c4 100644 ---- a/gio/gdbusmethodinvocation.c -+++ b/gio/gdbusmethodinvocation.c -@@ -424,7 +424,9 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - - /* property_info is only non-NULL if set that way from - * GDBusConnection, so this must be the case of async property -- * handling on either 'Get', 'Set' or 'GetAll'. -+ * handling on either 'Get' or 'Set'. -+ * -+ * property_info is NULL for 'GetAll'. - */ - if (invocation->property_info != NULL) - { -@@ -454,21 +456,6 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - g_variant_unref (nested); - } - -- else if (g_str_equal (invocation->method_name, "GetAll")) -- { -- if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) -- { -- g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", -- g_variant_get_type_string (parameters)); -- goto out; -- } -- -- /* Could iterate the list of properties and make sure that all -- * of them are actually on the interface and with the correct -- * types, but let's not do that for now... -- */ -- } -- - else if (g_str_equal (invocation->method_name, "Set")) - { - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE_UNIT)) -@@ -482,6 +469,21 @@ g_dbus_method_invocation_return_value_internal (GDBusMethodInvocation *invocatio - else - g_assert_not_reached (); - } -+ else if (g_str_equal (invocation->interface_name, "org.freedesktop.DBus.Properties") && -+ g_str_equal (invocation->method_name, "GetAll")) -+ { -+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) -+ { -+ g_warning ("Type of return value for property 'GetAll' call should be '(a{sv})' but got '%s'", -+ g_variant_get_type_string (parameters)); -+ goto out; -+ } -+ -+ /* Could iterate the list of properties and make sure that all -+ * of them are actually on the interface and with the correct -+ * types, but let's not do that for now... -+ */ -+ } - - if (G_UNLIKELY (_g_dbus_debug_return ())) - { --- -GitLab diff --git a/patch/backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch b/patch/backport-gdbusobjectmanagerservice-fix-leak-in-error-path.patch deleted file mode 100644 index 79cf015c01479a7944d18693ff34ac82d2689ea0..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch b/patch/backport-gdtlsconnection-Fix-a-check-for-a-vfunc-being-implemented.patch deleted file mode 100644 index 99ba4614c46ed047a5bb1a9bafa73c915c39f426..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gfileenumerator-fix-leak-in-error-path.patch b/patch/backport-gfileenumerator-fix-leak-in-error-path.patch deleted file mode 100644 index ddfe7fcaf76bc7c794f4600c130a158d20a45a99..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gio-tool-Fix-a-minor-memory-leak.patch b/patch/backport-gio-tool-Fix-a-minor-memory-leak.patch deleted file mode 100644 index 6684613770468731582ea64c5bc5316121299264..0000000000000000000000000000000000000000 --- a/patch/backport-gio-tool-Fix-a-minor-memory-leak.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Wed, 27 Apr 2022 15:01:08 +0100 -Subject: [PATCH] gio-tool: Fix a minor memory leak when using gio-set with - bytestrings -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Tested using: -```sh -touch ~/foo -gio set ~/foo -t bytestring user::test "\x00\x00" -``` -(it doesn鈥檛 matter that this fails; the bytestring is still decoded) - -Signed-off-by: Philip Withnall - -Coverity CID: #1474407 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3 - ---- - gio/gio-tool-set.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/gio/gio-tool-set.c b/gio/gio-tool-set.c -index 4dbe1214ff..c2a9431f61 100644 ---- a/gio/gio-tool-set.c -+++ b/gio/gio-tool-set.c -@@ -76,12 +76,14 @@ handle_set (int argc, char *argv[], gboolean do_help) - const char *attribute; - GFileAttributeType type; - gpointer value; -+ gpointer value_allocated = NULL; - gboolean b; - guint32 uint32; - gint32 int32; - guint64 uint64; - gint64 int64; - gchar *param; -+ int retval = 0; - - g_set_prgname ("gio set"); - -@@ -147,7 +149,7 @@ handle_set (int argc, char *argv[], gboolean do_help) - value = argv[3]; - break; - case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING: -- value = hex_unescape (argv[3]); -+ value = value_allocated = hex_unescape (argv[3]); - break; - case G_FILE_ATTRIBUTE_TYPE_BOOLEAN: - b = g_ascii_strcasecmp (argv[3], "true") == 0; -@@ -194,11 +196,11 @@ handle_set (int argc, char *argv[], gboolean do_help) - { - print_error ("%s", error->message); - g_error_free (error); -- g_object_unref (file); -- return 1; -+ retval = 1; - } - -+ g_clear_pointer (&value_allocated, g_free); - g_object_unref (file); - -- return 0; -+ return retval; - } --- -GitLab diff --git a/patch/backport-giochannel-Add-G_IO_FLAG_NONE.patch b/patch/backport-giochannel-Add-G_IO_FLAG_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f671e050baf98c5d45460305022d15a29a24b32 --- /dev/null +++ b/patch/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/patch/backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch b/patch/backport-gioenums-Add-G_TLS_CERTIFICATE_FLAGS_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..9603aeca1794cab6b65c6a1f365df1412f342ba3 --- /dev/null +++ b/patch/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/patch/backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch b/patch/backport-giomodule-test-Dont-pass-a-magic-number-to-g_test_trap_subprocess.patch new file mode 100644 index 0000000000000000000000000000000000000000..d52ad634a65b7bf6d53c78379291b08d61664821 --- /dev/null +++ b/patch/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/patch/backport-gkeyfile-Ensure-we-don-t-add-extra-blank-line-above-new-group.patch b/patch/backport-gkeyfile-Ensure-we-don-t-add-extra-blank-line-above-new-group.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8d0080cc4191ce79c153828b85ab7bc1dc7d813 --- /dev/null +++ b/patch/backport-gkeyfile-Ensure-we-don-t-add-extra-blank-line-above-new-group.patch @@ -0,0 +1,59 @@ +From c49502582faedecc7020155d95b16c7a1d78d432 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= +Date: Thu, 13 Jul 2023 10:06:21 +0200 +Subject: [PATCH] gkeyfile: Ensure we don't add extra blank line above new + group + +A forgotten edge case in 86b4b045: when the last value of the last group +has been added via g_key_file_set_value() and it contains line breaks. +The best we can do in this case is probably to do nothing. + +Closes: #3047 +Fixes: 86b4b0453ea3a814167d4a5f7a4031d467543716 +--- + glib/gkeyfile.c | 6 +++++- + glib/tests/keyfile.c | 10 ++++++++++ + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 145136706f..0e21ab4f14 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -3858,8 +3858,12 @@ g_key_file_add_group (GKeyFile *key_file, + { + /* separate groups by a blank line if we don't keep comments or group is created */ + GKeyFileGroup *next_group = key_file->groups->next->data; ++ GKeyFileKeyValuePair *pair; ++ if (next_group->key_value_pairs != NULL) ++ pair = next_group->key_value_pairs->data; ++ + if (next_group->key_value_pairs == NULL || +- ((GKeyFileKeyValuePair *) next_group->key_value_pairs->data)->key != NULL) ++ (pair->key != NULL && !g_strstr_len (pair->value, -1, "\n"))) + { + GKeyFileKeyValuePair *pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = NULL; +diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c +index d3eed29841..80cdc93d8f 100644 +--- a/glib/tests/keyfile.c ++++ b/glib/tests/keyfile.c +@@ -480,6 +480,16 @@ test_comments (void) + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); + g_assert_null (comment); + ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3047"); ++ ++ /* check if we don't add a blank line above new group if last value of preceding ++ * group was added via g_key_file_set_value() and contains line breaks */ ++ g_key_file_set_value (keyfile, "group4", "key1", "value1\n\n# group comment"); ++ g_key_file_set_string (keyfile, "group5", "key1", "value1"); ++ comment = g_key_file_get_comment (keyfile, "group5", NULL, &error); ++ check_no_error (&error); ++ g_assert_null (comment); ++ + g_key_file_free (keyfile); + } + +-- +GitLab + diff --git a/patch/backport-gkeyfile-Fix-group-comment-management.patch b/patch/backport-gkeyfile-Fix-group-comment-management.patch new file mode 100644 index 0000000000000000000000000000000000000000..dbde22278f3941144885190598674938af612cbc --- /dev/null +++ b/patch/backport-gkeyfile-Fix-group-comment-management.patch @@ -0,0 +1,536 @@ +From f74589f53041abff29d538a5d9884c3202f2c00a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= +Date: Thu, 20 Apr 2023 16:52:19 +0200 +Subject: [PATCH 1/2] gkeyfile: Replace g_slice_*() with + g_new*()/g_free_sized() + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/f74589f53041abff29d538a5d9884c3202f2c00a + +--- + glib/gkeyfile.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 9a4821bc5a..d76335653f 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -638,7 +638,7 @@ G_DEFINE_QUARK (g-key-file-error-quark, g_key_file_error) + static void + g_key_file_init (GKeyFile *key_file) + { +- key_file->current_group = g_slice_new0 (GKeyFileGroup); ++ key_file->current_group = g_new0 (GKeyFileGroup, 1); + key_file->groups = g_list_prepend (NULL, key_file->current_group); + key_file->group_hash = NULL; + key_file->start_group = NULL; +@@ -700,7 +700,7 @@ g_key_file_new (void) + { + GKeyFile *key_file; + +- key_file = g_slice_new0 (GKeyFile); ++ key_file = g_new0 (GKeyFile, 1); + key_file->ref_count = 1; + g_key_file_init (key_file); + +@@ -1205,7 +1205,7 @@ g_key_file_free (GKeyFile *key_file) + g_key_file_clear (key_file); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) +- g_slice_free (GKeyFile, key_file); ++ g_free_sized (key_file, sizeof (GKeyFile)); + else + g_key_file_init (key_file); + } +@@ -1227,7 +1227,7 @@ g_key_file_unref (GKeyFile *key_file) + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + { + g_key_file_clear (key_file); +- g_slice_free (GKeyFile, key_file); ++ g_free_sized (key_file, sizeof (GKeyFile)); + } + } + +@@ -1317,7 +1317,7 @@ g_key_file_parse_comment (GKeyFile *key_file, + + g_warn_if_fail (key_file->current_group != NULL); + +- pair = g_slice_new (GKeyFileKeyValuePair); ++ pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = NULL; + pair->value = g_strndup (line, length); + +@@ -1442,7 +1442,7 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file, + { + GKeyFileKeyValuePair *pair; + +- pair = g_slice_new (GKeyFileKeyValuePair); ++ pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = g_steal_pointer (&key); + pair->value = g_strndup (value_start, value_len); + +@@ -3339,7 +3339,7 @@ g_key_file_set_key_comment (GKeyFile *key_file, + + /* Now we can add our new comment + */ +- pair = g_slice_new (GKeyFileKeyValuePair); ++ pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + +@@ -3383,7 +3383,7 @@ g_key_file_set_group_comment (GKeyFile *key_file, + + /* Now we can add our new comment + */ +- group->comment = g_slice_new (GKeyFileKeyValuePair); ++ group->comment = g_new (GKeyFileKeyValuePair, 1); + group->comment->key = NULL; + group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); + +@@ -3416,7 +3416,7 @@ g_key_file_set_top_comment (GKeyFile *key_file, + if (comment == NULL) + return TRUE; + +- pair = g_slice_new (GKeyFileKeyValuePair); ++ pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + +@@ -3840,7 +3840,7 @@ g_key_file_add_group (GKeyFile *key_file, + return; + } + +- group = g_slice_new0 (GKeyFileGroup); ++ group = g_new0 (GKeyFileGroup, 1); + group->name = g_strdup (group_name); + group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); + key_file->groups = g_list_prepend (key_file->groups, group); +@@ -3862,7 +3862,7 @@ g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair) + { + g_free (pair->key); + g_free (pair->value); +- g_slice_free (GKeyFileKeyValuePair, pair); ++ g_free_sized (pair, sizeof (GKeyFileKeyValuePair)); + } + } + +@@ -3971,7 +3971,7 @@ g_key_file_remove_group_node (GKeyFile *key_file, + } + + g_free ((gchar *) group->name); +- g_slice_free (GKeyFileGroup, group); ++ g_free_sized (group, sizeof (GKeyFileGroup)); + g_list_free_1 (group_node); + } + +@@ -4031,7 +4031,7 @@ g_key_file_add_key (GKeyFile *key_file, + { + GKeyFileKeyValuePair *pair; + +- pair = g_slice_new (GKeyFileKeyValuePair); ++ pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = g_strdup (key); + pair->value = g_strdup (value); + +-- +GitLab + + +From 86b4b0453ea3a814167d4a5f7a4031d467543716 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= +Date: Fri, 14 Apr 2023 19:40:30 +0200 +Subject: [PATCH 2/2] gkeyfile: Fix group comment management + +This removes the `comment` member of the GKeyFileGroup structure, which +seemed intended to distinguish comments just above a group from comments +above them, separated by one or more blank lines. Indeed: +* This does not seem to match any specification in the documentation, + where blank lines and lines starting with `#` are indiscriminately + considered comments. In particular, no distinction is made between the + comment above the first group and the comment at the beginning of the + file. +* This distinction was only half implemented, resulting in confusion + between comment above a group and comment at the end of the preceding + group. + +Instead, the same logic is used for groups as for keys: the comment +above a group is simply the sequence of key-value pairs of the preceding +group where the key is null, starting from the bottom. + +The addition of a blank line above groups when writing, involved in +bugs #104 and #2927, is kept, but: +* It is now added as a comment as soon as the group is added (since a + blank line is considered a comment), so that + `g_key_file_get_comment()` returns the correct result right away. +* It is always added if comments are not kept. +* Otherwise it is only added if the group is newly created (not present + in the original data), in order to really keep comments (existing and + not existing). + +Closes: #104, #2927 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/86b4b0453ea3a814167d4a5f7a4031d467543716 + +--- + glib/gkeyfile.c | 137 +++++++++++++++++++++++-------------------- + glib/tests/keyfile.c | 75 ++++++++++++++++++++++- + 2 files changed, 147 insertions(+), 65 deletions(-) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index d76335653f..1fcef9fc91 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -529,8 +529,6 @@ struct _GKeyFileGroup + { + const gchar *name; /* NULL for above first group (which will be comments) */ + +- GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ +- + GList *key_value_pairs; + + /* Used in parallel with key_value_pairs for +@@ -579,7 +577,8 @@ static void g_key_file_add_key (GKeyFile + const gchar *key, + const gchar *value); + static void g_key_file_add_group (GKeyFile *key_file, +- const gchar *group_name); ++ const gchar *group_name, ++ gboolean created); + static gboolean g_key_file_is_group_name (const gchar *name); + static gboolean g_key_file_is_key_name (const gchar *name, + gsize len); +@@ -1354,7 +1353,7 @@ g_key_file_parse_group (GKeyFile *key_file, + return; + } + +- g_key_file_add_group (key_file, group_name); ++ g_key_file_add_group (key_file, group_name, FALSE); + g_free (group_name); + } + +@@ -1610,14 +1609,6 @@ g_key_file_to_data (GKeyFile *key_file, + + group = (GKeyFileGroup *) group_node->data; + +- /* separate groups by at least an empty line */ +- if (data_string->len >= 2 && +- data_string->str[data_string->len - 2] != '\n') +- g_string_append_c (data_string, '\n'); +- +- if (group->comment != NULL) +- g_string_append_printf (data_string, "%s\n", group->comment->value); +- + if (group->name != NULL) + g_string_append_printf (data_string, "[%s]\n", group->name); + +@@ -1902,7 +1893,7 @@ g_key_file_set_value (GKeyFile *key_file, + + if (!group) + { +- g_key_file_add_group (key_file, group_name); ++ g_key_file_add_group (key_file, group_name, TRUE); + group = (GKeyFileGroup *) key_file->groups->data; + + g_key_file_add_key (key_file, group, key, value); +@@ -3349,6 +3340,42 @@ g_key_file_set_key_comment (GKeyFile *key_file, + return TRUE; + } + ++static gboolean ++g_key_file_set_top_comment (GKeyFile *key_file, ++ const gchar *comment, ++ GError **error) ++{ ++ GList *group_node; ++ GKeyFileGroup *group; ++ GKeyFileKeyValuePair *pair; ++ ++ /* The last group in the list should be the top (comments only) ++ * group in the file ++ */ ++ g_warn_if_fail (key_file->groups != NULL); ++ group_node = g_list_last (key_file->groups); ++ group = (GKeyFileGroup *) group_node->data; ++ g_warn_if_fail (group->name == NULL); ++ ++ /* Note all keys must be comments at the top of ++ * the file, so we can just free it all. ++ */ ++ g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); ++ group->key_value_pairs = NULL; ++ ++ if (comment == NULL) ++ return TRUE; ++ ++ pair = g_new (GKeyFileKeyValuePair, 1); ++ pair->key = NULL; ++ pair->value = g_key_file_parse_comment_as_value (key_file, comment); ++ ++ group->key_value_pairs = ++ g_list_prepend (group->key_value_pairs, pair); ++ ++ return TRUE; ++} ++ + static gboolean + g_key_file_set_group_comment (GKeyFile *key_file, + const gchar *group_name, +@@ -3356,6 +3383,8 @@ g_key_file_set_group_comment (GKeyFile *key_file, + GError **error) + { + GKeyFileGroup *group; ++ GList *group_node; ++ GKeyFileKeyValuePair *pair; + + g_return_val_if_fail (group_name != NULL && g_key_file_is_group_name (group_name), FALSE); + +@@ -3370,12 +3399,22 @@ g_key_file_set_group_comment (GKeyFile *key_file, + return FALSE; + } + ++ if (group == key_file->start_group) ++ return g_key_file_set_top_comment (key_file, comment, error); ++ + /* First remove any existing comment + */ +- if (group->comment) ++ group_node = g_key_file_lookup_group_node (key_file, group_name); ++ group = group_node->next->data; ++ for (GList *lp = group->key_value_pairs; lp != NULL; ) + { +- g_key_file_key_value_pair_free (group->comment); +- group->comment = NULL; ++ GList *lnext = lp->next; ++ pair = lp->data; ++ if (pair->key != NULL) ++ break; ++ ++ g_key_file_remove_key_value_pair_node (key_file, group, lp); ++ lp = lnext; + } + + if (comment == NULL) +@@ -3383,45 +3422,10 @@ g_key_file_set_group_comment (GKeyFile *key_file, + + /* Now we can add our new comment + */ +- group->comment = g_new (GKeyFileKeyValuePair, 1); +- group->comment->key = NULL; +- group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); +- +- return TRUE; +-} +- +-static gboolean +-g_key_file_set_top_comment (GKeyFile *key_file, +- const gchar *comment, +- GError **error) +-{ +- GList *group_node; +- GKeyFileGroup *group; +- GKeyFileKeyValuePair *pair; +- +- /* The last group in the list should be the top (comments only) +- * group in the file +- */ +- g_warn_if_fail (key_file->groups != NULL); +- group_node = g_list_last (key_file->groups); +- group = (GKeyFileGroup *) group_node->data; +- g_warn_if_fail (group->name == NULL); +- +- /* Note all keys must be comments at the top of +- * the file, so we can just free it all. +- */ +- g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); +- group->key_value_pairs = NULL; +- +- if (comment == NULL) +- return TRUE; +- + pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); +- +- group->key_value_pairs = +- g_list_prepend (group->key_value_pairs, pair); ++ group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); + + return TRUE; + } +@@ -3629,9 +3633,6 @@ g_key_file_get_group_comment (GKeyFile *key_file, + return NULL; + } + +- if (group->comment) +- return g_strdup (group->comment->value); +- + group_node = g_key_file_lookup_group_node (key_file, group_name); + group_node = group_node->next; + group = (GKeyFileGroup *)group_node->data; +@@ -3826,7 +3827,8 @@ g_key_file_has_key (GKeyFile *key_file, + + static void + g_key_file_add_group (GKeyFile *key_file, +- const gchar *group_name) ++ const gchar *group_name, ++ gboolean created) + { + GKeyFileGroup *group; + +@@ -3847,7 +3849,22 @@ g_key_file_add_group (GKeyFile *key_file, + key_file->current_group = group; + + if (key_file->start_group == NULL) +- key_file->start_group = group; ++ { ++ key_file->start_group = group; ++ } ++ else if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS) || created) ++ { ++ /* separate groups by a blank line if we don't keep comments or group is created */ ++ GKeyFileGroup *next_group = key_file->groups->next->data; ++ if (next_group->key_value_pairs == NULL || ++ ((GKeyFileKeyValuePair *) next_group->key_value_pairs->data)->key != NULL) ++ { ++ GKeyFileKeyValuePair *pair = g_new (GKeyFileKeyValuePair, 1); ++ pair->key = NULL; ++ pair->value = g_strdup (""); ++ next_group->key_value_pairs = g_list_prepend (next_group->key_value_pairs, pair); ++ } ++ } + + if (!key_file->group_hash) + key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); +@@ -3958,12 +3975,6 @@ g_key_file_remove_group_node (GKeyFile *key_file, + + g_warn_if_fail (group->key_value_pairs == NULL); + +- if (group->comment) +- { +- g_key_file_key_value_pair_free (group->comment); +- group->comment = NULL; +- } +- + if (group->lookup_map) + { + g_hash_table_destroy (group->lookup_map); +diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c +index 3d72d9670e..d3eed29841 100644 +--- a/glib/tests/keyfile.c ++++ b/glib/tests/keyfile.c +@@ -382,7 +382,9 @@ test_comments (void) + "key4 = value4\n" + "# group comment\n" + "# group comment, continued\n" +- "[group2]\n"; ++ "[group2]\n\n" ++ "[group3]\n" ++ "[group4]\n"; + + const gchar *top_comment = " top comment\n top comment, continued"; + const gchar *group_comment = " group comment\n group comment, continued"; +@@ -427,6 +429,12 @@ test_comments (void) + check_name ("top comment", comment, top_comment, 0); + g_free (comment); + ++ g_key_file_remove_comment (keyfile, NULL, NULL, &error); ++ check_no_error (&error); ++ comment = g_key_file_get_comment (keyfile, NULL, NULL, &error); ++ check_no_error (&error); ++ g_assert_null (comment); ++ + comment = g_key_file_get_comment (keyfile, "group1", "key2", &error); + check_no_error (&error); + check_name ("key comment", comment, key_comment, 0); +@@ -448,7 +456,25 @@ test_comments (void) + check_name ("group comment", comment, group_comment, 0); + g_free (comment); + ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/104"); ++ ++ /* check if comments above another group than the first one are properly removed */ ++ g_key_file_remove_comment (keyfile, "group2", NULL, &error); ++ check_no_error (&error); ++ comment = g_key_file_get_comment (keyfile, "group2", NULL, &error); ++ check_no_error (&error); ++ g_assert_null (comment); ++ + comment = g_key_file_get_comment (keyfile, "group3", NULL, &error); ++ check_no_error (&error); ++ check_name ("group comment", comment, "", 0); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "group4", NULL, &error); ++ check_no_error (&error); ++ g_assert_null (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "group5", NULL, &error); + check_error (&error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND); +@@ -1321,9 +1347,16 @@ test_reload_idempotency (void) + "[fifth]\n"; + GKeyFile *keyfile; + GError *error = NULL; +- gchar *data1, *data2; ++ gchar *data1, *data2, *comment; + gsize len1, len2; + ++ const gchar *key_comment = " A random comment in the first group"; ++ const gchar *top_comment = " Top comment\n\n First comment"; ++ const gchar *group_comment_1 = top_comment; ++ const gchar *group_comment_2 = " Second comment - one line"; ++ const gchar *group_comment_3 = " Third comment - two lines\n Third comment - two lines"; ++ const gchar *group_comment_4 = "\n"; ++ + g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=420686"); + + /* check that we only insert a single new line between groups */ +@@ -1347,6 +1380,44 @@ test_reload_idempotency (void) + + data2 = g_key_file_to_data (keyfile, &len2, &error); + g_assert_nonnull (data2); ++ ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2927"); ++ ++ /* check if comments are preserved on reload */ ++ comment = g_key_file_get_comment (keyfile, "first", "anotherkey", &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, key_comment); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, NULL, NULL, &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, top_comment); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "first", NULL, &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, group_comment_1); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "second", NULL, &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, group_comment_2); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "third", NULL, &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, group_comment_3); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "fourth", NULL, &error); ++ check_no_error (&error); ++ g_assert_cmpstr (comment, ==, group_comment_4); ++ g_free (comment); ++ ++ comment = g_key_file_get_comment (keyfile, "fifth", NULL, &error); ++ check_no_error (&error); ++ g_assert_null (comment); ++ + g_key_file_free (keyfile); + + g_assert_cmpstr (data1, ==, data2); +-- +GitLab \ No newline at end of file diff --git a/patch/backport-gkeyfile-Skip-group-comment-when-adding-a-new-key-to-a-group.patch b/patch/backport-gkeyfile-Skip-group-comment-when-adding-a-new-key-to-a-group.patch new file mode 100644 index 0000000000000000000000000000000000000000..225d6e82b73394146660d5639c730258775b4b45 --- /dev/null +++ b/patch/backport-gkeyfile-Skip-group-comment-when-adding-a-new-key-to-a-group.patch @@ -0,0 +1,97 @@ +From 51dfb3c229c0478b3615f486fbbc36de2586bd52 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= +Date: Thu, 13 Jul 2023 10:19:04 +0200 +Subject: [PATCH] gkeyfile: Skip group comment when adding a new key to a group + +An oversight in 86b4b045: since the comment of group N now consists of +the last null-key values of group N-1, these keys must obviously be +skipped when adding a new non-null key to group N-1. + +Closes: #3047 +Fixes: 86b4b0453ea3a814167d4a5f7a4031d467543716 +--- + glib/gkeyfile.c | 19 ++++++++++++++----- + glib/tests/keyfile.c | 9 +++++++++ + 2 files changed, 23 insertions(+), 5 deletions(-) + +diff --git a/glib/gkeyfile.c b/glib/gkeyfile.c +index 0e21ab4f14..4759051977 100644 +--- a/glib/gkeyfile.c ++++ b/glib/gkeyfile.c +@@ -573,7 +573,8 @@ static void g_key_file_remove_key_value_pair_node (GKeyFile + + static void g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, +- GKeyFileKeyValuePair *pair); ++ GKeyFileKeyValuePair *pair, ++ GList *sibling); + static void g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, +@@ -1447,7 +1448,8 @@ g_key_file_parse_key_value_pair (GKeyFile *key_file, + pair->key = g_steal_pointer (&key); + pair->value = g_strndup (value_start, value_len); + +- g_key_file_add_key_value_pair (key_file, key_file->current_group, pair); ++ g_key_file_add_key_value_pair (key_file, key_file->current_group, pair, ++ key_file->current_group->key_value_pairs); + } + + g_free (key); +@@ -4034,10 +4036,11 @@ g_key_file_remove_group (GKeyFile *key_file, + static void + g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, +- GKeyFileKeyValuePair *pair) ++ GKeyFileKeyValuePair *pair, ++ GList *sibling) + { + g_hash_table_replace (group->lookup_map, pair->key, pair); +- group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); ++ group->key_value_pairs = g_list_insert_before (group->key_value_pairs, sibling, pair); + } + + static void +@@ -4047,12 +4050,18 @@ g_key_file_add_key (GKeyFile *key_file, + const gchar *value) + { + GKeyFileKeyValuePair *pair; ++ GList *lp; + + pair = g_new (GKeyFileKeyValuePair, 1); + pair->key = g_strdup (key); + pair->value = g_strdup (value); + +- g_key_file_add_key_value_pair (key_file, group, pair); ++ /* skip group comment */ ++ lp = group->key_value_pairs; ++ while (lp != NULL && ((GKeyFileKeyValuePair *) lp->data)->key == NULL) ++ lp = lp->next; ++ ++ g_key_file_add_key_value_pair (key_file, group, pair, lp); + } + + /** +diff --git a/glib/tests/keyfile.c b/glib/tests/keyfile.c +index 80cdc93d8f..2c8eca4ebc 100644 +--- a/glib/tests/keyfile.c ++++ b/glib/tests/keyfile.c +@@ -456,6 +456,15 @@ test_comments (void) + check_name ("group comment", comment, group_comment, 0); + g_free (comment); + ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3047"); ++ ++ /* check if adding a key to group N preserve group comment of group N+1 */ ++ g_key_file_set_string (keyfile, "group1", "key5", "value5"); ++ comment = g_key_file_get_comment (keyfile, "group2", NULL, &error); ++ check_no_error (&error); ++ check_name ("group comment", comment, group_comment, 0); ++ g_free (comment); ++ + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/104"); + + /* check if comments above another group than the first one are properly removed */ +-- +GitLab + diff --git a/patch/backport-glocalfileinfo-Fix-atime-mtime-mix.patch b/patch/backport-glocalfileinfo-Fix-atime-mtime-mix.patch deleted file mode 100644 index 8badc4c4027d786c22182f14fd1997c76de074b3..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-event-thread.patch b/patch/backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-event-thread.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d831f79460d0365017c22c4571f94078a5696ea --- /dev/null +++ b/patch/backport-glocalfilemonitor-Avoid-file-monitor-destruction-from-event-thread.patch @@ -0,0 +1,96 @@ +From 222f6ceada3c54cddf1cfa7a3b846716bafe244c Mon Sep 17 00:00:00 2001 +From: Benjamin Berg +Date: Fri, 18 Mar 2022 12:16:12 +0100 +Subject: [PATCH 1/3] glocalfilemonitor: Avoid file monitor destruction from + event thread + +Taking a reference to the GFileMonitor when handling events may cause +object destruction from th worker thread that calls the function. This +condition happens if the surrounding code drops the otherwise last +reference ot the GFileMonitor. The series of events causes destruction +from an unrelated worker thread and also triggers g_file_monitor_cancel +to be called from g_file_monitor_source_handle_event. + +For the inotify backend, this results in a deadlock as cancellation +needs to take a lock that protects data structures from being modified +while events are dispatched. + +One alternative to this approach might be to add an RCU (release, copy, +update) approach to the lists contained in the wd_dir_hash and +wd_file_hash hash tables. + +Fixes: #1941 + +An example stack trace of this happening is: + +Thread 2 (Thread 0x7fea68b1d640 (LWP 260961) "gmain"): + #0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38 + #1 0x00007fea692215dc in g_mutex_lock_slowpath (mutex=mutex@entry=0x7fea6911e148 ) at ../glib/gthread-posix.c:1493 + #2 0x00007fea69222062 in g_mutex_lock (mutex=mutex@entry=0x7fea6911e148 ) at ../glib/gthread-posix.c:1517 + #3 0x00007fea6908025a in _ih_sub_cancel (sub=0x1492620) at ../gio/inotify/inotify-helper.c:131 + #4 0x00007fea6907f9da in g_inotify_file_monitor_cancel (monitor=0x14a3550) at ../gio/inotify/ginotifyfilemonitor.c:75 + #5 0x00007fea68fae959 in g_file_monitor_cancel (monitor=0x14a3550) at ../gio/gfilemonitor.c:241 + #6 0x00007fea68fae9dc in g_file_monitor_dispose (object=0x14a3550) at ../gio/gfilemonitor.c:123 + #7 0x00007fea69139341 in g_object_unref (_object=) at ../gobject/gobject.c:3636 + #8 g_object_unref (_object=0x14a3550) at ../gobject/gobject.c:3553 + #9 0x00007fea6907507a in g_file_monitor_source_handle_event (fms=0x14c3560, event_type=, child=0x7fea64001460 "spawned-1", rename_to=rename_to@entry=0x0, other=other@entry=0x0, event_time=) at ../gio/glocalfilemonitor.c:457 + #10 0x00007fea6907fe0e in ih_event_callback (event=0x7fea64001420, sub=0x1492620, file_event=) at ../gio/inotify/inotify-helper.c:218 + #11 0x00007fea6908075c in ip_event_dispatch (dir_list=dir_list@entry=0x14c14c0, file_list=0x0, event=event@entry=0x7fea64001420) at ../gio/inotify/inotify-path.c:493 + #12 0x00007fea6908094e in ip_event_dispatch (event=0x7fea64001420, file_list=, dir_list=0x14c14c0) at ../gio/inotify/inotify-path.c:448 + #13 ip_event_callback (event=0x7fea64001420) at ../gio/inotify/inotify-path.c:548 + #14 ip_event_callback (event=0x7fea64001420) at ../gio/inotify/inotify-path.c:530 + #15 0x00007fea69081391 in ik_source_dispatch (source=0x14a2bf0, func=0x7fea69080890 , user_data=) at ../gio/inotify/inotify-kernel.c:327 + #16 0x00007fea691d0824 in g_main_dispatch (context=0x14a2cc0) at ../glib/gmain.c:3417 + #17 g_main_context_dispatch (context=0x14a2cc0) at ../glib/gmain.c:4135 + #18 0x00007fea691d0b88 in g_main_context_iterate (context=context@entry=0x14a2cc0, block=block@entry=1, dispatch=dispatch@entry=1, self=) at ../glib/gmain.c:4211 + #19 0x00007fea691d0c2f in g_main_context_iteration (context=0x14a2cc0, may_block=may_block@entry=1) at ../glib/gmain.c:4276 + #20 0x00007fea691d0c81 in glib_worker_main (data=) at ../glib/gmain.c:6176 + #21 0x00007fea691f9c2d in g_thread_proxy (data=0x1487cc0) at ../glib/gthread.c:827 + #22 0x00007fea68d93b1a in start_thread (arg=) at pthread_create.c:443 + #23 0x00007fea68e18650 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 +--- + gio/glocalfilemonitor.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c +index 4f85fea52..f408d0707 100644 +--- a/gio/glocalfilemonitor.c ++++ b/gio/glocalfilemonitor.c +@@ -348,7 +348,6 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms, + gint64 event_time) + { + gboolean interesting = TRUE; +- GFileMonitor *instance = NULL; + + g_assert (!child || is_basename (child)); + g_assert (!rename_to || is_basename (rename_to)); +@@ -359,13 +358,11 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms, + + g_mutex_lock (&fms->lock); + +- /* monitor is already gone -- don't bother */ +- instance = g_weak_ref_get (&fms->instance_ref); +- if (instance == NULL) +- { +- g_mutex_unlock (&fms->lock); +- return TRUE; +- } ++ /* NOTE: We process events even if the file monitor has already been disposed. ++ * The reason is that we must not take a reference to the instance here ++ * as destroying it from the event handling thread will lead to a ++ * deadlock when taking the lock in _ih_sub_cancel. ++ */ + + switch (event_type) + { +@@ -452,7 +449,6 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms, + g_file_monitor_source_update_ready_time (fms); + + g_mutex_unlock (&fms->lock); +- g_clear_object (&instance); + + return interesting; + } +-- +2.41.0.windows.3 + diff --git a/patch/backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch b/patch/backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f7683dac4b14f81f7d13f2b9a5d69804d9d4b58 --- /dev/null +++ b/patch/backport-glocalfilemonitor-Skip-event-handling-if-the-source-has-been-destroyed.patch @@ -0,0 +1,76 @@ +From 57bde3c9bda9cfdf1e55fd6ddc1c354bde1ee654 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 30 May 2022 17:54:18 +0100 +Subject: [PATCH 2/3] glocalfilemonitor: Skip event handling if the source has + been destroyed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This should prevent unbounded growth of the `event_queue` in the +unlikely case that the `GSource` is removed from its `GMainContext` and +destroyed separately from the `GFileMonitor`. + +I’m not sure if that can currently happen, but it could with future +refactoring, so it’s best to address the possibility now while we’re +thinking about this bit of code. + +Signed-off-by: Philip Withnall + +Helps: #1941 +--- + gio/glocalfilemonitor.c | 29 +++++++++++++++++++++++------ + 1 file changed, 23 insertions(+), 6 deletions(-) + +diff --git a/gio/glocalfilemonitor.c b/gio/glocalfilemonitor.c +index f408d0707..68afd7b51 100644 +--- a/gio/glocalfilemonitor.c ++++ b/gio/glocalfilemonitor.c +@@ -358,11 +358,28 @@ g_file_monitor_source_handle_event (GFileMonitorSource *fms, + + g_mutex_lock (&fms->lock); + +- /* NOTE: We process events even if the file monitor has already been disposed. +- * The reason is that we must not take a reference to the instance here +- * as destroying it from the event handling thread will lead to a +- * deadlock when taking the lock in _ih_sub_cancel. ++ /* NOTE: ++ * ++ * We process events even if the file monitor has already been disposed. ++ * The reason is that we must not take a reference to the instance here as ++ * destroying it from the event handling thread will lead to a deadlock when ++ * taking the lock in _ih_sub_cancel. ++ * ++ * This results in seemingly-unbounded growth of the `event_queue` with the ++ * calls to `g_file_monitor_source_queue_event()`. However, each of those sets ++ * the ready time on the #GSource, which means that it will be dispatched in ++ * a subsequent iteration of the #GMainContext it’s attached to. At that ++ * point, `g_file_monitor_source_dispatch()` will return %FALSE, and this will ++ * trigger finalisation of the source. That will clear the `event_queue`. ++ * ++ * If the source is no longer attached, this will return early to prevent ++ * unbounded queueing. + */ ++ if (g_source_is_destroyed ((GSource *) fms)) ++ { ++ g_mutex_unlock (&fms->lock); ++ return TRUE; ++ } + + switch (event_type) + { +@@ -595,9 +612,9 @@ g_file_monitor_source_dispose (GFileMonitorSource *fms) + + g_file_monitor_source_update_ready_time (fms); + +- g_mutex_unlock (&fms->lock); +- + g_source_destroy ((GSource *) fms); ++ ++ g_mutex_unlock (&fms->lock); + } + + static void +-- +2.41.0.windows.3 + diff --git a/patch/backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch b/patch/backport-gmarkup-Add-G_MARKUP_PARSE_FLAGS_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..063fc0165312c1ff97569df26b5dddb3c92e7d52 --- /dev/null +++ b/patch/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/patch/backport-gmessages-fix-dropping-irrelevant-log-domains.patch b/patch/backport-gmessages-fix-dropping-irrelevant-log-domains.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b2ddf7254a289a9afb2024172cbb10c13b57fba --- /dev/null +++ b/patch/backport-gmessages-fix-dropping-irrelevant-log-domains.patch @@ -0,0 +1,128 @@ +From 71f6d4c129fc729a5ead08637924d8c0973f2fe9 Mon Sep 17 00:00:00 2001 +From: Alexander Slobodeniuk +Date: Wed, 1 Nov 2023 10:32:27 +0100 +Subject: [PATCH 1/2] gmessages: fix dropping irrelevant log domains + +If the string of one log domain is contained in +another, it was printing both. + +For example, if G_MESSAGES_DEBUG is "Gtkspecial", +it would also keep the logs of the "Gtk" domain + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/71f6d4c129fc729a5ead08637924d8c0973f2fe9 + +--- + glib/gmessages.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/glib/gmessages.c b/glib/gmessages.c +index d0d38c925a..ebd3a5433e 100644 +--- a/glib/gmessages.c ++++ b/glib/gmessages.c +@@ -2465,6 +2465,26 @@ log_is_old_api (const GLogField *fields, + g_strcmp0 (fields[0].value, "1") == 0); + } + ++static gboolean ++domain_found (const gchar *domains, ++ const char *log_domain) ++{ ++ guint len; ++ const gchar *found; ++ ++ len = strlen (log_domain); ++ ++ for (found = strstr (domains, log_domain); found; ++ found = strstr (found + 1, log_domain)) ++ { ++ if ((found == domains || found[-1] == ' ') ++ && (found[len] == 0 || found[len] == ' ')) ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + /* + * Internal version of g_log_writer_default_would_drop(), which can + * read from either a log_domain or an array of fields. This avoids +@@ -2504,7 +2524,7 @@ should_drop_message (GLogLevelFlags log_level, + } + + if (strcmp (domains, "all") != 0 && +- (log_domain == NULL || !strstr (domains, log_domain))) ++ (log_domain == NULL || !domain_found (domains, log_domain))) + return TRUE; + } + +-- +GitLab + + +From 8eddbb9832b9a52a7495cc380e53715d920bb9ea Mon Sep 17 00:00:00 2001 +From: Alexander Slobodeniuk +Date: Wed, 1 Nov 2023 19:23:35 +0100 +Subject: [PATCH 2/2] glib/tests: extend logging test (dropping domains) + + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/8eddbb9832b9a52a7495cc380e53715d920bb9ea + +--- + glib/tests/logging.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/glib/tests/logging.c b/glib/tests/logging.c +index ea9dcb825e..f4c47e16c8 100644 +--- a/glib/tests/logging.c ++++ b/glib/tests/logging.c +@@ -244,6 +244,46 @@ test_default_handler_would_drop (void) + g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo")); + g_assert_false (g_log_writer_default_would_drop (1< -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/patch/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch b/patch/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch deleted file mode 100644 index c8115245cf7e2c5a55ad2fd2ac171ea74da6b648..0000000000000000000000000000000000000000 --- a/patch/backport-gopenuriportal-Fix-a-use-after-free-on-an-error-path.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 28 Apr 2022 10:56:10 +0100 -Subject: [PATCH] gopenuriportal: Fix a use-after-free on an error path - -`path` was used in building the error message after it had been freed. -Spotted by scan-build. - -Signed-off-by: Philip Withnall - -Helps: #1767 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e - ---- - gopenuriportal.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c -index ecf6fea..2f527d8 100644 ---- a/gio/gopenuriportal.c -+++ b/gio/gopenuriportal.c -@@ -108,10 +108,10 @@ 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); -+ g_free (path); -+ g_variant_builder_clear (&opt_builder); - return FALSE; - } - --- -2.33.0 - diff --git a/patch/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch b/patch/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch deleted file mode 100644 index 60c0414f0e759c579d11f885341c4e6f0fd9da40..0000000000000000000000000000000000000000 --- a/patch/backport-gprintf-Fix-a-memory-leak-with-an-invalid-format.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Wed, 9 Mar 2022 14:07:34 +0000 -Subject: [PATCH] gprintf: Fix a memory leak with an invalid format in - g_vasprintf() - -If using the fallback implementation of `g_vasprintf()`. - -Signed-off-by: Philip Withnall - -Coverity CID: #1474726 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db - ---- - glib/gprintf.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/glib/gprintf.c b/glib/gprintf.c -index 555a630bc2..0e094f00fa 100644 ---- a/glib/gprintf.c -+++ b/glib/gprintf.c -@@ -356,6 +356,12 @@ g_vasprintf (gchar **string, - - len = _g_vsprintf (*string, format, args2); - va_end (args2); -+ -+ if (len < 0) -+ { -+ g_free (*string); -+ *string = NULL; -+ } - } - #endif - --- -GitLab diff --git a/patch/backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch b/patch/backport-gproxyaddressenumerator-Fix-string-leakage-on-an-invalid-input.patch deleted file mode 100644 index 8652e45edb88ba559bf257121c3d3eb7e081fb41..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch b/patch/backport-gregex-Add-G_REGEX_DEFAULT-G_REGEX_MATCH_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..59103df320b95ab016717d9aa1fa48c97525ac1f --- /dev/null +++ b/patch/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/patch/backport-gregex-Allow-G_REGEX_JAVASCRIPT_COMPAT-in-compile-mask-for-g_regex_new.patch b/patch/backport-gregex-Allow-G_REGEX_JAVASCRIPT_COMPAT-in-compile-mask-for-g_regex_new.patch new file mode 100644 index 0000000000000000000000000000000000000000..bb839edde51059ace8e8f81167c66a03be42321d --- /dev/null +++ b/patch/backport-gregex-Allow-G_REGEX_JAVASCRIPT_COMPAT-in-compile-mask-for-g_regex_new.patch @@ -0,0 +1,57 @@ +From a164b49532957359c781ab56c3e1690f65f40788 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Guido=20G=C3=BCnther?= +Date: Fri, 23 Sep 2022 14:48:07 +0200 +Subject: [PATCH] gregex: Allow G_REGEX_JAVASCRIPT_COMPAT in compile mask for + g_regex_new + +The flag is still ignored but this way we properly deprecate +at compile time without raising an unexpected criticals at runtime: + + g_regex_new: assertion '(compile_options & ~G_REGEX_COMPILE_MASK) == 0' failed + +and then failing to create the regex completely. + +Fixes 8d5a44dc8 ("replace pcre1 with pcre2") + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a164b49532957359c781ab56c3e1690f65f40788 + +--- + glib/gregex.c | 5 ++++- + glib/tests/regex.c | 4 ++++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 220a1a11ac..6b22f1f151 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1684,7 +1684,10 @@ g_regex_new (const gchar *pattern, + + g_return_val_if_fail (pattern != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); +- g_return_val_if_fail ((compile_options & ~G_REGEX_COMPILE_MASK) == 0, NULL); ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS ++ g_return_val_if_fail ((compile_options & ~(G_REGEX_COMPILE_MASK | ++ G_REGEX_JAVASCRIPT_COMPAT)) == 0, NULL); ++G_GNUC_END_IGNORE_DEPRECATIONS + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + if (g_once_init_enter (&initialised)) +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 9803d49659..f2e1a04ada 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -2542,6 +2542,10 @@ main (int argc, char *argv[]) + TEST_NEW_CHECK_FLAGS ("(*BSR_ANYCRLF)a", 0, 0, G_REGEX_BSR_ANYCRLF, 0); + TEST_NEW_CHECK_FLAGS ("(*BSR_UNICODE)a", 0, 0, 0 /* this is the default in GRegex */, 0); + TEST_NEW_CHECK_FLAGS ("(*NO_START_OPT)a", 0, 0, 0 /* not exposed in GRegex */, 0); ++ /* Make sure we ignore deprecated G_REGEX_JAVASCRIPT_COMPAT */ ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS ++ TEST_NEW_CHECK_FLAGS ("a", G_REGEX_JAVASCRIPT_COMPAT, 0, 0, 0); ++G_GNUC_END_IGNORE_DEPRECATIONS + + /* TEST_NEW_FAIL(pattern, compile_opts, expected_error) */ + TEST_NEW_FAIL("(", 0, G_REGEX_ERROR_UNMATCHED_PARENTHESIS); +-- +GitLab + diff --git a/patch/backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch b/patch/backport-gregex-Avoid-re-allocating-if-we-have-no-size-change.patch new file mode 100644 index 0000000000000000000000000000000000000000..0164d75b8ee401d039d05161d323d1963f59e784 --- /dev/null +++ b/patch/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/patch/backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch b/patch/backport-gregex-Do-not-try-access-the-undefined-match-offsets.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbc510f6a83ababeea00fe1ba6747fa39b7fb58b --- /dev/null +++ b/patch/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/patch/backport-gregex-Drop-explanation-G_REGEX_JAVASCRIPT_COMPAT.patch b/patch/backport-gregex-Drop-explanation-G_REGEX_JAVASCRIPT_COMPAT.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d36f79597a7842b16818d528625d97e68272852 --- /dev/null +++ b/patch/backport-gregex-Drop-explanation-G_REGEX_JAVASCRIPT_COMPAT.patch @@ -0,0 +1,40 @@ +From 664ee9ca6afcc3e08c99f0918982e9d2e22f34a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Guido=20G=C3=BCnther?= +Date: Fri, 23 Sep 2022 15:27:49 +0200 +Subject: [PATCH] gregex: Drop explanation G_REGEX_JAVASCRIPT_COMPAT + +It's not supported as of glib 2.74 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/664ee9ca6afcc3e08c99f0918982e9d2e22f34a8 + +--- + glib/gregex.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 6b22f1f151..50abeee89f 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -89,18 +89,6 @@ + * unescaped "#" outside a character class is encountered. This indicates + * a comment that lasts until after the next newline. + * +- * When setting the %G_REGEX_JAVASCRIPT_COMPAT flag, pattern syntax and pattern +- * matching is changed to be compatible with the way that regular expressions +- * work in JavaScript. More precisely, a lonely ']' character in the pattern +- * is a syntax error; the '\x' escape only allows 0 to 2 hexadecimal digits, and +- * you must use the '\u' escape sequence with 4 hex digits to specify a unicode +- * codepoint instead of '\x' or 'x{....}'. If '\x' or '\u' are not followed by +- * the specified number of hex digits, they match 'x' and 'u' literally; also +- * '\U' always matches 'U' instead of being an error in the pattern. Finally, +- * pattern matching is modified so that back references to an unset subpattern +- * group produces a match with the empty string instead of an error. See +- * pcreapi(3) for more information. +- * + * Creating and manipulating the same #GRegex structure from different + * threads is not a problem as #GRegex does not modify its internal + * state between creation and destruction, on the other hand #GMatchInfo +-- +GitLab + diff --git a/patch/backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch b/patch/backport-gregex-Fix-a-potential-PCRE2-code-leak-on-reallocation-failures.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1dd7801acf3ae30ae6998eb6708d31ef8a3d5b0 --- /dev/null +++ b/patch/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/patch/backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch b/patch/backport-gregex-Free-match-info-if-offset-matching-recalc-failed.patch new file mode 100644 index 0000000000000000000000000000000000000000..d194bf1f1d0c6826ef353ab89078c6bad1bb6257 --- /dev/null +++ b/patch/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/patch/backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch b/patch/backport-gregex-Handle-the-case-we-need-to-re-allocate-the-match-data.patch new file mode 100644 index 0000000000000000000000000000000000000000..f9d340ea8d6b3d842aa734b2b835641d6be0eb1f --- /dev/null +++ b/patch/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/patch/backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch b/patch/backport-gregex-Mark-g_match_info_get_regex-as-transfer-none.patch new file mode 100644 index 0000000000000000000000000000000000000000..f0e86e93b19f1e3aebe36e348220f68a0a25dd3d --- /dev/null +++ b/patch/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/patch/backport-gregex-Remove-an-unreachable-return-statement.patch b/patch/backport-gregex-Remove-an-unreachable-return-statement.patch new file mode 100644 index 0000000000000000000000000000000000000000..04a6e2ced320cefd6eb3c816d8d159c9eecad3f4 --- /dev/null +++ b/patch/backport-gregex-Remove-an-unreachable-return-statement.patch @@ -0,0 +1,34 @@ +From 4fca3bba8f38627ee13b99b0b5093b73a2052e77 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 18 Oct 2022 15:05:30 +0100 +Subject: [PATCH] gregex: Remove an unreachable return statement + +Spotted by Coverity. + +Signed-off-by: Philip Withnall + +Coverity CID: #1497916 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/4fca3bba8f38627ee13b99b0b5093b73a2052e77 + +--- + glib/gregex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 41ad675a76..53eda2b19d 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -947,7 +947,7 @@ enable_jit_with_match_options (GRegex *regex, + break; + } + +- return regex->jit_status; ++ g_assert_not_reached (); + } + + /** +-- +GitLab + diff --git a/patch/backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch b/patch/backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch new file mode 100644 index 0000000000000000000000000000000000000000..a5e881d2592fe2e506fb1e0bb4448a8a75c2c8bd --- /dev/null +++ b/patch/backport-gregex-Use-pcre2-error-messages-if-we-dont-provide-a-specific-one.patch @@ -0,0 +1,187 @@ +From 6caf952e48dbed40b5dcff01a94f57ba079b526c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Tue, 20 Sep 2022 18:06:35 +0200 +Subject: [PATCH] gregex: Use pcre2 error messages if we don't provide a + specific one + +In case we got a compilation or match error we should try to provide +some useful error message, if possible, before returning a quite obscure +"internal error" or "unknown error" string. + +So rely on PCRE2 strings even if they're not translated they can provide +better information than the ones we're currently giving. + +Related to: https://gitlab.gnome.org/GNOME/glib/-/issues/2691 +Related to: https://gitlab.gnome.org/GNOME/glib/-/issues/2760 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/6caf952e48dbed40b5dcff01a94f57ba079b526c + +--- + glib/gregex.c | 64 ++++++++++++++++++++++++++++++++++++++++------ + glib/tests/regex.c | 2 ++ + 2 files changed, 58 insertions(+), 8 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 220a1a11ac..fcc28d62f4 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -456,8 +456,25 @@ get_pcre2_bsr_match_options (GRegexMatchFlags match_flags) + return 0; + } + ++static char * ++get_pcre2_error_string (int errcode) ++{ ++ PCRE2_UCHAR8 error_msg[2048]; ++ int err_length; ++ ++ err_length = pcre2_get_error_message (errcode, error_msg, ++ G_N_ELEMENTS (error_msg)); ++ ++ if (err_length <= 0) ++ return NULL; ++ ++ /* The array is always filled with a trailing zero */ ++ g_assert ((size_t) err_length < G_N_ELEMENTS (error_msg)); ++ return g_memdup2 (error_msg, err_length + 1); ++} ++ + static const gchar * +-match_error (gint errcode) ++translate_match_error (gint errcode) + { + switch (errcode) + { +@@ -511,7 +528,24 @@ match_error (gint errcode) + default: + break; + } +- return _("unknown error"); ++ return NULL; ++} ++ ++static char * ++get_match_error_message (int errcode) ++{ ++ const char *msg = translate_match_error (errcode); ++ char *error_string; ++ ++ if (msg) ++ return g_strdup (msg); ++ ++ error_string = get_pcre2_error_string (errcode); ++ ++ if (error_string) ++ return error_string; ++ ++ return g_strdup (_("unknown error")); + } + + static void +@@ -743,7 +777,6 @@ translate_compile_error (gint *errcode, const gchar **errmsg) + 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: +@@ -772,12 +805,10 @@ translate_compile_error (gint *errcode, const gchar **errmsg) + case PCRE2_ERROR_BAD_LITERAL_OPTIONS: + default: + *errcode = G_REGEX_ERROR_COMPILE; +- *errmsg = _("internal error"); + break; + } + + g_assert (*errcode != -1); +- g_assert (*errmsg != NULL); + } + + /* GMatchInfo */ +@@ -1096,9 +1127,12 @@ g_match_info_next (GMatchInfo *match_info, + + if (IS_PCRE2_ERROR (match_info->matches)) + { ++ gchar *error_msg = get_match_error_message (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)); ++ match_info->regex->pattern, error_msg); ++ g_clear_pointer (&error_msg, g_free); + return FALSE; + } + else if (match_info->matches == 0) +@@ -1800,11 +1834,20 @@ regex_compile (const gchar *pattern, + { + GError *tmp_error; + gchar *offset_str; ++ gchar *pcre2_errmsg = NULL; ++ int original_errcode; + + /* Translate the PCRE error code to GRegexError and use a translated + * error message if possible */ ++ original_errcode = errcode; + translate_compile_error (&errcode, &errmsg); + ++ if (!errmsg) ++ { ++ errmsg = _("unknown error"); ++ pcre2_errmsg = get_pcre2_error_string (original_errcode); ++ } ++ + /* PCRE uses byte offsets but we want to show character offsets */ + erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]); + +@@ -1812,9 +1855,11 @@ regex_compile (const gchar *pattern, + tmp_error = g_error_new (G_REGEX_ERROR, errcode, + _("Error while compiling regular expression ‘%s’ " + "at char %s: %s"), +- pattern, offset_str, errmsg); ++ pattern, offset_str, ++ pcre2_errmsg ? pcre2_errmsg : errmsg); + g_propagate_error (error, tmp_error); + g_free (offset_str); ++ g_clear_pointer (&pcre2_errmsg, g_free); + + return NULL; + } +@@ -2402,9 +2447,12 @@ g_regex_match_all_full (const GRegex *regex, + } + else if (IS_PCRE2_ERROR (info->matches)) + { ++ gchar *error_msg = get_match_error_message (info->matches); ++ + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, + _("Error while matching regular expression %s: %s"), +- regex->pattern, match_error (info->matches)); ++ regex->pattern, error_msg); ++ g_clear_pointer (&error_msg, g_free); + } + else if (info->matches != PCRE2_ERROR_NOMATCH) + { +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 9803d49659..52af212f29 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -2560,6 +2560,7 @@ main (int argc, char *argv[]) + TEST_NEW_FAIL ("[a-z", 0, G_REGEX_ERROR_UNTERMINATED_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 ("^[[:alnum:]-_.]+$", 0, G_REGEX_ERROR_COMPILE); + 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_MISSING_SUBPATTERN_NAME); +@@ -2636,6 +2637,7 @@ main (int argc, char *argv[]) + 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); ++ TEST_MATCH_SIMPLE("^[[:alnum:]\\-_.]+$", "admin-foo", 0, 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); +-- +GitLab + diff --git a/patch/backport-gregex-add-original-test-case.patch b/patch/backport-gregex-add-original-test-case.patch new file mode 100644 index 0000000000000000000000000000000000000000..52028482596c50e1de4f537b19afa400ac11cbd6 --- /dev/null +++ b/patch/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/patch/backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch b/patch/backport-gregex-do-not-set-match-and-recursion-limits-on-match-context.patch new file mode 100644 index 0000000000000000000000000000000000000000..b5ac211e4ddc36538d34dc20b6031ecfb358d120 --- /dev/null +++ b/patch/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/patch/backport-gregex-ensure-we-translate-the-errcode.patch b/patch/backport-gregex-ensure-we-translate-the-errcode.patch new file mode 100644 index 0000000000000000000000000000000000000000..530cdb3d82d96422afc628750b758cfaf77a7473 --- /dev/null +++ b/patch/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/patch/backport-gregex-format-specifier-for-localized-error-message.patch b/patch/backport-gregex-format-specifier-for-localized-error-message.patch new file mode 100644 index 0000000000000000000000000000000000000000..02ce7a72d5e4adfb98ece8a94079121f11195c96 --- /dev/null +++ b/patch/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/patch/backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch b/patch/backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d6d873dbcd645dbb2644bf722545be4b93ef6a9 --- /dev/null +++ b/patch/backport-gregex-if-JIT-stack-limit-is-reached-fall-back-to-interpretive-matching.patch @@ -0,0 +1,120 @@ +From 406f85a48f1ec41cda15ae617a979f7df749cb27 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Sun, 20 Aug 2023 16:33:53 +0200 +Subject: [PATCH 1/2] gregex: if JIT stack limit is reached, fall back to + interpretive matching + +Conflict:Move large_test_string to fix declaration-after-statement +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/406f85a48f1ec41cda15ae617a979f7df749cb27 + +--- + glib/gregex.c | 13 ++++++++++--- + glib/tests/regex.c | 10 +++++++++- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 5ce034db41..1b3ee02f30 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -484,8 +484,6 @@ translate_match_error (gint errcode) + /* not used by pcre2_match() */ + break; + case PCRE2_ERROR_MATCHLIMIT: +- case PCRE2_ERROR_JIT_STACKLIMIT: +- return _("backtracking limit reached"); + case PCRE2_ERROR_CALLOUT: + /* callouts are not implemented */ + break; +@@ -1107,8 +1105,17 @@ g_match_info_next (GMatchInfo *match_info, + opts, + match_info->match_data, + match_info->match_context); ++ /* if the JIT stack limit was reached, fall back to non-JIT matching in ++ * the next conditional statement */ ++ if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT) ++ { ++ g_info ("PCRE2 JIT stack limit reached, falling back to " ++ "non-optimized matching."); ++ opts |= PCRE2_NO_JIT; ++ jit_status = JIT_STATUS_DISABLED; ++ } + } +- else ++ if (jit_status != JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_match (match_info->regex->pcre_re, + (PCRE2_SPTR8) match_info->string, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index 821fc59608..f18db483c2 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -51,8 +51,9 @@ + /* A random value use to mark untouched integer variables. */ + #define UNTOUCHED -559038737 + +-/* A length of the test string in JIT stack test */ ++/* Lengths of test strings in JIT stack tests */ + #define TEST_STRING_LEN 20000 ++#define LARGE_TEST_STRING_LEN 200000 + + static gint total; + +@@ -2485,6 +2486,7 @@ int + main (int argc, char *argv[]) + { + char test_string[TEST_STRING_LEN]; ++ char large_test_string[LARGE_TEST_STRING_LEN]; + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); +@@ -2711,6 +2713,12 @@ G_GNUC_END_IGNORE_DEPRECATIONS + test_string[TEST_STRING_LEN - 1] = '\0'; + TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); + ++ /* Test that gregex falls back to unoptimized matching when reaching the JIT ++ * compiler stack limit */ ++ memset (large_test_string, '*', LARGE_TEST_STRING_LEN); ++ large_test_string[LARGE_TEST_STRING_LEN - 1] = '\0'; ++ TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", large_test_string, 0, 0, TRUE); ++ + /* TEST_MATCH(pattern, compile_opts, match_opts, string, + * string_len, start_position, match_opts2, expected) */ + TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); +-- +GitLab + + +From 986fa3fdad5155924b17dbde16811d017a6413da Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 21 Aug 2023 10:19:43 +0000 +Subject: [PATCH 2/2] Apply 2 suggestion(s) to 1 file(s) + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/986fa3fdad5155924b17dbde16811d017a6413da + +--- + glib/gregex.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 1b3ee02f30..b37a5e04c7 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1109,12 +1109,13 @@ g_match_info_next (GMatchInfo *match_info, + * the next conditional statement */ + if (match_info->matches == PCRE2_ERROR_JIT_STACKLIMIT) + { +- g_info ("PCRE2 JIT stack limit reached, falling back to " +- "non-optimized matching."); ++ g_debug ("PCRE2 JIT stack limit reached, falling back to " ++ "non-optimized matching."); + opts |= PCRE2_NO_JIT; + jit_status = JIT_STATUS_DISABLED; + } + } ++ + if (jit_status != JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_match (match_info->regex->pcre_re, +-- +GitLab \ No newline at end of file diff --git a/patch/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch b/patch/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a9ed186fb8a3f3cfed96d622a572436ed32270b --- /dev/null +++ b/patch/backport-gregex-set-default-max-stack-size-for-PCRE2-JIT-compiler-to-512KiB.patch @@ -0,0 +1,166 @@ +From 842a105464f6390a433da8791d7b19b65df16f47 Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 14 Aug 2023 20:32:48 +0200 +Subject: [PATCH 1/2] gregex: remove redundant call to + enable_jit_with_match_options + +There is no point to enable jit in g_regex_new, since JIT will be only +used when we do a first match, and at that point +enable_jit_with_match_options will be called again already and will +update the options set in g_regex_new. Instead just run it at first +match for the first time, to the same end result. + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/842a105464f6390a433da8791d7b19b65df16f47 + +--- + glib/gregex.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index 39b9edeecd..f6b2b716fc 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -1764,7 +1764,6 @@ G_GNUC_END_IGNORE_DEPRECATIONS + regex->orig_compile_opts = compile_options; + regex->match_opts = pcre_match_options; + regex->orig_match_opts = match_options; +- regex->jit_status = enable_jit_with_match_options (regex, regex->match_opts); + + return regex; + } +-- +GitLab + + +From c3ff5b8eb39f1ab31383604910ae12f325e5afee Mon Sep 17 00:00:00 2001 +From: Aleksei Rybalkin +Date: Mon, 14 Aug 2023 20:41:40 +0200 +Subject: [PATCH 2/2] gregex: set default max stack size for PCRE2 JIT compiler + to 512KiB + +Previous default used was 32KiB (the library default) which caused some +complex patterns to fail, see #2824. The memory will not be allocated +unless used. + +Conflict:Move test_string to fix declaration-after-statement +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/c3ff5b8eb39f1ab31383604910ae12f325e5afee + +--- + glib/gregex.c | 22 ++++++++++++++-------- + glib/tests/regex.c | 9 +++++++++ + 2 files changed, 23 insertions(+), 8 deletions(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index f6b2b716fc..5ce034db41 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -232,6 +232,7 @@ struct _GMatchInfo + gssize string_len; /* length of string, in bytes */ + pcre2_match_context *match_context; + pcre2_match_data *match_data; ++ pcre2_jit_stack *jit_stack; + }; + + typedef enum +@@ -896,22 +897,22 @@ recalc_match_offsets (GMatchInfo *match_info, + } + + static JITStatus +-enable_jit_with_match_options (GRegex *regex, ++enable_jit_with_match_options (GMatchInfo *match_info, + uint32_t match_options) + { + gint retval; + uint32_t old_jit_options, new_jit_options; + +- if (!(regex->orig_compile_opts & G_REGEX_OPTIMIZE)) ++ if (!(match_info->regex->orig_compile_opts & G_REGEX_OPTIMIZE)) + return JIT_STATUS_DISABLED; + +- if (regex->jit_status == JIT_STATUS_DISABLED) ++ if (match_info->regex->jit_status == JIT_STATUS_DISABLED) + return JIT_STATUS_DISABLED; + + if (match_options & G_REGEX_PCRE2_JIT_UNSUPPORTED_OPTIONS) + return JIT_STATUS_DISABLED; + +- old_jit_options = regex->jit_options; ++ old_jit_options = match_info->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; +@@ -920,13 +921,16 @@ enable_jit_with_match_options (GRegex *regex, + + /* no new options enabled */ + if (new_jit_options == old_jit_options) +- return regex->jit_status; ++ return match_info->regex->jit_status; + +- retval = pcre2_jit_compile (regex->pcre_re, new_jit_options); ++ retval = pcre2_jit_compile (match_info->regex->pcre_re, new_jit_options); + switch (retval) + { + case 0: /* JIT enabled successfully */ +- regex->jit_options = new_jit_options; ++ match_info->regex->jit_options = new_jit_options; ++ /* Set min stack size for JIT to 32KiB and max to 512KiB */ ++ match_info->jit_stack = pcre2_jit_stack_create (1 << 15, 1 << 19, NULL); ++ pcre2_jit_stack_assign (match_info->match_context, NULL, match_info->jit_stack); + return JIT_STATUS_ENABLED; + case PCRE2_ERROR_NOMEMORY: + g_debug ("JIT compilation was requested with G_REGEX_OPTIMIZE, " +@@ -1023,6 +1027,8 @@ g_match_info_unref (GMatchInfo *match_info) + g_regex_unref (match_info->regex); + if (match_info->match_context) + pcre2_match_context_free (match_info->match_context); ++ if (match_info->jit_stack) ++ pcre2_jit_stack_free (match_info->jit_stack); + if (match_info->match_data) + pcre2_match_data_free (match_info->match_data); + g_free (match_info->offsets); +@@ -1091,7 +1097,7 @@ g_match_info_next (GMatchInfo *match_info, + + opts = match_info->regex->match_opts | match_info->match_opts; + +- jit_status = enable_jit_with_match_options (match_info->regex, opts); ++ jit_status = enable_jit_with_match_options (match_info, opts); + if (jit_status == JIT_STATUS_ENABLED) + { + match_info->matches = pcre2_jit_match (match_info->regex->pcre_re, +diff --git a/glib/tests/regex.c b/glib/tests/regex.c +index cf2bb8199d..821fc59608 100644 +--- a/glib/tests/regex.c ++++ b/glib/tests/regex.c +@@ -51,6 +51,9 @@ + /* A random value use to mark untouched integer variables. */ + #define UNTOUCHED -559038737 + ++/* A length of the test string in JIT stack test */ ++#define TEST_STRING_LEN 20000 ++ + static gint total; + + typedef struct { +@@ -2481,6 +2484,7 @@ test_jit_unsupported_matching_options (void) + int + main (int argc, char *argv[]) + { ++ char test_string[TEST_STRING_LEN]; + setlocale (LC_ALL, ""); + + g_test_init (&argc, &argv, NULL); +@@ -2702,6 +2706,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS + TEST_MATCH_SIMPLE("\\", "a", 0, 0, FALSE); + TEST_MATCH_SIMPLE("[", "", 0, 0, FALSE); + ++ /* Test that JIT compiler has enough stack */ ++ memset (test_string, '*', TEST_STRING_LEN); ++ test_string[TEST_STRING_LEN - 1] = '\0'; ++ TEST_MATCH_SIMPLE ("^(?:[ \t\n]|[^[:cntrl:]])*$", test_string, 0, 0, TRUE); ++ + /* TEST_MATCH(pattern, compile_opts, match_opts, string, + * string_len, start_position, match_opts2, expected) */ + TEST_MATCH("a", 0, 0, "a", -1, 0, 0, TRUE); +-- +GitLab \ No newline at end of file diff --git a/patch/backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch b/patch/backport-gregex-use-G_REGEX_OPTIMIZE-flag-to-enable-JIT-compilation.patch new file mode 100644 index 0000000000000000000000000000000000000000..54bb85216eeddc0569450b160cebb2ee9e3a5611 --- /dev/null +++ b/patch/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/patch/backport-gregex-use-correct-size-for-pcre2_pattern_info.patch b/patch/backport-gregex-use-correct-size-for-pcre2_pattern_info.patch new file mode 100644 index 0000000000000000000000000000000000000000..0f9d0ef0b171c7995d894689b8030e792900428a --- /dev/null +++ b/patch/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/patch/backport-gregex-use-g_debug-instead-of-g_warning-in-case-JIT-is-not-available.patch b/patch/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/patch/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/patch/backport-gsignal-Add-G_CONNECT_DEFAULT.patch b/patch/backport-gsignal-Add-G_CONNECT_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..8dfc89241b834327ada1e9c8ba7c28c48f14f1f0 --- /dev/null +++ b/patch/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/patch/backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch b/patch/backport-gsocks5proxy-Fix-buffer-overflow-on-a-really-long-domain-name.patch deleted file mode 100644 index af277b7a6a0481ae1fc34c3c3ffd582b0483d3af..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch b/patch/backport-gsocks5proxy-Handle-EOF-when-reading-from-a-stream.patch deleted file mode 100644 index dc9123970001cc30f9a7bee62f0e8fccee9a746f..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch b/patch/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch deleted file mode 100644 index 912e474f51b1bf6ddf77e48b9877c10ea08b049c..0000000000000000000000000000000000000000 --- a/patch/backport-gtestdbus-Print-the-dbus-address-on-a-specific-FD-intead-of-stdout.patch +++ /dev/null @@ -1,192 +0,0 @@ -From d98a52254b4a681569a44f6be2aeceeaed58202c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= -Date: Mon, 22 Nov 2021 16:55:35 +0100 -Subject: [PATCH] gtestdbus: Print the dbus address on a specific FD intead of - stdout - -We used to use a pipe for the dbus daemon stdout to read the defined -address, but that was already requiring a workaround to ensure that dbus -daemon children were then able to write to stdout. -However the current implementation is still causing troubles in some -cases in which the daemon is very verbose, leading to hangs when writing -to stdout. - -As per this, just don't handle stdout ourself, but use instead a -specific pipe to get the address address. That can now be safely closed -once we've received the data we need. - -This reverts commit d80adeaa960ddfa13837900d0391f9bd9c239f78. - -Fixes: #2537 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d98a52254b4a681569a44f6be2aeceeaed58202c - ---- - gio/gtestdbus.c | 89 ++++++++++++++++++++++++++++++++----------------- - 1 file changed, 59 insertions(+), 30 deletions(-) - -diff --git a/gio/gtestdbus.c b/gio/gtestdbus.c -index 703a0b3a5a..992d29cef0 100644 ---- a/gio/gtestdbus.c -+++ b/gio/gtestdbus.c -@@ -32,6 +32,8 @@ - #endif - #ifdef G_OS_WIN32 - #include -+#include -+#include - #endif - - #include -@@ -44,8 +46,8 @@ - - #include "glibintl.h" - --#ifdef G_OS_WIN32 --#include -+#ifdef G_OS_UNIX -+#include "glib-unix.h" - #endif - - /* -------------------------------------------------------------------------- */ -@@ -436,7 +438,6 @@ struct _GTestDBusPrivate - GTestDBusFlags flags; - GPtrArray *service_dirs; - GPid bus_pid; -- gint bus_stdout_fd; - gchar *bus_address; - gboolean up; - }; -@@ -596,58 +597,87 @@ write_config_file (GTestDBus *self) - return path; - } - -+static gboolean -+make_pipe (gint pipe_fds[2], -+ GError **error) -+{ -+#if defined(G_OS_UNIX) -+ return g_unix_open_pipe (pipe_fds, FD_CLOEXEC, error); -+#elif defined(G_OS_WIN32) -+ if (_pipe (pipe_fds, 4096, _O_BINARY) < 0) -+ { -+ int errsv = errno; -+ -+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, -+ _("Failed to create pipe for communicating with child process (%s)"), -+ g_strerror (errsv)); -+ return FALSE; -+ } -+ return TRUE; -+#else -+ g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, -+ _("Pipes are not supported in this platform")); -+ return FALSE; -+#endif -+} -+ - static void - start_daemon (GTestDBus *self) - { - const gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL}; -+ gint pipe_fds[2] = {-1, -1}; - gchar *config_path; - gchar *config_arg; -+ gchar *print_address; - GIOChannel *channel; -- gint stdout_fd2; - gsize termpos; - GError *error = NULL; - - if (g_getenv ("G_TEST_DBUS_DAEMON") != NULL) - argv[0] = (gchar *)g_getenv ("G_TEST_DBUS_DAEMON"); - -+ make_pipe (pipe_fds, &error); -+ g_assert_no_error (error); -+ -+ print_address = g_strdup_printf ("--print-address=%d", pipe_fds[1]); -+ argv[1] = print_address; -+ g_assert_no_error (error); -+ - /* Write config file and set its path in argv */ - config_path = write_config_file (self); - config_arg = g_strdup_printf ("--config-file=%s", config_path); - argv[2] = config_arg; - - /* Spawn dbus-daemon */ -- g_spawn_async_with_pipes (NULL, -- (gchar **) argv, -- NULL, -- /* We Need this to get the pid returned on win32 */ -- G_SPAWN_DO_NOT_REAP_CHILD | -- G_SPAWN_SEARCH_PATH | -- /* dbus-daemon will not abuse our descriptors, and -- * passing this means we can use posix_spawn() for speed */ -- G_SPAWN_LEAVE_DESCRIPTORS_OPEN, -- NULL, -- NULL, -- &self->priv->bus_pid, -- NULL, -- &self->priv->bus_stdout_fd, -- NULL, -- &error); -+ g_spawn_async_with_pipes_and_fds (NULL, -+ argv, -+ NULL, -+ /* We Need this to get the pid returned on win32 */ -+ G_SPAWN_DO_NOT_REAP_CHILD | -+ G_SPAWN_SEARCH_PATH | -+ /* dbus-daemon will not abuse our descriptors, and -+ * passing this means we can use posix_spawn() for speed */ -+ G_SPAWN_LEAVE_DESCRIPTORS_OPEN, -+ NULL, NULL, -+ -1, -1, -1, -+ &pipe_fds[1], &pipe_fds[1], 1, -+ &self->priv->bus_pid, -+ NULL, NULL, NULL, -+ &error); - g_assert_no_error (error); - - _g_test_watcher_add_pid (self->priv->bus_pid); - -- /* Read bus address from daemon' stdout. We have to be careful to avoid -- * closing the FD, as it is passed to any D-Bus service activated processes, -- * and if we close it, they will get a SIGPIPE and die when they try to write -- * to their stdout. */ -- stdout_fd2 = dup (self->priv->bus_stdout_fd); -- g_assert_cmpint (stdout_fd2, >=, 0); -- channel = g_io_channel_unix_new (stdout_fd2); -- -+ /* Read bus address from pipe */ -+ channel = g_io_channel_unix_new (pipe_fds[0]); -+ pipe_fds[0] = -1; -+ g_io_channel_set_close_on_unref (channel, TRUE); - g_io_channel_read_line (channel, &self->priv->bus_address, NULL, - &termpos, &error); - g_assert_no_error (error); - self->priv->bus_address[termpos] = '\0'; -+ close (pipe_fds[1]); -+ pipe_fds[1] = -1; - - /* start dbus-monitor */ - if (g_getenv ("G_DBUS_MONITOR") != NULL) -@@ -671,6 +701,7 @@ start_daemon (GTestDBus *self) - if (g_unlink (config_path) != 0) - g_assert_not_reached (); - -+ g_free (print_address); - g_free (config_path); - g_free (config_arg); - } -@@ -687,8 +718,6 @@ stop_daemon (GTestDBus *self) - _g_test_watcher_remove_pid (self->priv->bus_pid); - g_spawn_close_pid (self->priv->bus_pid); - self->priv->bus_pid = 0; -- close (self->priv->bus_stdout_fd); -- self->priv->bus_stdout_fd = -1; - - g_free (self->priv->bus_address); - self->priv->bus_address = NULL; --- -GitLab diff --git a/patch/backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch b/patch/backport-gtestutils-Add-G_TEST_SUBPROCESS_DEFAULT.patch new file mode 100644 index 0000000000000000000000000000000000000000..78b0bccc8435dd4ad428c57cb12b8381ffe8d80d --- /dev/null +++ b/patch/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/patch/backport-gthread-posix-Free-a-memory-leak-on-error-path.patch b/patch/backport-gthread-posix-Free-a-memory-leak-on-error-path.patch deleted file mode 100644 index 41232948f4955d1380de97023bdd3f02e375280d..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gtype-Add-G_TYPE_FLAG_NONE.patch b/patch/backport-gtype-Add-G_TYPE_FLAG_NONE.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f03059311dc4194c7d99f4e492f0ec54b6db35f --- /dev/null +++ b/patch/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/patch/backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch b/patch/backport-gtype-Fix-pointer-being-dereferenced-despite-NULL-check.patch deleted file mode 100644 index 4877e527a9827c3319681bb46141f0674f87432b..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch b/patch/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch deleted file mode 100644 index c511c7e30d38febeba2d1ac4c3fdaab8b8993574..0000000000000000000000000000000000000000 --- a/patch/backport-gunixmounts-Add-cache-to-g_unix_mount_points_get.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 36f7684d56c5d6182398b5db992c1e81ef6cb2f5 Mon Sep 17 00:00:00 2001 -From: Rozhuk Ivan -Date: Sun, 18 Oct 2020 03:06:46 +0300 -Subject: [PATCH] gunixmounts: Add cache to g_unix_mount_points_get() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -`_g_get_unix_mount_points()` parses `/etc/fstab` every time it’s called, -so caching the result can improve performance when mounts are queried -frequently. - -The cache will remain in memory until `/etc/fstab` is next modified. -This means that the final copy of the cache will be deliberately -‘leaked’ on process exit. - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/36f7684d56c5d6182398b5db992c1e81ef6cb2f5 - ---- - gio/gunixmounts.c | 31 +++++++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) - -diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c -index ecfa61de86..9c8ef5d666 100644 ---- a/gio/gunixmounts.c -+++ b/gio/gunixmounts.c -@@ -1666,6 +1666,14 @@ g_unix_mount_for (const char *file_path, - return entry; - } - -+static gpointer -+copy_mount_point_cb (gconstpointer src, -+ gpointer data) -+{ -+ GUnixMountPoint *src_mount_point = (GUnixMountPoint *) src; -+ return g_unix_mount_point_copy (src_mount_point); -+} -+ - /** - * g_unix_mount_points_get: - * @time_read: (out) (optional): guint64 to contain a timestamp. -@@ -1681,10 +1689,29 @@ g_unix_mount_for (const char *file_path, - GList * - g_unix_mount_points_get (guint64 *time_read) - { -+ static GList *mnt_pts_last = NULL; -+ static guint64 time_read_last = 0; -+ GList *mnt_pts = NULL; -+ guint64 time_read_now; -+ G_LOCK_DEFINE_STATIC (unix_mount_points); -+ -+ G_LOCK (unix_mount_points); -+ -+ time_read_now = get_mount_points_timestamp (); -+ if (time_read_now != time_read_last || mnt_pts_last == NULL) -+ { -+ time_read_last = time_read_now; -+ g_list_free_full (mnt_pts_last, (GDestroyNotify) g_unix_mount_point_free); -+ mnt_pts_last = _g_get_unix_mount_points (); -+ } -+ mnt_pts = g_list_copy_deep (mnt_pts_last, copy_mount_point_cb, NULL); -+ -+ G_UNLOCK (unix_mount_points); -+ - if (time_read) -- *time_read = get_mount_points_timestamp (); -+ *time_read = time_read_now; - -- return _g_get_unix_mount_points (); -+ return mnt_pts; - } - - /** --- -GitLab - diff --git a/patch/backport-gutf8-add-string-length-check.patch b/patch/backport-gutf8-add-string-length-check.patch deleted file mode 100644 index 93603952b9dd3e810deb3f7262772dfc127ce5ad..0000000000000000000000000000000000000000 --- a/patch/backport-gutf8-add-string-length-check.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001 -From: Chen Guanqiao -Date: Thu, 11 Nov 2021 01:04:38 +0800 -Subject: [PATCH] gutf8: add string length check when ending character offset - is -1 - -Some function such as atk_text_get_text, use -1 to indicate the end of the -string. And an crash occurs when the -1 is passed to g_utf8_substring. - -Call Trace: - 0 __memmove_avx_unaligned_erms - 1 memcpy - 2 g_utf8_substring - 3 impl_GetText - 4 handle_other - 5 handle_message - 6 _dbus_object_tree_dispatch_and_unlock - 7 dbus_connection_dispatch - 8 dbus_connection_dispatch - 9 () - 10 g_main_dispatch - 11 g_main_context_dispatch - 12 g_main_context_iterate - 13 g_main_context_iteration - 14 g_application_run - 15 main - -Signed-off-by: Chen Guanqiao - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/9adbdd45d7101405eb05487bdf6a2015af9f8afd - ---- - glib/gutf8.c | 19 +++++++++++++++++-- - glib/tests/utf8-misc.c | 4 ++++ - 2 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/glib/gutf8.c b/glib/gutf8.c -index 7d053540d6..9097f690b3 100644 ---- a/glib/gutf8.c -+++ b/glib/gutf8.c -@@ -271,11 +271,15 @@ g_utf8_strlen (const gchar *p, - * g_utf8_substring: - * @str: a UTF-8 encoded string - * @start_pos: a character offset within @str -- * @end_pos: another character offset within @str -+ * @end_pos: another character offset within @str, -+ * or `-1` to indicate the end of the string - * - * Copies a substring out of a UTF-8 encoded string. - * The substring will contain @end_pos - @start_pos characters. - * -+ * Since GLib 2.72, `-1` can be passed to @end_pos to indicate the -+ * end of the string. -+ * - * Returns: (transfer full): a newly allocated copy of the requested - * substring. Free with g_free() when no longer needed. - * -@@ -288,8 +292,19 @@ g_utf8_substring (const gchar *str, - { - gchar *start, *end, *out; - -+ g_return_val_if_fail (end_pos >= start_pos || end_pos == -1, NULL); -+ - start = g_utf8_offset_to_pointer (str, start_pos); -- end = g_utf8_offset_to_pointer (start, end_pos - start_pos); -+ -+ if (end_pos == -1) -+ { -+ glong length = g_utf8_strlen (start, -1); -+ end = g_utf8_offset_to_pointer (start, length); -+ } -+ else -+ { -+ end = g_utf8_offset_to_pointer (start, end_pos - start_pos); -+ } - - out = g_malloc (end - start + 1); - memcpy (out, start, end - start); -diff --git a/glib/tests/utf8-misc.c b/glib/tests/utf8-misc.c -index 7a8c37448b..c137294229 100644 ---- a/glib/tests/utf8-misc.c -+++ b/glib/tests/utf8-misc.c -@@ -128,6 +128,10 @@ test_utf8_substring (void) - r = g_utf8_substring ("abc\xe2\x82\xa0gh\xe2\x82\xa4", 2, 5); - g_assert_cmpstr (r, ==, "c\xe2\x82\xa0g"); - g_free (r); -+ -+ r = g_utf8_substring ("abcd", 1, -1); -+ g_assert_cmpstr (r, ==, "bcd"); -+ g_free (r); - } - - static void --- -GitLab - diff --git a/patch/backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch b/patch/backport-gutils-Avoid-segfault-in-g_get_user_database_entry.patch deleted file mode 100644 index 3e978a0092f77fb069b226379ab78286f4101198..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch b/patch/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc5e9738da700cee7be661bdbd626fd237c4a8e2 --- /dev/null +++ b/patch/backport-gutils-Fix-an-unlikely-minor-leak-in-g_build_user_data_dir.patch @@ -0,0 +1,31 @@ +From 1a979ab4947fc259af01ea65263aaa4d417553fb Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Tue, 14 Nov 2023 11:00:21 +0000 +Subject: [PATCH] gutils: Fix an unlikely minor leak in g_build_user_data_dir() + +A leak can happen if the `data_dir` is the empty string. + +See https://gitlab.gnome.org/GNOME/glib/-/jobs/3294034 + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/1a979ab4947fc259af01ea65263aaa4d417553fb + +Signed-off-by: Philip Withnall +--- + glib/gutils.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/glib/gutils.c b/glib/gutils.c +index dfe115843e..ffc7d750c7 100644 +--- a/glib/gutils.c ++++ b/glib/gutils.c +@@ -1883,6 +1883,7 @@ g_build_user_data_dir (void) + if (!data_dir || !data_dir[0]) + { + gchar *home_dir = g_build_home_dir (); ++ g_free (data_dir); + data_dir = g_build_filename (home_dir, ".local", "share", NULL); + g_free (home_dir); + } +-- +GitLab \ No newline at end of file diff --git a/patch/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch b/patch/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch deleted file mode 100644 index 405164e330178d548c27da8f7dbdd90b170913a7..0000000000000000000000000000000000000000 --- a/patch/backport-gutils-Fix-g_find_program_in_path-to-return-an-absolute-path.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 78dc1cc3cd669e9fb92ae7847bab2b308c0a8628 Mon Sep 17 00:00:00 2001 -From: Christoph Niethammer -Date: Thu, 27 Jan 2022 03:54:01 +0100 -Subject: [PATCH] gutils: Fix g_find_program_in_path() to return an absolute - path - -Fix a possibility of returning a relative path, in case PATH contains -a relative path. According to the doc, the function should return an -absolute path. - -Signed-off-by: Christoph Niethammer - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/78dc1cc3cd669e9fb92ae7847bab2b308c0a8628 - ---- - glib/gutils.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/glib/gutils.c b/glib/gutils.c -index 6652d0ba05..6cc4506073 100644 ---- a/glib/gutils.c -+++ b/glib/gutils.c -@@ -456,7 +456,14 @@ g_find_program_in_path (const gchar *program) - !g_file_test (startp, G_FILE_TEST_IS_DIR)) - { - gchar *ret; -- ret = g_strdup (startp); -+ if (g_path_is_absolute (startp)) { -+ ret = g_strdup (startp); -+ } else { -+ gchar *cwd = NULL; -+ cwd = g_get_current_dir (); -+ ret = g_build_filename (cwd, startp, NULL); -+ g_free (cwd); -+ } - g_free (freeme); - #ifdef G_OS_WIN32 - g_free ((gchar *) path_copy); --- -GitLab diff --git a/patch/backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch b/patch/backport-gvariant-Fix-memory-leak-on-a-TYPE-CHECK-failure.patch deleted file mode 100644 index 50392fc47533342e7529139adfca2cf627664eac..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch b/patch/backport-gvariant-Fix-pointers-being-dereferenced-despite-NULL-checks.patch deleted file mode 100644 index 29217873ea7ccf6e7020a389d6d87c2f53c70caf..0000000000000000000000000000000000000000 --- a/patch/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/patch/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch b/patch/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch deleted file mode 100644 index 447cbf9ab6c788e20ecd47128c5c9d18f4825a14..0000000000000000000000000000000000000000 --- a/patch/backport-gvariant-serialiser-Prevent-unbounded-recursion.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 77233f6f0779fe0c1cb48861d7deded4ae413567 Mon Sep 17 00:00:00 2001 -From: Sebastian Wilhelmi -Date: Thu, 6 Jan 2022 20:50:34 +0000 -Subject: [PATCH] gvariant-serialiser: Prevent unbounded recursion in - is_normal() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This fixes a bug in 7c4e6e9fbe473de0401c778c6b0c4aad27d5145a. - -The original approach in that commit accidentally only checked the depth -at the leaf nodes in the variant tree, whereas actually the depth should -be checked before recursing to avoid stack overflow. - -It neglected to consider that `g_variant_serialised_is_normal()` would -be recursed into by some of the `DISPATCH(_is_normal)` cases. When that -happened, the depth check was after the recursion so couldn鈥檛 prevent a -stack overflow. - -Fixes: #2572 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/77233f6f0779fe0c1cb48861d7deded4ae413567 - ---- - glib/gvariant-serialiser.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/glib/gvariant-serialiser.c b/glib/gvariant-serialiser.c -index 832a8fdc2a..7b13381b6f 100644 ---- a/glib/gvariant-serialiser.c -+++ b/glib/gvariant-serialiser.c -@@ -1587,6 +1587,9 @@ g_variant_serialised_byteswap (GVariantSerialised serialised) - gboolean - g_variant_serialised_is_normal (GVariantSerialised serialised) - { -+ if (serialised.depth >= G_VARIANT_MAX_RECURSION_DEPTH) -+ return FALSE; -+ - DISPATCH_CASES (serialised.type_info, - - return gvs_/**/,/**/_is_normal (serialised); -@@ -1595,8 +1598,6 @@ g_variant_serialised_is_normal (GVariantSerialised serialised) - - if (serialised.data == NULL) - return FALSE; -- if (serialised.depth >= G_VARIANT_MAX_RECURSION_DEPTH) -- return FALSE; - - /* some hard-coded terminal cases */ - switch (g_variant_type_info_get_type_char (serialised.type_info)) --- -GitLab diff --git a/patch/backport-lib-openharmony-glib.patch b/patch/backport-openharmony-adapt.patch similarity index 87% rename from patch/backport-lib-openharmony-glib.patch rename to patch/backport-openharmony-adapt.patch index 5e1b9080754b35f39239a2352798cc08836a2ced..e4f9e1abf37887e70f70ac3fdaf58c503cfc7cc9 100644 --- a/patch/backport-lib-openharmony-glib.patch +++ b/patch/backport-openharmony-adapt.patch @@ -1,9 +1,9 @@ diff --git a/config.h b/config.h new file mode 100644 -index 0000000..0b4fb17 +index 0000000..da224eb --- /dev/null +++ b/config.h -@@ -0,0 +1,430 @@ +@@ -0,0 +1,428 @@ +/* + * Autogenerated by the Meson build system. + * Do not edit, your changes will be lost. @@ -32,21 +32,21 @@ index 0000000..0b4fb17 +#define ENABLE_NLS 1 +#endif + -+#define EXEEXT ++#define EXEEXT + +#define GETTEXT_PACKAGE "glib20" + -+#define GLIB_BINARY_AGE 6801 ++#define GLIB_BINARY_AGE 7202 + -+#define GLIB_INTERFACE_AGE 1 ++#define GLIB_INTERFACE_AGE 2 + +#define GLIB_LOCALE_DIR "/usr/local/share/locale" + +#define GLIB_MAJOR_VERSION 2 + -+#define GLIB_MICRO_VERSION 1 ++#define GLIB_MICRO_VERSION 2 + -+#define GLIB_MINOR_VERSION 68 ++#define GLIB_MINOR_VERSION 72 + +#define G_VA_COPY va_copy + @@ -68,6 +68,8 @@ index 0000000..0b4fb17 + +#define HAVE_DIRENT_H 1 + ++#define HAVE_DN_COMP 1 ++ +#define HAVE_ENDMNTENT 1 + +#define HAVE_ENDSERVENT 1 @@ -140,8 +142,6 @@ index 0000000..0b4fb17 + +#define HAVE_LINK 1 + -+#define HAVE_LINUX_MAGIC_H 1 -+ +#define HAVE_LOCALE_H 1 + +#define HAVE_LOCALTIME_R 1 @@ -204,8 +204,6 @@ index 0000000..0b4fb17 + +#define HAVE_RECVMMSG 1 + -+#define HAVE_RES_INIT 1 -+ +#define HAVE_RES_NCLOSE 1 + +#define HAVE_RES_NINIT 1 @@ -370,13 +368,13 @@ index 0000000..0b4fb17 + +#define PACKAGE_NAME "glib" + -+#define PACKAGE_STRING "glib 2.68.1" ++#define PACKAGE_STRING "glib 2.72.2" + +#define PACKAGE_TARNAME "glib" + +#define PACKAGE_URL "" + -+#define PACKAGE_VERSION "2.68.1" ++#define PACKAGE_VERSION "2.72.2" + +#define SIZEOF_CHAR 1 + @@ -434,184 +432,16 @@ index 0000000..0b4fb17 + +#define gl_unused + -diff --git a/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.tx b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.tx -new file mode 100644 -index 0000000..1e3b8b8 ---- /dev/null -+++ b/docs/reference/gio/gdbus-object-manager-example/gdbus-object-manager-example-sections.tx -@@ -0,0 +1,161 @@ -+
-+ExampleAnimal -+ExampleAnimal -+ExampleAnimal -+ExampleAnimalIface -+example_animal_interface_info -+example_animal_override_properties -+example_animal_call_poke -+example_animal_call_poke_finish -+example_animal_call_poke_sync -+example_animal_complete_poke -+example_animal_emit_jumped -+example_animal_get_mood -+example_animal_get_foo -+example_animal_get_bar -+example_animal_dup_mood -+example_animal_dup_foo -+example_animal_dup_bar -+example_animal_set_mood -+example_animal_set_foo -+example_animal_set_bar -+ExampleAnimalProxy -+ExampleAnimalProxyClass -+example_animal_proxy_new -+example_animal_proxy_new_finish -+example_animal_proxy_new_sync -+example_animal_proxy_new_for_bus -+example_animal_proxy_new_for_bus_finish -+example_animal_proxy_new_for_bus_sync -+ExampleAnimalSkeleton -+ExampleAnimalSkeletonClass -+example_animal_skeleton_new -+ -+example_animal_get_type -+example_animal_proxy_get_type -+example_animal_skeleton_get_type -+ExampleAnimalSkeletonPrivate -+ExampleAnimalProxyPrivate -+EXAMPLE_TYPE_ANIMAL -+EXAMPLE_TYPE_ANIMAL_PROXY -+EXAMPLE_TYPE_ANIMAL_SKELETON -+EXAMPLE_ANIMAL -+EXAMPLE_ANIMAL_GET_IFACE -+EXAMPLE_ANIMAL_PROXY -+EXAMPLE_ANIMAL_PROXY_CLASS -+EXAMPLE_ANIMAL_PROXY_GET_CLASS -+EXAMPLE_ANIMAL_SKELETON -+EXAMPLE_ANIMAL_SKELETON_CLASS -+EXAMPLE_ANIMAL_SKELETON_GET_CLASS -+EXAMPLE_IS_ANIMAL -+EXAMPLE_IS_ANIMAL_PROXY -+EXAMPLE_IS_ANIMAL_PROXY_CLASS -+EXAMPLE_IS_ANIMAL_SKELETON -+EXAMPLE_IS_ANIMAL_SKELETON_CLASS -+
-+ -+
-+ExampleCat -+ExampleCat -+ExampleCat -+ExampleCatIface -+example_cat_interface_info -+example_cat_override_properties -+ExampleCatProxy -+ExampleCatProxyClass -+example_cat_proxy_new -+example_cat_proxy_new_finish -+example_cat_proxy_new_sync -+example_cat_proxy_new_for_bus -+example_cat_proxy_new_for_bus_finish -+example_cat_proxy_new_for_bus_sync -+ExampleCatSkeleton -+ExampleCatSkeletonClass -+example_cat_skeleton_new -+ -+example_cat_get_type -+example_cat_proxy_get_type -+example_cat_skeleton_get_type -+ExampleCatProxyPrivate -+ExampleCatSkeletonPrivate -+EXAMPLE_TYPE_CAT -+EXAMPLE_TYPE_CAT_PROXY -+EXAMPLE_TYPE_CAT_SKELETON -+EXAMPLE_CAT -+EXAMPLE_CAT_GET_IFACE -+EXAMPLE_CAT_PROXY -+EXAMPLE_CAT_PROXY_CLASS -+EXAMPLE_CAT_PROXY_GET_CLASS -+EXAMPLE_CAT_SKELETON -+EXAMPLE_CAT_SKELETON_CLASS -+EXAMPLE_CAT_SKELETON_GET_CLASS -+EXAMPLE_IS_CAT -+EXAMPLE_IS_CAT_PROXY -+EXAMPLE_IS_CAT_PROXY_CLASS -+EXAMPLE_IS_CAT_SKELETON -+EXAMPLE_IS_CAT_SKELETON_CLASS -+
-+ -+
-+ExampleObject -+ExampleObject -+ExampleObject -+ExampleObjectIface -+example_object_get_animal -+example_object_get_cat -+example_object_peek_animal -+example_object_peek_cat -+ExampleObjectProxy -+ExampleObjectProxyClass -+example_object_proxy_new -+ExampleObjectSkeleton -+ExampleObjectSkeletonClass -+example_object_skeleton_new -+example_object_skeleton_set_animal -+example_object_skeleton_set_cat -+ -+example_object_get_type -+example_object_proxy_get_type -+example_object_skeleton_get_type -+ExampleObjectProxyPrivate -+ExampleObjectSkeletonPrivate -+EXAMPLE_IS_OBJECT -+EXAMPLE_IS_OBJECT_PROXY -+EXAMPLE_IS_OBJECT_PROXY_CLASS -+EXAMPLE_IS_OBJECT_SKELETON -+EXAMPLE_IS_OBJECT_SKELETON_CLASS -+EXAMPLE_OBJECT -+EXAMPLE_OBJECT_GET_IFACE -+EXAMPLE_OBJECT_PROXY -+EXAMPLE_OBJECT_PROXY_CLASS -+EXAMPLE_OBJECT_PROXY_GET_CLASS -+EXAMPLE_OBJECT_SKELETON -+EXAMPLE_OBJECT_SKELETON_CLASS -+EXAMPLE_OBJECT_SKELETON_GET_CLASS -+EXAMPLE_TYPE_OBJECT -+EXAMPLE_TYPE_OBJECT_PROXY -+EXAMPLE_TYPE_OBJECT_SKELETON -+
-+ -+
-+ExampleObjectManagerClient -+ExampleObjectManagerClient -+ExampleObjectManagerClient -+ExampleObjectManagerClientClass -+example_object_manager_client_get_proxy_type -+example_object_manager_client_new -+example_object_manager_client_new_finish -+example_object_manager_client_new_sync -+example_object_manager_client_new_for_bus -+example_object_manager_client_new_for_bus_finish -+example_object_manager_client_new_for_bus_sync -+ -+example_object_manager_client_get_type -+EXAMPLE_IS_OBJECT_MANAGER_CLIENT -+EXAMPLE_IS_OBJECT_MANAGER_CLIENT_CLASS -+EXAMPLE_OBJECT_MANAGER_CLIENT -+EXAMPLE_OBJECT_MANAGER_CLIENT_CLASS -+EXAMPLE_OBJECT_MANAGER_CLIENT_GET_CLASS -+EXAMPLE_TYPE_OBJECT_MANAGER_CLIENT -+ExampleObjectManagerClientPrivate -+
diff --git a/gio/gconstructor_as_data.h b/gio/gconstructor_as_data.h new file mode 100644 -index 0000000..35dc395 +index 0000000..b447ff5 --- /dev/null +++ b/gio/gconstructor_as_data.h @@ -0,0 +1 @@ -+const char gconstructor_code[] = "\x2f\x2a\x0a\x20\x20\x49\x66\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x69\x73\x20\x74\x72\x75\x65\x20\x74\x68\x65\x6e\x20\x74\x68\x65\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x20\x73\x75\x70\x70\x6f\x72\x74\x20\x2a\x62\x6f\x74\x68\x2a\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x61\x6e\x64\x0a\x20\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x2c\x20\x69\x6e\x20\x61\x20\x75\x73\x61\x62\x6c\x65\x20\x77\x61\x79\x2c\x20\x69\x6e\x63\x6c\x75\x64\x69\x6e\x67\x20\x65\x2e\x67\x2e\x20\x6f\x6e\x20\x6c\x69\x62\x72\x61\x72\x79\x20\x75\x6e\x6c\x6f\x61\x64\x2e\x20\x49\x66\x20\x6e\x6f\x74\x20\x79\x6f\x75\x27\x72\x65\x20\x6f\x6e\x0a\x20\x20\x79\x6f\x75\x72\x20\x6f\x77\x6e\x2e\x0a\x0a\x20\x20\x53\x6f\x6d\x65\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x73\x20\x6e\x65\x65\x64\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x74\x68\x69\x73\x2c\x20\x77\x68\x69\x63\x68\x20\x64\x6f\x65\x73\x20\x6e\x6f\x74\x20\x77\x6f\x72\x6b\x20\x77\x69\x74\x68\x20\x6d\x61\x63\x72\x6f\x73\x2c\x0a\x20\x20\x73\x6f\x20\x74\x68\x65\x20\x77\x61\x79\x20\x79\x6f\x75\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x75\x73\x65\x20\x74\x68\x69\x73\x20\x69\x73\x20\x28\x66\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x29\x3a\x0a\x0a\x20\x20\x23\x69\x66\x64\x65\x66\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x0a\x20\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x0a\x20\x20\x23\x65\x6e\x64\x69\x66\x0a\x20\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x0a\x20\x20\x20\x2e\x2e\x2e\x0a\x20\x20\x7d\x0a\x0a\x2a\x2f\x0a\x0a\x23\x69\x66\x6e\x64\x65\x66\x20\x5f\x5f\x47\x54\x4b\x5f\x44\x4f\x43\x5f\x49\x47\x4e\x4f\x52\x45\x5f\x5f\x0a\x0a\x23\x69\x66\x20\x20\x5f\x5f\x47\x4e\x55\x43\x5f\x5f\x20\x3e\x20\x32\x20\x7c\x7c\x20\x28\x5f\x5f\x47\x4e\x55\x43\x5f\x5f\x20\x3d\x3d\x20\x32\x20\x26\x26\x20\x5f\x5f\x47\x4e\x55\x43\x5f\x4d\x49\x4e\x4f\x52\x5f\x5f\x20\x3e\x3d\x20\x37\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\x5f\x28\x28\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x29\x20\x5f\x66\x75\x6e\x63\x20\x28\x76\x6f\x69\x64\x29\x3b\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\x5f\x28\x28\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x29\x20\x5f\x66\x75\x6e\x63\x20\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x29\x20\x26\x26\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x20\x3e\x3d\x20\x31\x35\x30\x30\x29\x0a\x2f\x2a\x20\x56\x69\x73\x75\x61\x6c\x20\x73\x74\x75\x64\x69\x6f\x20\x32\x30\x30\x38\x20\x61\x6e\x64\x20\x6c\x61\x74\x65\x72\x20\x68\x61\x73\x20\x5f\x50\x72\x61\x67\x6d\x61\x20\x2a\x2f\x0a\x0a\x23\x69\x6e\x63\x6c\x75\x64\x65\x20\x3c\x73\x74\x64\x6c\x69\x62\x2e\x68\x3e\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x2f\x2a\x20\x57\x65\x20\x64\x6f\x20\x73\x6f\x6d\x65\x20\x77\x65\x69\x72\x64\x20\x74\x68\x69\x6e\x67\x73\x20\x74\x6f\x20\x61\x76\x6f\x69\x64\x20\x74\x68\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x62\x65\x69\x6e\x67\x20\x6f\x70\x74\x69\x6d\x69\x7a\x65\x64\x0a\x20\x2a\x20\x61\x77\x61\x79\x20\x6f\x6e\x20\x56\x53\x32\x30\x31\x35\x20\x69\x66\x20\x57\x68\x6f\x6c\x65\x50\x72\x6f\x67\x72\x61\x6d\x4f\x70\x74\x69\x6d\x69\x7a\x61\x74\x69\x6f\x6e\x20\x69\x73\x20\x65\x6e\x61\x62\x6c\x65\x64\x2e\x20\x46\x69\x72\x73\x74\x20\x77\x65\x0a\x20\x2a\x20\x6d\x61\x6b\x65\x20\x61\x20\x72\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x74\x6f\x20\x74\x68\x65\x20\x61\x72\x72\x61\x79\x20\x66\x72\x6f\x6d\x20\x74\x68\x65\x20\x77\x72\x61\x70\x70\x65\x72\x20\x74\x6f\x20\x6d\x61\x6b\x65\x20\x73\x75\x72\x65\x20\x69\x74\x73\x0a\x20\x2a\x20\x72\x65\x66\x65\x72\x65\x6e\x63\x65\x73\x2e\x20\x54\x68\x65\x6e\x20\x77\x65\x20\x75\x73\x65\x20\x61\x20\x70\x72\x61\x67\x6d\x61\x20\x74\x6f\x20\x6d\x61\x6b\x65\x20\x73\x75\x72\x65\x20\x74\x68\x65\x20\x77\x72\x61\x70\x70\x65\x72\x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x0a\x20\x2a\x20\x73\x79\x6d\x62\x6f\x6c\x20\x69\x73\x20\x61\x6c\x77\x61\x79\x73\x20\x69\x6e\x63\x6c\x75\x64\x65\x64\x20\x61\x74\x20\x74\x68\x65\x20\x6c\x69\x6e\x6b\x20\x73\x74\x61\x67\x65\x2e\x20\x41\x6c\x73\x6f\x2c\x20\x74\x68\x65\x20\x73\x79\x6d\x62\x6f\x6c\x73\x0a\x20\x2a\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x62\x65\x20\x65\x78\x74\x65\x72\x6e\x20\x28\x62\x75\x74\x20\x6e\x6f\x74\x20\x64\x6c\x6c\x65\x78\x70\x6f\x72\x74\x29\x2c\x20\x65\x76\x65\x6e\x20\x74\x68\x6f\x75\x67\x68\x20\x74\x68\x65\x79\x20\x61\x72\x65\x20\x6e\x6f\x74\x0a\x20\x2a\x20\x72\x65\x61\x6c\x6c\x79\x20\x75\x73\x65\x64\x20\x66\x72\x6f\x6d\x20\x61\x6e\x6f\x74\x68\x65\x72\x20\x6f\x62\x6a\x65\x63\x74\x20\x66\x69\x6c\x65\x2e\x0a\x20\x2a\x2f\x0a\x0a\x2f\x2a\x20\x57\x65\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x61\x63\x63\x6f\x75\x6e\x74\x20\x66\x6f\x72\x20\x64\x69\x66\x66\x65\x72\x65\x6e\x63\x65\x73\x20\x62\x65\x74\x77\x65\x65\x6e\x20\x74\x68\x65\x20\x6d\x61\x6e\x67\x6c\x69\x6e\x67\x20\x6f\x66\x20\x73\x79\x6d\x62\x6f\x6c\x73\x0a\x20\x2a\x20\x66\x6f\x72\x20\x78\x38\x36\x20\x61\x6e\x64\x20\x78\x36\x34\x2f\x41\x52\x4d\x2f\x41\x52\x4d\x36\x34\x20\x70\x72\x6f\x67\x72\x61\x6d\x73\x2c\x20\x61\x73\x20\x73\x79\x6d\x62\x6f\x6c\x73\x20\x6f\x6e\x20\x78\x38\x36\x20\x61\x72\x65\x20\x70\x72\x65\x66\x69\x78\x65\x64\x0a\x20\x2a\x20\x77\x69\x74\x68\x20\x61\x6e\x20\x75\x6e\x64\x65\x72\x73\x63\x6f\x72\x65\x20\x62\x75\x74\x20\x73\x79\x6d\x62\x6f\x6c\x73\x20\x6f\x6e\x20\x78\x36\x34\x2f\x41\x52\x4d\x2f\x41\x52\x4d\x36\x34\x20\x61\x72\x65\x20\x6e\x6f\x74\x2e\x0a\x20\x2a\x2f\x0a\x23\x69\x66\x64\x65\x66\x20\x5f\x4d\x5f\x49\x58\x38\x36\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x20\x22\x5f\x22\x0a\x23\x65\x6c\x73\x65\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x20\x22\x22\x0a\x23\x65\x6e\x64\x69\x66\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x47\x5f\x4d\x53\x56\x43\x5f\x43\x54\x4f\x52\x20\x28\x5f\x66\x75\x6e\x63\x2c\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x47\x5f\x4d\x53\x56\x43\x5f\x44\x54\x4f\x52\x20\x28\x5f\x66\x75\x6e\x63\x2c\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x2c\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x65\x78\x74\x65\x72\x6e\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5c\x0a\x20\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x5f\x66\x75\x6e\x63\x28\x29\x3b\x20\x67\x5f\x73\x6c\x69\x73\x74\x5f\x66\x69\x6e\x64\x20\x28\x4e\x55\x4c\x4c\x2c\x20\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x63\x6f\x6d\x6d\x65\x6e\x74\x28\x6c\x69\x6e\x6b\x65\x72\x2c\x22\x2f\x69\x6e\x63\x6c\x75\x64\x65\x3a\x22\x20\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x20\x23\x20\x5f\x66\x75\x6e\x63\x20\x22\x5f\x77\x72\x61\x70\x70\x65\x72\x22\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x44\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x2c\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x65\x78\x74\x65\x72\x6e\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5c\x0a\x20\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x61\x74\x65\x78\x69\x74\x20\x28\x5f\x66\x75\x6e\x63\x29\x3b\x20\x67\x5f\x73\x6c\x69\x73\x74\x5f\x66\x69\x6e\x64\x20\x28\x4e\x55\x4c\x4c\x2c\x20\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x63\x6f\x6d\x6d\x65\x6e\x74\x28\x6c\x69\x6e\x6b\x65\x72\x2c\x22\x2f\x69\x6e\x63\x6c\x75\x64\x65\x3a\x22\x20\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x20\x23\x20\x5f\x66\x75\x6e\x63\x20\x22\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x22\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x2f\x2a\x20\x50\x72\x65\x20\x56\x69\x73\x75\x61\x6c\x20\x73\x74\x75\x64\x69\x6f\x20\x32\x30\x30\x38\x20\x6d\x75\x73\x74\x20\x75\x73\x65\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x73\x65\x63\x74\x69\x6f\x6e\x20\x2a\x2f\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x5f\x66\x75\x6e\x63\x28\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x28\x2a\x70\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x61\x74\x65\x78\x69\x74\x20\x28\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x28\x5f\x5f\x53\x55\x4e\x50\x52\x4f\x5f\x43\x29\x0a\x0a\x2f\x2a\x20\x54\x68\x69\x73\x20\x69\x73\x20\x6e\x6f\x74\x20\x74\x65\x73\x74\x65\x64\x2c\x20\x62\x75\x74\x20\x69\x20\x62\x65\x6c\x69\x65\x76\x65\x20\x69\x74\x20\x73\x68\x6f\x75\x6c\x64\x20\x77\x6f\x72\x6b\x2c\x20\x62\x61\x73\x65\x64\x20\x6f\x6e\x3a\x0a\x20\x2a\x20\x68\x74\x74\x70\x3a\x2f\x2f\x6f\x70\x65\x6e\x73\x6f\x75\x72\x63\x65\x2e\x61\x70\x70\x6c\x65\x2e\x63\x6f\x6d\x2f\x73\x6f\x75\x72\x63\x65\x2f\x4f\x70\x65\x6e\x53\x53\x4c\x30\x39\x38\x2f\x4f\x70\x65\x6e\x53\x53\x4c\x30\x39\x38\x2d\x33\x35\x2f\x73\x72\x63\x2f\x66\x69\x70\x73\x2f\x66\x69\x70\x73\x5f\x70\x72\x65\x6d\x61\x69\x6e\x2e\x63\x0a\x20\x2a\x2f\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x69\x6e\x69\x74\x28\x5f\x66\x75\x6e\x63\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x66\x69\x6e\x69\x28\x5f\x66\x75\x6e\x63\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x65\x6c\x73\x65\x0a\x0a\x2f\x2a\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x6e\x6f\x74\x20\x73\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x66\x6f\x72\x20\x74\x68\x69\x73\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x20\x2a\x2f\x0a\x0a\x23\x65\x6e\x64\x69\x66\x0a\x0a\x23\x65\x6e\x64\x69\x66\x20\x2f\x2a\x20\x5f\x5f\x47\x54\x4b\x5f\x44\x4f\x43\x5f\x49\x47\x4e\x4f\x52\x45\x5f\x5f\x20\x2a\x2f\x0a"; -\ No newline at end of file ++const char gconstructor_code[] = "\x2f\x2a\x20\x47\x4c\x49\x42\x20\x2d\x20\x4c\x69\x62\x72\x61\x72\x79\x20\x6f\x66\x20\x75\x73\x65\x66\x75\x6c\x20\x72\x6f\x75\x74\x69\x6e\x65\x73\x20\x66\x6f\x72\x20\x43\x20\x70\x72\x6f\x67\x72\x61\x6d\x6d\x69\x6e\x67\x0a\x20\x2a\x20\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\x43\x29\x20\x31\x39\x39\x35\x2d\x31\x39\x39\x37\x20\x20\x50\x65\x74\x65\x72\x20\x4d\x61\x74\x74\x69\x73\x2c\x20\x53\x70\x65\x6e\x63\x65\x72\x20\x4b\x69\x6d\x62\x61\x6c\x6c\x20\x61\x6e\x64\x20\x4a\x6f\x73\x68\x20\x4d\x61\x63\x44\x6f\x6e\x61\x6c\x64\x0a\x20\x2a\x0a\x20\x2a\x20\x54\x68\x69\x73\x20\x6c\x69\x62\x72\x61\x72\x79\x20\x69\x73\x20\x66\x72\x65\x65\x20\x73\x6f\x66\x74\x77\x61\x72\x65\x3b\x20\x79\x6f\x75\x20\x63\x61\x6e\x20\x72\x65\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x20\x69\x74\x20\x61\x6e\x64\x2f\x6f\x72\x0a\x20\x2a\x20\x6d\x6f\x64\x69\x66\x79\x20\x69\x74\x20\x75\x6e\x64\x65\x72\x20\x74\x68\x65\x20\x74\x65\x72\x6d\x73\x20\x6f\x66\x20\x74\x68\x65\x20\x47\x4e\x55\x20\x4c\x65\x73\x73\x65\x72\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x50\x75\x62\x6c\x69\x63\x0a\x20\x2a\x20\x4c\x69\x63\x65\x6e\x73\x65\x20\x61\x73\x20\x70\x75\x62\x6c\x69\x73\x68\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x46\x72\x65\x65\x20\x53\x6f\x66\x74\x77\x61\x72\x65\x20\x46\x6f\x75\x6e\x64\x61\x74\x69\x6f\x6e\x3b\x20\x65\x69\x74\x68\x65\x72\x0a\x20\x2a\x20\x76\x65\x72\x73\x69\x6f\x6e\x20\x32\x2e\x31\x20\x6f\x66\x20\x74\x68\x65\x20\x4c\x69\x63\x65\x6e\x73\x65\x2c\x20\x6f\x72\x20\x28\x61\x74\x20\x79\x6f\x75\x72\x20\x6f\x70\x74\x69\x6f\x6e\x29\x20\x61\x6e\x79\x20\x6c\x61\x74\x65\x72\x20\x76\x65\x72\x73\x69\x6f\x6e\x2e\x0a\x20\x2a\x0a\x20\x2a\x20\x54\x68\x69\x73\x20\x6c\x69\x62\x72\x61\x72\x79\x20\x69\x73\x20\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\x20\x69\x6e\x20\x74\x68\x65\x20\x68\x6f\x70\x65\x20\x74\x68\x61\x74\x20\x69\x74\x20\x77\x69\x6c\x6c\x20\x62\x65\x20\x75\x73\x65\x66\x75\x6c\x2c\x0a\x20\x2a\x20\x62\x75\x74\x20\x57\x49\x54\x48\x4f\x55\x54\x20\x41\x4e\x59\x20\x57\x41\x52\x52\x41\x4e\x54\x59\x3b\x20\x77\x69\x74\x68\x6f\x75\x74\x20\x65\x76\x65\x6e\x20\x74\x68\x65\x20\x69\x6d\x70\x6c\x69\x65\x64\x20\x77\x61\x72\x72\x61\x6e\x74\x79\x20\x6f\x66\x0a\x20\x2a\x20\x4d\x45\x52\x43\x48\x41\x4e\x54\x41\x42\x49\x4c\x49\x54\x59\x20\x6f\x72\x20\x46\x49\x54\x4e\x45\x53\x53\x20\x46\x4f\x52\x20\x41\x20\x50\x41\x52\x54\x49\x43\x55\x4c\x41\x52\x20\x50\x55\x52\x50\x4f\x53\x45\x2e\x09\x20\x53\x65\x65\x20\x74\x68\x65\x20\x47\x4e\x55\x0a\x20\x2a\x20\x4c\x65\x73\x73\x65\x72\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x50\x75\x62\x6c\x69\x63\x20\x4c\x69\x63\x65\x6e\x73\x65\x20\x66\x6f\x72\x20\x6d\x6f\x72\x65\x20\x64\x65\x74\x61\x69\x6c\x73\x2e\x0a\x20\x2a\x0a\x20\x2a\x20\x59\x6f\x75\x20\x73\x68\x6f\x75\x6c\x64\x20\x68\x61\x76\x65\x20\x72\x65\x63\x65\x69\x76\x65\x64\x20\x61\x20\x63\x6f\x70\x79\x20\x6f\x66\x20\x74\x68\x65\x20\x47\x4e\x55\x20\x4c\x65\x73\x73\x65\x72\x20\x47\x65\x6e\x65\x72\x61\x6c\x20\x50\x75\x62\x6c\x69\x63\x0a\x20\x2a\x20\x4c\x69\x63\x65\x6e\x73\x65\x20\x61\x6c\x6f\x6e\x67\x20\x77\x69\x74\x68\x20\x74\x68\x69\x73\x20\x6c\x69\x62\x72\x61\x72\x79\x3b\x20\x69\x66\x20\x6e\x6f\x74\x2c\x20\x73\x65\x65\x20\x3c\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x2f\x6c\x69\x63\x65\x6e\x73\x65\x73\x2f\x3e\x2e\x0a\x20\x2a\x2f\x0a\x0a\x2f\x2a\x0a\x20\x2a\x20\x4d\x6f\x64\x69\x66\x69\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x47\x4c\x69\x62\x20\x54\x65\x61\x6d\x20\x61\x6e\x64\x20\x6f\x74\x68\x65\x72\x73\x20\x31\x39\x39\x37\x2d\x32\x30\x30\x30\x2e\x20\x20\x53\x65\x65\x20\x74\x68\x65\x20\x41\x55\x54\x48\x4f\x52\x53\x0a\x20\x2a\x20\x66\x69\x6c\x65\x20\x66\x6f\x72\x20\x61\x20\x6c\x69\x73\x74\x20\x6f\x66\x20\x70\x65\x6f\x70\x6c\x65\x20\x6f\x6e\x20\x74\x68\x65\x20\x47\x4c\x69\x62\x20\x54\x65\x61\x6d\x2e\x20\x20\x53\x65\x65\x20\x74\x68\x65\x20\x43\x68\x61\x6e\x67\x65\x4c\x6f\x67\x0a\x20\x2a\x20\x66\x69\x6c\x65\x73\x20\x66\x6f\x72\x20\x61\x20\x6c\x69\x73\x74\x20\x6f\x66\x20\x63\x68\x61\x6e\x67\x65\x73\x2e\x20\x20\x54\x68\x65\x73\x65\x20\x66\x69\x6c\x65\x73\x20\x61\x72\x65\x20\x64\x69\x73\x74\x72\x69\x62\x75\x74\x65\x64\x20\x77\x69\x74\x68\x0a\x20\x2a\x20\x47\x4c\x69\x62\x20\x61\x74\x20\x66\x74\x70\x3a\x2f\x2f\x66\x74\x70\x2e\x67\x74\x6b\x2e\x6f\x72\x67\x2f\x70\x75\x62\x2f\x67\x74\x6b\x2f\x2e\x0a\x20\x2a\x2f\x0a\x0a\x23\x69\x66\x6e\x64\x65\x66\x20\x5f\x5f\x47\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x48\x5f\x5f\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x5f\x5f\x47\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x48\x5f\x5f\x0a\x0a\x2f\x2a\x0a\x20\x20\x49\x66\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x69\x73\x20\x74\x72\x75\x65\x20\x74\x68\x65\x6e\x20\x74\x68\x65\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x20\x73\x75\x70\x70\x6f\x72\x74\x20\x2a\x62\x6f\x74\x68\x2a\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x61\x6e\x64\x0a\x20\x20\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x2c\x20\x69\x6e\x20\x61\x20\x75\x73\x61\x62\x6c\x65\x20\x77\x61\x79\x2c\x20\x69\x6e\x63\x6c\x75\x64\x69\x6e\x67\x20\x65\x2e\x67\x2e\x20\x6f\x6e\x20\x6c\x69\x62\x72\x61\x72\x79\x20\x75\x6e\x6c\x6f\x61\x64\x2e\x20\x49\x66\x20\x6e\x6f\x74\x20\x79\x6f\x75\x27\x72\x65\x20\x6f\x6e\x0a\x20\x20\x79\x6f\x75\x72\x20\x6f\x77\x6e\x2e\x0a\x0a\x20\x20\x53\x6f\x6d\x65\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x73\x20\x6e\x65\x65\x64\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x74\x68\x69\x73\x2c\x20\x77\x68\x69\x63\x68\x20\x64\x6f\x65\x73\x20\x6e\x6f\x74\x20\x77\x6f\x72\x6b\x20\x77\x69\x74\x68\x20\x6d\x61\x63\x72\x6f\x73\x2c\x0a\x20\x20\x73\x6f\x20\x74\x68\x65\x20\x77\x61\x79\x20\x79\x6f\x75\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x75\x73\x65\x20\x74\x68\x69\x73\x20\x69\x73\x20\x28\x66\x6f\x72\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x29\x3a\x0a\x0a\x20\x20\x23\x69\x66\x64\x65\x66\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x0a\x20\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x0a\x20\x20\x23\x65\x6e\x64\x69\x66\x0a\x20\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x6d\x79\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x0a\x20\x20\x20\x2e\x2e\x2e\x0a\x20\x20\x7d\x0a\x0a\x2a\x2f\x0a\x0a\x23\x69\x66\x6e\x64\x65\x66\x20\x5f\x5f\x47\x54\x4b\x5f\x44\x4f\x43\x5f\x49\x47\x4e\x4f\x52\x45\x5f\x5f\x0a\x0a\x23\x69\x66\x20\x20\x5f\x5f\x47\x4e\x55\x43\x5f\x5f\x20\x3e\x20\x32\x20\x7c\x7c\x20\x28\x5f\x5f\x47\x4e\x55\x43\x5f\x5f\x20\x3d\x3d\x20\x32\x20\x26\x26\x20\x5f\x5f\x47\x4e\x55\x43\x5f\x4d\x49\x4e\x4f\x52\x5f\x5f\x20\x3e\x3d\x20\x37\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\x5f\x28\x28\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x29\x20\x5f\x66\x75\x6e\x63\x20\x28\x76\x6f\x69\x64\x29\x3b\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x5f\x61\x74\x74\x72\x69\x62\x75\x74\x65\x5f\x5f\x28\x28\x64\x65\x73\x74\x72\x75\x63\x74\x6f\x72\x29\x29\x20\x5f\x66\x75\x6e\x63\x20\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x29\x20\x26\x26\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x20\x3e\x3d\x20\x31\x35\x30\x30\x29\x0a\x2f\x2a\x20\x56\x69\x73\x75\x61\x6c\x20\x73\x74\x75\x64\x69\x6f\x20\x32\x30\x30\x38\x20\x61\x6e\x64\x20\x6c\x61\x74\x65\x72\x20\x68\x61\x73\x20\x5f\x50\x72\x61\x67\x6d\x61\x20\x2a\x2f\x0a\x0a\x2f\x2a\x0a\x20\x2a\x20\x4f\x6e\x6c\x79\x20\x74\x72\x79\x20\x74\x6f\x20\x69\x6e\x63\x6c\x75\x64\x65\x20\x67\x73\x6c\x69\x73\x74\x2e\x68\x20\x69\x66\x20\x6e\x6f\x74\x20\x61\x6c\x72\x65\x61\x64\x79\x20\x69\x6e\x63\x6c\x75\x64\x65\x64\x20\x76\x69\x61\x20\x67\x6c\x69\x62\x2e\x68\x2c\x0a\x20\x2a\x20\x73\x6f\x20\x74\x68\x61\x74\x20\x69\x74\x65\x6d\x73\x20\x75\x73\x69\x6e\x67\x20\x67\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x2e\x68\x20\x6f\x75\x74\x73\x69\x64\x65\x20\x6f\x66\x20\x47\x4c\x69\x62\x20\x28\x73\x75\x63\x68\x20\x61\x73\x0a\x20\x2a\x20\x47\x52\x65\x73\x6f\x75\x72\x63\x65\x73\x29\x20\x63\x6f\x6e\x74\x69\x6e\x75\x65\x20\x74\x6f\x20\x62\x75\x69\x6c\x64\x20\x70\x72\x6f\x70\x65\x72\x6c\x79\x2e\x0a\x20\x2a\x2f\x0a\x23\x69\x66\x6e\x64\x65\x66\x20\x5f\x5f\x47\x5f\x4c\x49\x42\x5f\x48\x5f\x5f\x0a\x23\x69\x6e\x63\x6c\x75\x64\x65\x20\x22\x67\x73\x6c\x69\x73\x74\x2e\x68\x22\x0a\x23\x65\x6e\x64\x69\x66\x0a\x0a\x23\x69\x6e\x63\x6c\x75\x64\x65\x20\x3c\x73\x74\x64\x6c\x69\x62\x2e\x68\x3e\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x2f\x2a\x20\x57\x65\x20\x64\x6f\x20\x73\x6f\x6d\x65\x20\x77\x65\x69\x72\x64\x20\x74\x68\x69\x6e\x67\x73\x20\x74\x6f\x20\x61\x76\x6f\x69\x64\x20\x74\x68\x65\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x62\x65\x69\x6e\x67\x20\x6f\x70\x74\x69\x6d\x69\x7a\x65\x64\x0a\x20\x2a\x20\x61\x77\x61\x79\x20\x6f\x6e\x20\x56\x53\x32\x30\x31\x35\x20\x69\x66\x20\x57\x68\x6f\x6c\x65\x50\x72\x6f\x67\x72\x61\x6d\x4f\x70\x74\x69\x6d\x69\x7a\x61\x74\x69\x6f\x6e\x20\x69\x73\x20\x65\x6e\x61\x62\x6c\x65\x64\x2e\x20\x46\x69\x72\x73\x74\x20\x77\x65\x0a\x20\x2a\x20\x6d\x61\x6b\x65\x20\x61\x20\x72\x65\x66\x65\x72\x65\x6e\x63\x65\x20\x74\x6f\x20\x74\x68\x65\x20\x61\x72\x72\x61\x79\x20\x66\x72\x6f\x6d\x20\x74\x68\x65\x20\x77\x72\x61\x70\x70\x65\x72\x20\x74\x6f\x20\x6d\x61\x6b\x65\x20\x73\x75\x72\x65\x20\x69\x74\x73\x0a\x20\x2a\x20\x72\x65\x66\x65\x72\x65\x6e\x63\x65\x73\x2e\x20\x54\x68\x65\x6e\x20\x77\x65\x20\x75\x73\x65\x20\x61\x20\x70\x72\x61\x67\x6d\x61\x20\x74\x6f\x20\x6d\x61\x6b\x65\x20\x73\x75\x72\x65\x20\x74\x68\x65\x20\x77\x72\x61\x70\x70\x65\x72\x20\x66\x75\x6e\x63\x74\x69\x6f\x6e\x0a\x20\x2a\x20\x73\x79\x6d\x62\x6f\x6c\x20\x69\x73\x20\x61\x6c\x77\x61\x79\x73\x20\x69\x6e\x63\x6c\x75\x64\x65\x64\x20\x61\x74\x20\x74\x68\x65\x20\x6c\x69\x6e\x6b\x20\x73\x74\x61\x67\x65\x2e\x20\x41\x6c\x73\x6f\x2c\x20\x74\x68\x65\x20\x73\x79\x6d\x62\x6f\x6c\x73\x0a\x20\x2a\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x62\x65\x20\x65\x78\x74\x65\x72\x6e\x20\x28\x62\x75\x74\x20\x6e\x6f\x74\x20\x64\x6c\x6c\x65\x78\x70\x6f\x72\x74\x29\x2c\x20\x65\x76\x65\x6e\x20\x74\x68\x6f\x75\x67\x68\x20\x74\x68\x65\x79\x20\x61\x72\x65\x20\x6e\x6f\x74\x0a\x20\x2a\x20\x72\x65\x61\x6c\x6c\x79\x20\x75\x73\x65\x64\x20\x66\x72\x6f\x6d\x20\x61\x6e\x6f\x74\x68\x65\x72\x20\x6f\x62\x6a\x65\x63\x74\x20\x66\x69\x6c\x65\x2e\x0a\x20\x2a\x2f\x0a\x0a\x2f\x2a\x20\x57\x65\x20\x6e\x65\x65\x64\x20\x74\x6f\x20\x61\x63\x63\x6f\x75\x6e\x74\x20\x66\x6f\x72\x20\x64\x69\x66\x66\x65\x72\x65\x6e\x63\x65\x73\x20\x62\x65\x74\x77\x65\x65\x6e\x20\x74\x68\x65\x20\x6d\x61\x6e\x67\x6c\x69\x6e\x67\x20\x6f\x66\x20\x73\x79\x6d\x62\x6f\x6c\x73\x0a\x20\x2a\x20\x66\x6f\x72\x20\x78\x38\x36\x20\x61\x6e\x64\x20\x78\x36\x34\x2f\x41\x52\x4d\x2f\x41\x52\x4d\x36\x34\x20\x70\x72\x6f\x67\x72\x61\x6d\x73\x2c\x20\x61\x73\x20\x73\x79\x6d\x62\x6f\x6c\x73\x20\x6f\x6e\x20\x78\x38\x36\x20\x61\x72\x65\x20\x70\x72\x65\x66\x69\x78\x65\x64\x0a\x20\x2a\x20\x77\x69\x74\x68\x20\x61\x6e\x20\x75\x6e\x64\x65\x72\x73\x63\x6f\x72\x65\x20\x62\x75\x74\x20\x73\x79\x6d\x62\x6f\x6c\x73\x20\x6f\x6e\x20\x78\x36\x34\x2f\x41\x52\x4d\x2f\x41\x52\x4d\x36\x34\x20\x61\x72\x65\x20\x6e\x6f\x74\x2e\x0a\x20\x2a\x2f\x0a\x23\x69\x66\x64\x65\x66\x20\x5f\x4d\x5f\x49\x58\x38\x36\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x20\x22\x5f\x22\x0a\x23\x65\x6c\x73\x65\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x20\x22\x22\x0a\x23\x65\x6e\x64\x69\x66\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x47\x5f\x4d\x53\x56\x43\x5f\x43\x54\x4f\x52\x20\x28\x5f\x66\x75\x6e\x63\x2c\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x47\x5f\x4d\x53\x56\x43\x5f\x44\x54\x4f\x52\x20\x28\x5f\x66\x75\x6e\x63\x2c\x20\x47\x5f\x4d\x53\x56\x43\x5f\x53\x59\x4d\x42\x4f\x4c\x5f\x50\x52\x45\x46\x49\x58\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x2c\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x65\x78\x74\x65\x72\x6e\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5c\x0a\x20\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x5f\x66\x75\x6e\x63\x28\x29\x3b\x20\x67\x5f\x73\x6c\x69\x73\x74\x5f\x66\x69\x6e\x64\x20\x28\x4e\x55\x4c\x4c\x2c\x20\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x63\x6f\x6d\x6d\x65\x6e\x74\x28\x6c\x69\x6e\x6b\x65\x72\x2c\x22\x2f\x69\x6e\x63\x6c\x75\x64\x65\x3a\x22\x20\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x20\x23\x20\x5f\x66\x75\x6e\x63\x20\x22\x5f\x77\x72\x61\x70\x70\x65\x72\x22\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x4d\x53\x56\x43\x5f\x44\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x2c\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x65\x78\x74\x65\x72\x6e\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x5c\x0a\x20\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x61\x74\x65\x78\x69\x74\x20\x28\x5f\x66\x75\x6e\x63\x29\x3b\x20\x67\x5f\x73\x6c\x69\x73\x74\x5f\x66\x69\x6e\x64\x20\x28\x4e\x55\x4c\x4c\x2c\x20\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x63\x6f\x6d\x6d\x65\x6e\x74\x28\x6c\x69\x6e\x6b\x65\x72\x2c\x22\x2f\x69\x6e\x63\x6c\x75\x64\x65\x3a\x22\x20\x5f\x73\x79\x6d\x5f\x70\x72\x65\x66\x69\x78\x20\x23\x20\x5f\x66\x75\x6e\x63\x20\x22\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x22\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x70\x72\x61\x67\x6d\x61\x28\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x29\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x20\x28\x5f\x4d\x53\x43\x5f\x56\x45\x52\x29\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x2f\x2a\x20\x50\x72\x65\x20\x56\x69\x73\x75\x61\x6c\x20\x73\x74\x75\x64\x69\x6f\x20\x32\x30\x30\x38\x20\x6d\x75\x73\x74\x20\x75\x73\x65\x20\x23\x70\x72\x61\x67\x6d\x61\x20\x73\x65\x63\x74\x69\x6f\x6e\x20\x2a\x2f\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x5f\x66\x75\x6e\x63\x28\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x28\x2a\x70\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x77\x72\x61\x70\x70\x65\x72\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x65\x63\x74\x69\x6f\x6e\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x2c\x72\x65\x61\x64\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x28\x76\x6f\x69\x64\x29\x20\x7b\x20\x61\x74\x65\x78\x69\x74\x20\x28\x5f\x66\x75\x6e\x63\x29\x3b\x20\x72\x65\x74\x75\x72\x6e\x20\x30\x3b\x20\x7d\x20\x5c\x0a\x20\x20\x5f\x5f\x64\x65\x63\x6c\x73\x70\x65\x63\x28\x61\x6c\x6c\x6f\x63\x61\x74\x65\x28\x22\x2e\x43\x52\x54\x24\x58\x43\x55\x22\x29\x29\x20\x73\x74\x61\x74\x69\x63\x20\x69\x6e\x74\x20\x28\x2a\x20\x5f\x61\x72\x72\x61\x79\x20\x23\x23\x20\x5f\x66\x75\x6e\x63\x29\x28\x76\x6f\x69\x64\x29\x20\x3d\x20\x5f\x66\x75\x6e\x63\x20\x23\x23\x20\x5f\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x3b\x0a\x0a\x23\x65\x6c\x69\x66\x20\x64\x65\x66\x69\x6e\x65\x64\x28\x5f\x5f\x53\x55\x4e\x50\x52\x4f\x5f\x43\x29\x0a\x0a\x2f\x2a\x20\x54\x68\x69\x73\x20\x69\x73\x20\x6e\x6f\x74\x20\x74\x65\x73\x74\x65\x64\x2c\x20\x62\x75\x74\x20\x69\x20\x62\x65\x6c\x69\x65\x76\x65\x20\x69\x74\x20\x73\x68\x6f\x75\x6c\x64\x20\x77\x6f\x72\x6b\x2c\x20\x62\x61\x73\x65\x64\x20\x6f\x6e\x3a\x0a\x20\x2a\x20\x68\x74\x74\x70\x3a\x2f\x2f\x6f\x70\x65\x6e\x73\x6f\x75\x72\x63\x65\x2e\x61\x70\x70\x6c\x65\x2e\x63\x6f\x6d\x2f\x73\x6f\x75\x72\x63\x65\x2f\x4f\x70\x65\x6e\x53\x53\x4c\x30\x39\x38\x2f\x4f\x70\x65\x6e\x53\x53\x4c\x30\x39\x38\x2d\x33\x35\x2f\x73\x72\x63\x2f\x66\x69\x70\x73\x2f\x66\x69\x70\x73\x5f\x70\x72\x65\x6d\x61\x69\x6e\x2e\x63\x0a\x20\x2a\x2f\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x48\x41\x53\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x53\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x4e\x45\x45\x44\x53\x5f\x50\x52\x41\x47\x4d\x41\x20\x31\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x69\x6e\x69\x74\x28\x5f\x66\x75\x6e\x63\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x50\x52\x41\x47\x4d\x41\x5f\x41\x52\x47\x53\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x66\x69\x6e\x69\x28\x5f\x66\x75\x6e\x63\x29\x0a\x23\x64\x65\x66\x69\x6e\x65\x20\x47\x5f\x44\x45\x46\x49\x4e\x45\x5f\x44\x45\x53\x54\x52\x55\x43\x54\x4f\x52\x28\x5f\x66\x75\x6e\x63\x29\x20\x5c\x0a\x20\x20\x73\x74\x61\x74\x69\x63\x20\x76\x6f\x69\x64\x20\x5f\x66\x75\x6e\x63\x28\x76\x6f\x69\x64\x29\x3b\x0a\x0a\x23\x65\x6c\x73\x65\x0a\x0a\x2f\x2a\x20\x63\x6f\x6e\x73\x74\x72\x75\x63\x74\x6f\x72\x73\x20\x6e\x6f\x74\x20\x73\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x66\x6f\x72\x20\x74\x68\x69\x73\x20\x63\x6f\x6d\x70\x69\x6c\x65\x72\x20\x2a\x2f\x0a\x0a\x23\x65\x6e\x64\x69\x66\x0a\x0a\x23\x65\x6e\x64\x69\x66\x20\x2f\x2a\x20\x5f\x5f\x47\x54\x4b\x5f\x44\x4f\x43\x5f\x49\x47\x4e\x4f\x52\x45\x5f\x5f\x20\x2a\x2f\x0a\x23\x65\x6e\x64\x69\x66\x20\x2f\x2a\x20\x5f\x5f\x47\x5f\x43\x4f\x4e\x53\x54\x52\x55\x43\x54\x4f\x52\x5f\x48\x5f\x5f\x20\x2a\x2f\x0a"; diff --git a/gio/gdbus-daemon-generated.c b/gio/gdbus-daemon-generated.c new file mode 100644 -index 0000000..bbdf7ff +index 0000000..24706b6 --- /dev/null +++ b/gio/gdbus-daemon-generated.c @@ -0,0 +1,4339 @@ @@ -1683,7 +1513,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the Hello() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_hello() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_hello() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1707,7 +1537,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the RequestName() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_request_name() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_request_name() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1730,7 +1560,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the ReleaseName() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_release_name() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_release_name() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1754,7 +1584,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the StartServiceByName() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_start_service_by_name() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_start_service_by_name() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1777,7 +1607,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the NameHasOwner() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_name_has_owner() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_name_has_owner() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1799,7 +1629,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the ListNames() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_names() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_names() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1821,7 +1651,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the ListActivatableNames() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_activatable_names() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_activatable_names() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1844,7 +1674,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the AddMatch() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_add_match() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_add_match() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1867,7 +1697,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the RemoveMatch() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_remove_match() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_remove_match() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1890,7 +1720,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the GetNameOwner() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_name_owner() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_name_owner() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1913,7 +1743,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the ListQueuedOwners() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_queued_owners() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_list_queued_owners() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1936,7 +1766,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the GetConnectionUnixUser() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_unix_user() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_unix_user() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1959,7 +1789,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the GetConnectionUnixProcessID() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_unix_process_id() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_unix_process_id() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -1982,7 +1812,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the GetConnectionSELinuxSecurityContext() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_selinux_security_context() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_connection_selinux_security_context() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -2005,7 +1835,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the UpdateActivationEnvironment() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_update_activation_environment() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_update_activation_environment() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -2027,7 +1857,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the ReloadConfig() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_reload_config() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_reload_config() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -2049,7 +1879,7 @@ index 0000000..bbdf7ff + * + * Signal emitted when a remote caller is invoking the GetId() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_id() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call _g_freedesktop_dbus_complete_get_id() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -5636,10 +5466,10 @@ index 0000000..8a99684 +#endif /* __GDBUS_DAEMON_GENERATED_H__ */ diff --git a/gio/gioenumtypes.c b/gio/gioenumtypes.c new file mode 100644 -index 0000000..8c0c3e6 +index 0000000..0ccd900 --- /dev/null +++ b/gio/gioenumtypes.c -@@ -0,0 +1,1801 @@ +@@ -0,0 +1,1834 @@ + +/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ + @@ -6562,6 +6392,7 @@ index 0000000..8c0c3e6 + { G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, "G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START", "do-not-auto-start" }, + { G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES", "get-invalidated-properties" }, + { G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION, "G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START_AT_CONSTRUCTION", "do-not-auto-start-at-construction" }, ++ { G_DBUS_PROXY_FLAGS_NO_MATCH_RULE, "G_DBUS_PROXY_FLAGS_NO_MATCH_RULE", "no-match-rule" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -6881,6 +6712,7 @@ index 0000000..8c0c3e6 + { G_CREDENTIALS_TYPE_SOLARIS_UCRED, "G_CREDENTIALS_TYPE_SOLARIS_UCRED", "solaris-ucred" }, + { G_CREDENTIALS_TYPE_NETBSD_UNPCBID, "G_CREDENTIALS_TYPE_NETBSD_UNPCBID", "netbsd-unpcbid" }, + { G_CREDENTIALS_TYPE_APPLE_XUCRED, "G_CREDENTIALS_TYPE_APPLE_XUCRED", "apple-xucred" }, ++ { G_CREDENTIALS_TYPE_WIN32_PID, "G_CREDENTIALS_TYPE_WIN32_PID", "win32-pid" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -6952,6 +6784,7 @@ index 0000000..8c0c3e6 + { G_TLS_ERROR_CERTIFICATE_REQUIRED, "G_TLS_ERROR_CERTIFICATE_REQUIRED", "certificate-required" }, + { G_TLS_ERROR_EOF, "G_TLS_ERROR_EOF", "eof" }, + { G_TLS_ERROR_INAPPROPRIATE_FALLBACK, "G_TLS_ERROR_INAPPROPRIATE_FALLBACK", "inappropriate-fallback" }, ++ { G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD, "G_TLS_ERROR_BAD_CERTIFICATE_PASSWORD", "bad-certificate-password" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -6969,6 +6802,7 @@ index 0000000..8c0c3e6 + if (g_once_init_enter (&static_g_define_type_id)) + { + static const GFlagsValue values[] = { ++ { G_TLS_CERTIFICATE_FLAGS_NONE, "G_TLS_CERTIFICATE_FLAGS_NONE", "flags-none" }, + { G_TLS_CERTIFICATE_UNKNOWN_CA, "G_TLS_CERTIFICATE_UNKNOWN_CA", "unknown-ca" }, + { G_TLS_CERTIFICATE_BAD_IDENTITY, "G_TLS_CERTIFICATE_BAD_IDENTITY", "bad-identity" }, + { G_TLS_CERTIFICATE_NOT_ACTIVATED, "G_TLS_CERTIFICATE_NOT_ACTIVATED", "not-activated" }, @@ -7079,6 +6913,9 @@ index 0000000..8c0c3e6 + { G_TLS_PASSWORD_RETRY, "G_TLS_PASSWORD_RETRY", "retry" }, + { G_TLS_PASSWORD_MANY_TRIES, "G_TLS_PASSWORD_MANY_TRIES", "many-tries" }, + { G_TLS_PASSWORD_FINAL_TRY, "G_TLS_PASSWORD_FINAL_TRY", "final-try" }, ++ { G_TLS_PASSWORD_PKCS11_USER, "G_TLS_PASSWORD_PKCS11_USER", "pkcs11-user" }, ++ { G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER, "G_TLS_PASSWORD_PKCS11_SECURITY_OFFICER", "pkcs11-security-officer" }, ++ { G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC, "G_TLS_PASSWORD_PKCS11_CONTEXT_SPECIFIC", "pkcs11-context-specific" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -7202,6 +7039,31 @@ index 0000000..8c0c3e6 + return static_g_define_type_id; +} +GType ++g_tls_protocol_version_get_type (void) ++{ ++ static gsize static_g_define_type_id = 0; ++ ++ if (g_once_init_enter (&static_g_define_type_id)) ++ { ++ static const GEnumValue values[] = { ++ { G_TLS_PROTOCOL_VERSION_UNKNOWN, "G_TLS_PROTOCOL_VERSION_UNKNOWN", "unknown" }, ++ { G_TLS_PROTOCOL_VERSION_SSL_3_0, "G_TLS_PROTOCOL_VERSION_SSL_3_0", "ssl-3-0" }, ++ { G_TLS_PROTOCOL_VERSION_TLS_1_0, "G_TLS_PROTOCOL_VERSION_TLS_1_0", "tls-1-0" }, ++ { G_TLS_PROTOCOL_VERSION_TLS_1_1, "G_TLS_PROTOCOL_VERSION_TLS_1_1", "tls-1-1" }, ++ { G_TLS_PROTOCOL_VERSION_TLS_1_2, "G_TLS_PROTOCOL_VERSION_TLS_1_2", "tls-1-2" }, ++ { G_TLS_PROTOCOL_VERSION_TLS_1_3, "G_TLS_PROTOCOL_VERSION_TLS_1_3", "tls-1-3" }, ++ { G_TLS_PROTOCOL_VERSION_DTLS_1_0, "G_TLS_PROTOCOL_VERSION_DTLS_1_0", "dtls-1-0" }, ++ { G_TLS_PROTOCOL_VERSION_DTLS_1_2, "G_TLS_PROTOCOL_VERSION_DTLS_1_2", "dtls-1-2" }, ++ { 0, NULL, NULL } ++ }; ++ GType g_define_type_id = ++ g_enum_register_static (g_intern_static_string ("GTlsProtocolVersion"), values); ++ g_once_init_leave (&static_g_define_type_id, g_define_type_id); ++ } ++ ++ return static_g_define_type_id; ++} ++GType +g_io_module_scope_flags_get_type (void) +{ + static gsize static_g_define_type_id = 0; @@ -7302,6 +7164,7 @@ index 0000000..8c0c3e6 + { G_SUBPROCESS_FLAGS_STDERR_SILENCE, "G_SUBPROCESS_FLAGS_STDERR_SILENCE", "stderr-silence" }, + { G_SUBPROCESS_FLAGS_STDERR_MERGE, "G_SUBPROCESS_FLAGS_STDERR_MERGE", "stderr-merge" }, + { G_SUBPROCESS_FLAGS_INHERIT_FDS, "G_SUBPROCESS_FLAGS_INHERIT_FDS", "inherit-fds" }, ++ { G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP, "G_SUBPROCESS_FLAGS_SEARCH_PATH_FROM_ENVP", "search-path-from-envp" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -7443,10 +7306,10 @@ index 0000000..8c0c3e6 + diff --git a/gio/gioenumtypes.h b/gio/gioenumtypes.h new file mode 100644 -index 0000000..201be60 +index 0000000..dd4e2c1 --- /dev/null +++ b/gio/gioenumtypes.h -@@ -0,0 +1,183 @@ +@@ -0,0 +1,185 @@ + +/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ + @@ -7598,6 +7461,8 @@ index 0000000..201be60 +#define G_TYPE_TLS_DATABASE_LOOKUP_FLAGS (g_tls_database_lookup_flags_get_type ()) +GLIB_AVAILABLE_IN_ALL GType g_tls_certificate_request_flags_get_type (void) G_GNUC_CONST; +#define G_TYPE_TLS_CERTIFICATE_REQUEST_FLAGS (g_tls_certificate_request_flags_get_type ()) ++GLIB_AVAILABLE_IN_ALL GType g_tls_protocol_version_get_type (void) G_GNUC_CONST; ++#define G_TYPE_TLS_PROTOCOL_VERSION (g_tls_protocol_version_get_type ()) +GLIB_AVAILABLE_IN_ALL GType g_io_module_scope_flags_get_type (void) G_GNUC_CONST; +#define G_TYPE_IO_MODULE_SCOPE_FLAGS (g_io_module_scope_flags_get_type ()) +GLIB_AVAILABLE_IN_ALL GType g_socket_client_event_get_type (void) G_GNUC_CONST; @@ -7714,34 +7579,9 @@ index 0000000..1f1124a +G_END_DECLS + +#endif /* __G_NETWORKING_H__ */ -diff --git a/gio/meson.build b/gio/meson.build -index 49a37a7..492add3 100644 ---- a/gio/meson.build -+++ b/gio/meson.build -@@ -962,6 +962,7 @@ gio_querymodules = executable('gio-querymodules', 'gio-querymodules.c', 'giomodu - c_args : gio_c_args, - # intl.lib is not compatible with SAFESEH - link_args : noseh_link_args, -+ install_dir: glib_libexecdir, - dependencies : [libgio_dep, libgobject_dep, libgmodule_dep, libglib_dep]) - - glib_compile_schemas = executable('glib-compile-schemas', -diff --git a/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b b/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b -new file mode 100644 -index 0000000..83976e0 ---- /dev/null -+++ b/gio/tests/desktop-files/home/applications/epiphany-weather-for-toronto-island-9c6a4e022b -@@ -0,0 +1,7 @@ -+[Desktop Entry] -+Name=Weather for Toronto Island -+Exec=true -+StartupNotify=true -+Terminal=false -+Type=Application -+StartupWMClass=epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb diff --git a/gio/xdp-dbus.c b/gio/xdp-dbus.c new file mode 100644 -index 0000000..1372db7 +index 0000000..3e9dbff --- /dev/null +++ b/gio/xdp-dbus.c @@ -0,0 +1,7909 @@ @@ -8711,7 +8551,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the GetMountPoint() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_get_mount_point() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_get_mount_point() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8737,7 +8577,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the Add() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8764,7 +8604,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the AddNamed() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_named() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_named() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8791,7 +8631,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the AddFull() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_full() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_full() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8819,7 +8659,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the AddNamedFull() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_named_full() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_add_named_full() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8844,7 +8684,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the GrantPermissions() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_grant_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_grant_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8869,7 +8709,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the RevokePermissions() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_revoke_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_revoke_permissions() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8892,7 +8732,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the Delete() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_delete() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_delete() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8915,7 +8755,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the Lookup() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8938,7 +8778,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the Info() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_info() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_info() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -8961,7 +8801,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the List() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_list() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_documents_complete_list() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -11756,7 +11596,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the OpenURI() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_uri() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_uri() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -11782,7 +11622,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the OpenFile() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_file() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_file() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -11808,7 +11648,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the OpenDirectory() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_directory() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_open_uri_complete_open_directory() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -13349,7 +13189,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the Lookup() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_proxy_resolver_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_proxy_resolver_complete_lookup() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -14577,7 +14417,7 @@ index 0000000..1372db7 + * + * Signal emitted when a remote caller is invoking the TrashFile() D-Bus method. + * -+ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_trash_complete_trash_file() or e.g. g_dbus_method_invocation_return_error() on it) and no order signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. ++ * If a signal handler returns %TRUE, it means the signal handler will handle the invocation (e.g. take a reference to @invocation and eventually call gxdp_trash_complete_trash_file() or e.g. g_dbus_method_invocation_return_error() on it) and no other signal handlers will run. If no signal handler handles the invocation, the %G_DBUS_ERROR_UNKNOWN_METHOD error is returned. + * + * Returns: %G_DBUS_METHOD_INVOCATION_HANDLED or %TRUE if the invocation was handled, %G_DBUS_METHOD_INVOCATION_UNHANDLED or %FALSE to let other signal handlers run. + */ @@ -16833,10 +16673,10 @@ index 0000000..6c06210 + +#endif /* __XDP_DBUS_H__ */ diff --git a/glib/gatomic.h b/glib/gatomic.h -index 2ad648a..c8c00ab 100644 +index 8b2b880..7bb4443 100644 --- a/glib/gatomic.h +++ b/glib/gatomic.h -@@ -90,7 +90,13 @@ G_END_DECLS +@@ -86,7 +86,13 @@ G_END_DECLS #if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) /* We prefer the new C11-style atomic extension of GCC if available */ @@ -16904,10 +16744,10 @@ index 5f996d2..a3e11c4 100644 #define _(String) gettext (String) diff --git a/glib/glibconfig.h b/glib/glibconfig.h new file mode 100644 -index 0000000..54e74bd +index 0000000..4189f00 --- /dev/null +++ b/glib/glibconfig.h -@@ -0,0 +1,292 @@ +@@ -0,0 +1,294 @@ +/* glibconfig.h + * + * This is a generated file. Please modify 'glibconfig.h.in' @@ -16930,6 +16770,8 @@ index 0000000..54e74bd + +/* #undef GLIB_STATIC_COMPILATION */ +/* #undef GOBJECT_STATIC_COMPILATION */ ++/* #undef G_INTL_STATIC_COMPILATION */ ++/* #undef FFI_STATIC_BUILD */ + +G_BEGIN_DECLS + @@ -17075,8 +16917,8 @@ index 0000000..54e74bd + + +#define GLIB_MAJOR_VERSION 2 -+#define GLIB_MINOR_VERSION 68 -+#define GLIB_MICRO_VERSION 1 ++#define GLIB_MINOR_VERSION 72 ++#define GLIB_MICRO_VERSION 2 + +#define G_OS_UNIX + @@ -17200,1250 +17042,21 @@ index 0000000..54e74bd +G_END_DECLS + +#endif /* __GLIBCONFIG_H__ */ -diff --git a/glib/gregex.c b/glib/gregex.c -index 5e6ddfb..3ab76ca 100644 ---- a/glib/gregex.c -+++ b/glib/gregex.c -@@ -22,11 +22,8 @@ - - #include - --#ifdef USE_SYSTEM_PCRE --#include --#else --#include "pcre/pcre.h" --#endif -+#define PCRE2_CODE_UNIT_WIDTH 8 -+#include - - #include "gtypes.h" - #include "gregex.h" -@@ -110,87 +107,49 @@ - * library written by Philip Hazel. - */ - -+/* signifies that flags have already been converted from pcre1 to pcre2 */ -+#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) - - /* if the string is in UTF-8 use g_utf8_ functions, else use - * use just +/- 1. */ -@@ -214,20 +173,20 @@ struct _GMatchInfo - 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_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 */ -+ pcre2_code *pcre_re; /* compiled form of the pattern */ - GRegexCompileFlags compile_opts; /* options used at compile time on the pattern */ - 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_PCRE_ERROR(ret) ((ret) < PCRE2_ERROR_NOMATCH && (ret) != PCRE2_ERROR_PARTIAL) - - typedef struct _InterpolationData InterpolationData; - static gboolean interpolation_list_needs_match (GList *list); -@@ -238,70 +197,396 @@ 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; -+ if ((pcre1_flags & G_REGEX_NEWLINE_CRLF) == G_REGEX_NEWLINE_CRLF) -+ pcre2_flags |= PCRE2_NEWLINE_CRLF; -+ 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 */ -+ if (pcre1_flags & G_REGEX_OPTIMIZE) -+ pcre2_flags |= 0; -+ if (pcre1_flags & G_REGEX_JAVASCRIPT_COMPAT) -+ pcre2_flags |= 0; -+ -+ 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; -+ 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; -+ 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; -+ if (pcre1_flags & G_REGEX_RAW) -+ pcre2_flags |= PCRE2_UTF; -+ -+ 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; -+ if ((pcre2_flags & PCRE2_NEWLINE_CRLF) == PCRE2_NEWLINE_CRLF) -+ pcre1_flags |= G_REGEX_NEWLINE_CRLF; -+ 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; -+ 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; -+ 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; -+ if (pcre2_flags & PCRE2_UTF) -+ pcre1_flags |= G_REGEX_RAW; -+ -+ return pcre1_flags; -+} -+ -+static gint -+map_to_gregex_error (gint pcre2_error) -+{ -+ /* Maps error codes from pcre2 to gregex values (which were based on pcre1) -+ */ -+ switch (pcre2_error) -+ { -+ case PCRE2_ERROR_END_BACKSLASH: -+ return G_REGEX_ERROR_STRAY_BACKSLASH; -+ case PCRE2_ERROR_END_BACKSLASH_C: -+ return G_REGEX_ERROR_MISSING_CONTROL_CHAR; -+ case PCRE2_ERROR_UNKNOWN_ESCAPE: -+ return G_REGEX_ERROR_UNRECOGNIZED_ESCAPE; -+ case PCRE2_ERROR_QUANTIFIER_OUT_OF_ORDER: -+ return G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER; -+ case PCRE2_ERROR_QUANTIFIER_TOO_BIG: -+ return G_REGEX_ERROR_QUANTIFIER_TOO_BIG; -+ case PCRE2_ERROR_MISSING_SQUARE_BRACKET: -+ return G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS; -+ case PCRE2_ERROR_ESCAPE_INVALID_IN_CLASS: -+ return G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS; -+ case PCRE2_ERROR_CLASS_RANGE_ORDER: -+ return G_REGEX_ERROR_RANGE_OUT_OF_ORDER; -+ case PCRE2_ERROR_QUANTIFIER_INVALID: -+ return G_REGEX_ERROR_NOTHING_TO_REPEAT; -+ case PCRE2_ERROR_INTERNAL_UNEXPECTED_REPEAT: -+ return G_REGEX_ERROR_NOTHING_TO_REPEAT; -+ case PCRE2_ERROR_INVALID_AFTER_PARENS_QUERY: -+ return G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; -+ case PCRE2_ERROR_POSIX_CLASS_NOT_IN_CLASS: -+ return G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS; -+ case PCRE2_ERROR_POSIX_NO_SUPPORT_COLLATING: -+ return G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED; -+ case PCRE2_ERROR_MISSING_CLOSING_PARENTHESIS: -+ return G_REGEX_ERROR_UNMATCHED_PARENTHESIS; -+ case PCRE2_ERROR_BAD_SUBPATTERN_REFERENCE: -+ return G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE; -+ case PCRE2_ERROR_MISSING_COMMENT_CLOSING: -+ return G_REGEX_ERROR_UNTERMINATED_COMMENT; -+ case PCRE2_ERROR_PATTERN_TOO_LARGE: -+ return G_REGEX_ERROR_EXPRESSION_TOO_LARGE; -+ case PCRE2_ERROR_UNMATCHED_CLOSING_PARENTHESIS: -+ return G_REGEX_ERROR_UNMATCHED_PARENTHESIS; -+ case PCRE2_ERROR_MISSING_CONDITION_CLOSING: -+ return G_REGEX_ERROR_MALFORMED_CONDITION; -+ case PCRE2_ERROR_LOOKBEHIND_NOT_FIXED_LENGTH: -+ return G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND; -+ case PCRE2_ERROR_TOO_MANY_CONDITION_BRANCHES: -+ return G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES; -+ case PCRE2_ERROR_CONDITION_ASSERTION_EXPECTED: -+ return G_REGEX_ERROR_ASSERTION_EXPECTED; -+ case PCRE2_ERROR_BAD_RELATIVE_REFERENCE: -+ return G_REGEX_ERROR_INVALID_RELATIVE_REFERENCE; -+ case PCRE2_ERROR_UNKNOWN_POSIX_CLASS: -+ return G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME; -+ case PCRE2_ERROR_CODE_POINT_TOO_BIG: -+ return G_REGEX_ERROR_HEX_CODE_TOO_LARGE; -+ case PCRE2_ERROR_LOOKBEHIND_INVALID_BACKSLASH_C: -+ return G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND; -+ case PCRE2_ERROR_UNSUPPORTED_ESCAPE_SEQUENCE: -+ return G_REGEX_ERROR_UNRECOGNIZED_ESCAPE; -+ case PCRE2_ERROR_MISSING_NAME_TERMINATOR: -+ return G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR; -+ case PCRE2_ERROR_DUPLICATE_SUBPATTERN_NAME: -+ return G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME; -+ case PCRE2_ERROR_MALFORMED_UNICODE_PROPERTY: -+ return G_REGEX_ERROR_MALFORMED_PROPERTY; -+ case PCRE2_ERROR_UNKNOWN_UNICODE_PROPERTY: -+ return G_REGEX_ERROR_UNKNOWN_PROPERTY; -+ case PCRE2_ERROR_SUBPATTERN_NAME_TOO_LONG: -+ return G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG; -+ case PCRE2_ERROR_TOO_MANY_NAMED_SUBPATTERNS: -+ return G_REGEX_ERROR_TOO_MANY_SUBPATTERNS; -+ case PCRE2_ERROR_OCTAL_BYTE_TOO_BIG: -+ return G_REGEX_ERROR_INVALID_OCTAL_VALUE; -+ case PCRE2_ERROR_DEFINE_TOO_MANY_BRANCHES: -+ return G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE; -+ case PCRE2_ERROR_INTERNAL_UNKNOWN_NEWLINE: -+ return G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS; -+ case PCRE2_ERROR_BACKSLASH_G_SYNTAX: -+ return G_REGEX_ERROR_MISSING_BACK_REFERENCE; -+ case PCRE2_ERROR_PARENS_QUERY_R_MISSING_CLOSING: -+ return G_REGEX_ERROR_UNMATCHED_PARENTHESIS; -+ case PCRE2_ERROR_VERB_ARGUMENT_NOT_ALLOWED: -+ return G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN; -+ case PCRE2_ERROR_VERB_UNKNOWN: -+ return G_REGEX_ERROR_UNKNOWN_BACKTRACKING_CONTROL_VERB; -+ case PCRE2_ERROR_SUBPATTERN_NUMBER_TOO_BIG: -+ return G_REGEX_ERROR_NUMBER_TOO_BIG; -+ case PCRE2_ERROR_SUBPATTERN_NAME_EXPECTED: -+ return G_REGEX_ERROR_MISSING_SUBPATTERN_NAME; -+ case PCRE2_ERROR_SUBPATTERN_NAMES_MISMATCH: -+ return G_REGEX_ERROR_EXTRA_SUBPATTERN_NAME; -+ case PCRE2_ERROR_MARK_MISSING_ARGUMENT: -+ return G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_REQUIRED; -+ case PCRE2_ERROR_INVALID_HEXADECIMAL: -+ return G_REGEX_ERROR_HEX_CODE_TOO_LARGE; -+ case PCRE2_ERROR_BACKSLASH_C_SYNTAX: -+ return G_REGEX_ERROR_INVALID_CONTROL_CHAR; -+ case PCRE2_ERROR_BACKSLASH_K_SYNTAX: -+ return G_REGEX_ERROR_MISSING_NAME; -+ case PCRE2_ERROR_BACKSLASH_N_IN_CLASS: -+ return G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS; -+ case PCRE2_ERROR_VERB_NAME_TOO_LONG: -+ return G_REGEX_ERROR_NAME_TOO_LONG; -+ case PCRE2_ERROR_NULL_PATTERN: -+ case PCRE2_ERROR_BAD_OPTIONS: -+ case PCRE2_ERROR_PARENTHESES_NEST_TOO_DEEP: -+ case PCRE2_ERROR_HEAP_FAILED: -+ case PCRE2_ERROR_INTERNAL_CODE_OVERFLOW: -+ case PCRE2_ERROR_ZERO_RELATIVE_REFERENCE: -+ case PCRE2_ERROR_INTERNAL_STUDY_ERROR: -+ case PCRE2_ERROR_UNICODE_NOT_SUPPORTED: -+ 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_UNRECOGNIZED_AFTER_QUERY_P: -+ case PCRE2_ERROR_INVALID_SUBPATTERN_NAME: -+ case PCRE2_ERROR_UNICODE_PROPERTIES_UNAVAILABLE: -+ case PCRE2_ERROR_CLASS_INVALID_RANGE: -+ case PCRE2_ERROR_INTERNAL_OVERRAN_WORKSPACE: -+ case PCRE2_ERROR_INTERNAL_MISSING_SUBPATTERN: -+ case PCRE2_ERROR_BACKSLASH_O_MISSING_BRACE: -+ case PCRE2_ERROR_INTERNAL_PARSED_OVERFLOW: -+ case PCRE2_ERROR_INVALID_OCTAL: -+ case PCRE2_ERROR_INTERNAL_BAD_CODE_LOOKBEHINDS: -+ case PCRE2_ERROR_CALLOUT_STRING_TOO_LONG: -+ case PCRE2_ERROR_UNICODE_DISALLOWED_CODE_POINT: -+ case PCRE2_ERROR_UTF_IS_DISABLED: -+ case PCRE2_ERROR_UCP_IS_DISABLED: -+ 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_INTERNAL_BAD_CODE_AUTO_POSSESS: -+ 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_BACKSLASH_C_LIBRARY_DISABLED: -+ case PCRE2_ERROR_PATTERN_TOO_COMPLICATED: -+ case PCRE2_ERROR_LOOKBEHIND_TOO_LONG: -+ case PCRE2_ERROR_PATTERN_STRING_TOO_LONG: -+ case PCRE2_ERROR_INTERNAL_BAD_CODE: -+ case PCRE2_ERROR_INTERNAL_BAD_CODE_IN_SKIP: -+ case PCRE2_ERROR_NO_SURROGATES_IN_UTF16: -+ case PCRE2_ERROR_BAD_LITERAL_OPTIONS: -+ default: -+ return G_REGEX_ERROR_COMPILE; -+ } -+} - - 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: -+ case PCRE2_ERROR_NOSUBSTRING: - /* not used by pcre_exec() */ - 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; -@@ -321,7 +606,8 @@ 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. - */ -- *errcode += 100; -+ -+ *errcode = map_to_gregex_error (*errcode); - - switch (*errcode) - { -@@ -562,6 +848,8 @@ match_info_new (const GRegex *regex, - { - GMatchInfo *match_info; - -+ match_options = map_to_pcre2_match_flags (match_options); -+ - if (string_len < 0) - string_len = strlen (string); - -@@ -570,7 +858,7 @@ 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; - -@@ -585,8 +873,8 @@ match_info_new (const GRegex *regex, - else - { - gint capture_count; -- pcre_fullinfo (regex->pcre_re, regex->extra, -- PCRE_INFO_CAPTURECOUNT, &capture_count); -+ pcre2_pattern_info (regex->pcre_re, PCRE2_INFO_CAPTURECOUNT, -+ &capture_count); - match_info->n_offsets = (capture_count + 1) * 3; - } - -@@ -595,6 +883,10 @@ 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; - } - -@@ -669,6 +961,8 @@ 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_data) -+ pcre2_match_data_free (match_info->match_data); - g_free (match_info->offsets); - g_free (match_info->workspace); - g_free (match_info); -@@ -715,6 +1009,9 @@ g_match_info_next (GMatchInfo *match_info, - { - gint prev_match_start; - gint prev_match_end; -+ gint i; -+ gint opts; -+ PCRE2_SIZE *ovector; - - g_return_val_if_fail (match_info != NULL, FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); -@@ -727,18 +1024,19 @@ 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); -+ 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_SPTR)match_info->string, -+ match_info->string_len, -+ match_info->pos, -+ opts & ~G_REGEX_FLAGS_CONVERTED, -+ match_info->match_data, -+ NULL); -+ - if (IS_PCRE_ERROR (match_info->matches)) - { - g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, -@@ -746,6 +1044,18 @@ g_match_info_next (GMatchInfo *match_info, - match_info->regex->pattern, match_error (match_info->matches)); - return FALSE; - } -+ else -+ { -+ 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]; -+ } -+ } - - /* avoid infinite loops if the pattern is an empty string or something - * equivalent */ -@@ -755,7 +1065,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 +1141,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 +1199,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; - } - - /** -@@ -1069,17 +1379,17 @@ 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_SPTR)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); -+ entrysize = pcre2_substring_nametable_scan (match_info->regex->pcre_re, -+ (PCRE2_SPTR)name, -+ &first, -+ &last); - - if (entrysize <= 0) - return entrysize; -@@ -1259,9 +1569,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); - } - } -@@ -1269,11 +1577,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: -@@ -1297,11 +1605,12 @@ 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; - -+ 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); - g_return_val_if_fail ((compile_options & ~G_REGEX_COMPILE_MASK) == 0, NULL); -@@ -1309,17 +1618,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)) -@@ -1329,14 +1634,8 @@ 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; -- - re = regex_compile (pattern, compile_options, &compile_options, - &match_options, error); -- - if (re == NULL) - return NULL; - -@@ -1347,78 +1646,56 @@ g_regex_new (const gchar *pattern, - regex->compile_opts = compile_options; - 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 pcre2_code * -+regex_compile (const gchar *pattern, -+ GRegexCompileFlags compile_options, -+ GRegexCompileFlags *compile_options_out, -+ GRegexMatchFlags *match_options, -+ GError **error) - { -- pcre *re; -+ pcre2_code *re; - const gchar *errmsg; -- gint erroffset; -+ PCRE2_SIZE erroffset; - gint errcode; - GRegexCompileFlags nonpcre_compile_options; - unsigned long int pcre_compile_options; - -+ compile_options = map_to_pcre2_compile_flags (compile_options); -+ *match_options = map_to_pcre2_match_flags (*match_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) -+ if (compile_options & PCRE2_UTF) - { - /* disable utf-8 */ -- compile_options &= ~G_REGEX_RAW; -+ compile_options &= ~PCRE2_UTF; - } - else - { - /* enable utf-8 */ -- compile_options |= PCRE_UTF8 | PCRE_NO_UTF8_CHECK; -+ compile_options |= PCRE2_UTF | PCRE2_NO_UTF_CHECK; - - if (match_options != NULL) -- *match_options |= PCRE_NO_UTF8_CHECK; -+ *match_options |= PCRE2_NO_UTF_CHECK; - } -- - /* 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)) -+ if (!(compile_options & PCRE2_NEWLINE_CR) && -+ !(compile_options & PCRE2_NEWLINE_LF)) - { -- compile_options |= PCRE_NEWLINE_ANY; -+ compile_options |= PCRE2_NEWLINE_ANY; - } - -- 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_SPTR)pattern, PCRE2_ZERO_TERMINATED, compile_options & ~G_REGEX_FLAGS_CONVERTED, -+ &errcode, &erroffset, NULL); - - /* if the compilation failed, set the error member and return - * immediately */ -@@ -1434,8 +1711,8 @@ regex_compile (const gchar *pattern, - erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]); - - tmp_error = g_error_new (G_REGEX_ERROR, errcode, -- _("Error while compiling regular " -- "expression %s at char %d: %s"), -+ _ ("Error while compiling regular " -+ "expression %s at char %" G_GSIZE_FORMAT ": %s"), - pattern, erroffset, errmsg); - g_propagate_error (error, tmp_error); - -@@ -1445,21 +1722,21 @@ 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_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; -+ 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) -@@ -1504,8 +1781,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; - } -@@ -1525,8 +1801,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; - } -@@ -1546,8 +1821,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; - } -@@ -1569,8 +1843,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; - } -@@ -1594,7 +1868,7 @@ g_regex_get_compile_flags (const GRegex *regex) - { - g_return_val_if_fail (regex != NULL, 0); - -- return regex->compile_opts; -+ return map_to_pcre1_compile_flags (regex->compile_opts); - } - - /** -@@ -1612,7 +1886,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); - } - - /** -@@ -1646,6 +1920,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, 0, NULL); - if (!regex) - return FALSE; -@@ -1713,6 +1990,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); - } -@@ -1796,6 +2075,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); -@@ -1846,6 +2127,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); - } -@@ -1915,9 +2198,12 @@ g_regex_match_all_full (const GRegex *regex, - { - GMatchInfo *info; - gboolean done; -- pcre *pcre_re; -- pcre_extra *extra; -+ pcre2_code *pcre_re; - gboolean retval; -+ PCRE2_SIZE *ovector; -+ gint i; -+ -+ 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); -@@ -1933,19 +2219,14 @@ g_regex_match_all_full (const GRegex *regex, - * 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, -@@ -1955,13 +2236,24 @@ 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_SPTR)info->string, info->string_len, -+ info->pos, -+ (match_options | PCRE2_NO_UTF_CHECK) & ~G_REGEX_FLAGS_CONVERTED, -+ info->match_data, -+ NULL, -+ info->workspace, info->n_workspace); -+ -+ info->n_offsets = pcre2_get_ovector_count (info->match_data) * 2; -+ ovector = pcre2_get_ovector_pointer (info->match_data); -+ info->offsets = g_realloc (info->offsets, -+ info->n_offsets * sizeof (gint)); -+ for (i = 0; i < info->n_offsets; i++) -+ { -+ info->offsets[i] = (int) ovector[i]; -+ } -+ -+ if (info->matches == PCRE2_ERROR_DFA_WSSIZE) - { - /* info->workspace is too small. */ - info->n_workspace *= 2; -@@ -1986,7 +2278,7 @@ g_regex_match_all_full (const GRegex *regex, - } - - #ifdef PCRE_NO_AUTO_POSSESS -- pcre_free (pcre_re); -+ pcre2_code_free (pcre_re); - #endif - - /* set info->pos to -1 so that a call to g_match_info_next() fails. */ -@@ -2022,8 +2314,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_SPTR)name); -+ if (num == PCRE2_ERROR_NOSUBSTRING) - num = -1; - - return num; -@@ -2078,6 +2370,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; -@@ -2121,6 +2416,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); - } -@@ -2185,6 +2482,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); -@@ -2809,6 +3108,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); -@@ -2878,6 +3179,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); - -@@ -2966,6 +3269,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/gscanner.c b/glib/gscanner.c -index c858abf..9b36c15 100644 +index 5f34218..39a9269 100644 --- a/glib/gscanner.c +++ b/glib/gscanner.c @@ -1678,7 +1678,7 @@ g_scanner_get_token_i (GScanner *scanner, case G_TOKEN_SYMBOL: if (scanner->config->symbol_2_token) -- *token_p = (GTokenType) value_p->v_symbol; +- *token_p = (GTokenType) ((size_t) value_p->v_symbol); + *token_p = (GTokenType)(intptr_t)value_p->v_symbol; break; case G_TOKEN_BINARY: diff --git a/glib/gslice.c b/glib/gslice.c -index d6335c9..fae2334 100644 +index 4e99920..c58591e 100644 --- a/glib/gslice.c +++ b/glib/gslice.c @@ -51,6 +51,18 @@ @@ -18465,27 +17078,29 @@ index d6335c9..fae2334 100644 /** * SECTION:memory_slices * @title: Memory Slices -@@ -675,6 +687,64 @@ magazine_chain_prepare_fields (ChunkLink *magazine_chunks) +@@ -675,6 +687,66 @@ magazine_chain_prepare_fields (ChunkLink *magazine_chunks) #define magazine_chain_next(mc) ((mc)->next->next->data) #define magazine_chain_count(mc) ((mc)->next->next->next->data) ++ +#ifdef OHOS_OPT_PERFORMANCE +/* + * ohos.opt.performance.0004 + * fix glib cache too large problem. when thread exit, release mem no user. + */ ++ +static void -+magazine_cache_trim (Allocator *allocator, -+ guint ix, -+ guint stamp, ++magazine_cache_trim (Allocator *local_allocator, ++ guint ix, ++ guint stamp, + gboolean release) +{ -+ /* g_mutex_lock (allocator->mutex); done by caller */ ++ /* g_mutex_lock (local_allocator->mutex); done by caller */ + /* trim magazine cache from tail */ -+ ChunkLink *current = magazine_chain_prev (allocator->magazines[ix]); ++ ChunkLink *current = magazine_chain_prev (local_allocator->magazines[ix]); + ChunkLink *trash = NULL; -+ while (!G_APPROX_VALUE(stamp, magazine_chain_uint_stamp (current), -+ allocator->config.working_set_msecs) || release) ++ while (!G_APPROX_VALUE (stamp, magazine_chain_uint_stamp (current), ++ local_allocator->config.working_set_msecs) || release) + { + /* unlink */ + ChunkLink *prev = magazine_chain_prev (current); @@ -18499,19 +17114,19 @@ index d6335c9..fae2334 100644 + magazine_chain_prev (current) = trash; + trash = current; + /* fixup list head if required */ -+ if (current == allocator->magazines[ix]) ++ if (current == local_allocator->magazines[ix]) + { -+ allocator->magazines[ix] = NULL; ++ local_allocator->magazines[ix] = NULL; + break; + } + current = prev; + } -+ g_mutex_unlock (&allocator->magazine_mutex); ++ g_mutex_unlock (&local_allocator->magazine_mutex); + /* free trash */ + if (trash) + { -+ const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); -+ g_mutex_lock (&allocator->slab_mutex); ++ const gsize chunk_size = SLAB_CHUNK_SIZE (local_allocator, ix); ++ g_mutex_lock (&local_allocator->slab_mutex); + while (trash) + { + current = trash; @@ -18523,15 +17138,15 @@ index d6335c9..fae2334 100644 + slab_allocator_free_chunk (chunk_size, chunk); + } + } -+ g_mutex_unlock (&allocator->slab_mutex); ++ g_mutex_unlock (&local_allocator->slab_mutex); + } +} +#else static void - magazine_cache_trim (Allocator *allocator, - guint ix, -@@ -726,7 +796,42 @@ magazine_cache_trim (Allocator *allocator, - g_mutex_unlock (&allocator->slab_mutex); + magazine_cache_trim (Allocator *local_allocator, + guint ix, +@@ -726,7 +798,42 @@ magazine_cache_trim (Allocator *local_allocator, + g_mutex_unlock (&local_allocator->slab_mutex); } } +#endif @@ -18544,8 +17159,8 @@ index d6335c9..fae2334 100644 +static void +magazine_cache_push_magazine (guint ix, + ChunkLink *magazine_chunks, -+ gsize count, -+ gboolean release) /* must be >= MIN_MAGAZINE_SIZE */ ++ gsize count, /* must be >= MIN_MAGAZINE_SIZE */ ++ gboolean release) +{ + ChunkLink *current = magazine_chain_prepare_fields (magazine_chunks); + ChunkLink *next, *prev; @@ -18573,16 +17188,15 @@ index d6335c9..fae2334 100644 static void magazine_cache_push_magazine (guint ix, ChunkLink *magazine_chunks, -@@ -754,7 +859,7 @@ magazine_cache_push_magazine (guint ix, +@@ -754,6 +861,7 @@ magazine_cache_push_magazine (guint ix, magazine_cache_trim (allocator, ix, allocator->last_stamp); /* g_mutex_unlock (allocator->mutex); was done by magazine_cache_trim() */ } -- +#endif + static ChunkLink* magazine_cache_pop_magazine (guint ix, - gsize *countp) -@@ -818,7 +923,15 @@ private_thread_memory_cleanup (gpointer data) +@@ -818,7 +926,15 @@ private_thread_memory_cleanup (gpointer data) { Magazine *mag = mags[j]; if (mag->count >= MIN_MAGAZINE_SIZE) @@ -18598,7 +17212,7 @@ index d6335c9..fae2334 100644 else { const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); -@@ -850,7 +963,15 @@ thread_memory_magazine2_unload (ThreadMemory *tmem, +@@ -850,7 +966,15 @@ thread_memory_magazine2_unload (ThreadMemory *tmem, guint ix) { Magazine *mag = &tmem->magazine2[ix]; @@ -18614,7 +17228,7 @@ index d6335c9..fae2334 100644 mag->chunks = NULL; mag->count = 0; } -@@ -1071,7 +1192,7 @@ g_slice_alloc (gsize mem_size) +@@ -1074,7 +1198,7 @@ g_slice_alloc (gsize mem_size) smc_notify_alloc (mem, mem_size); TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size)); @@ -18623,7 +17237,7 @@ index d6335c9..fae2334 100644 return mem; } -@@ -1180,6 +1301,7 @@ g_slice_free1 (gsize mem_size, +@@ -1183,6 +1307,7 @@ g_slice_free1 (gsize mem_size, g_free (mem_block); } TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size)); @@ -18631,7 +17245,7 @@ index d6335c9..fae2334 100644 } /** -@@ -1207,6 +1329,7 @@ g_slice_free_chain_with_offset (gsize mem_size, +@@ -1210,6 +1335,7 @@ g_slice_free_chain_with_offset (gsize mem_size, gpointer mem_chain, gsize next_offset) { @@ -18639,7 +17253,7 @@ index d6335c9..fae2334 100644 gpointer slice = mem_chain; /* while the thread magazines and the magazine cache are implemented so that * they can easily be extended to allow for free lists containing more free -@@ -1454,6 +1577,7 @@ allocator_memalign (gsize alignment, +@@ -1457,6 +1583,7 @@ allocator_memalign (gsize alignment, gint err = ENOMEM; #if HAVE_POSIX_MEMALIGN err = posix_memalign (&aligned_memory, alignment, memsize); @@ -18647,7 +17261,7 @@ index d6335c9..fae2334 100644 #elif HAVE_MEMALIGN errno = 0; aligned_memory = memalign (alignment, memsize); -@@ -1497,6 +1621,7 @@ allocator_memfree (gsize memsize, +@@ -1500,6 +1627,7 @@ allocator_memfree (gsize memsize, gpointer mem) { #if HAVE_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC @@ -18676,7 +17290,7 @@ index 2b44c9a..520faa1 100644 guint byte_size) G_GNUC_ALLOC_SIZE(2); diff --git a/glib/gthread-posix.c b/glib/gthread-posix.c -index 3d69767..160ebd5 100644 +index 8e2e66d..9286fc7 100644 --- a/glib/gthread-posix.c +++ b/glib/gthread-posix.c @@ -72,8 +72,14 @@ @@ -18695,281 +17309,6 @@ index 3d69767..160ebd5 100644 #define USE_NATIVE_MUTEX #endif -diff --git a/glib/meson.build b/glib/meson.build -index 8c18e6d..f6e24fe 100644 ---- a/glib/meson.build -+++ b/glib/meson.build -@@ -351,21 +351,15 @@ else - glib_dtrace_hdr = [] - endif - --pcre_static_args = [] -- --if use_pcre_static_flag -- pcre_static_args = ['-DPCRE_STATIC'] --endif -- - if use_system_pcre -- pcre_deps = [pcre] -+ pcre_deps = [pcre2] - pcre_objects = [] - else - pcre_deps = [] - pcre_objects = [libpcre.extract_all_objects()] - 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'] + glib_hidden_visibility_args - libglib = library('glib-2.0', - glib_dtrace_obj, glib_dtrace_hdr, - sources : [deprecated_sources, glib_sources], -@@ -377,7 +371,7 @@ libglib = library('glib-2.0', - # intl.lib is not compatible with SAFESEH - link_args : [noseh_link_args, glib_link_flags, win32_ldflags], - include_directories : configinc, -- dependencies : pcre_deps + [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 c77ccdd..7490321 100644 ---- a/glib/tests/meson.build -+++ b/glib/tests/meson.build -@@ -78,8 +78,7 @@ glib_tests = { - }, - 'refstring' : {}, - 'regex' : { -- 'dependencies' : [pcre], -- 'c_args' : use_pcre_static_flag ? ['-DPCRE_STATIC'] : [], -+ 'dependencies' : [pcre2], - }, - 'rwlock' : {}, - 'scannerapi' : {}, -diff --git a/glib/tests/regex.c b/glib/tests/regex.c -index c57bd8c..862da6f 100644 ---- a/glib/tests/regex.c -+++ b/glib/tests/regex.c -@@ -25,11 +25,8 @@ - #include - #include "glib.h" - --#ifdef USE_SYSTEM_PCRE --#include --#else --#include "glib/pcre/pcre.h" --#endif -+#define PCRE2_CODE_UNIT_WIDTH 8 -+#include - - /* U+20AC EURO SIGN (symbol, currency) */ - #define EURO "\xe2\x82\xac" -@@ -2169,24 +2166,6 @@ test_max_lookbehind (void) - g_regex_unref (regex); - } - --static gboolean --pcre_ge (guint64 major, guint64 minor) --{ -- const char *version; -- gchar *ptr; -- guint64 pcre_major, pcre_minor; -- -- /* e.g. 8.35 2014-04-04 */ -- version = pcre_version (); -- -- pcre_major = g_ascii_strtoull (version, &ptr, 10); -- /* ptr points to ".MINOR (release date)" */ -- g_assert (ptr[0] == '.'); -- pcre_minor = g_ascii_strtoull (ptr + 1, NULL, 10); -- -- return (pcre_major > major) || (pcre_major == major && pcre_minor >= minor); --} -- - int - main (int argc, char *argv[]) - { -@@ -2230,18 +2209,17 @@ main (int argc, char *argv[]) - TEST_NEW ("(?U)[a-z]+", 0, 0); - - /* 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, 0, 0, 0); - 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); -- TEST_NEW_CHECK_FLAGS ("(*CR)a", 0, 0, G_REGEX_NEWLINE_CR, 0); -- TEST_NEW_CHECK_FLAGS ("(*LF)a", 0, 0, G_REGEX_NEWLINE_LF, 0); -- TEST_NEW_CHECK_FLAGS ("(*CRLF)a", 0, 0, G_REGEX_NEWLINE_CRLF, 0); -+ TEST_NEW_CHECK_FLAGS ("(*CR)a", 0, 0, 0, 0); -+ TEST_NEW_CHECK_FLAGS ("(*LF)a", 0, 0, 0, 0); -+ TEST_NEW_CHECK_FLAGS ("(*CRLF)a", 0, 0, 0, 0); - TEST_NEW_CHECK_FLAGS ("(*ANY)a", 0, 0, 0 /* this is the default in GRegex */, 0); -- TEST_NEW_CHECK_FLAGS ("(*ANYCRLF)a", 0, 0, G_REGEX_NEWLINE_ANYCRLF, 0); -- TEST_NEW_CHECK_FLAGS ("(*BSR_ANYCRLF)a", 0, 0, G_REGEX_BSR_ANYCRLF, 0); -+ TEST_NEW_CHECK_FLAGS ("(*ANYCRLF)a", 0, 0, 0, 0); -+ TEST_NEW_CHECK_FLAGS ("(*BSR_ANYCRLF)a", 0, 0, 0, 0); - TEST_NEW_CHECK_FLAGS ("(*BSR_UNICODE)a", 0, 0, 0 /* this is the default in GRegex */, 0); - TEST_NEW_CHECK_FLAGS ("(*NO_START_OPT)a", 0, 0, 0 /* not exposed in GRegex */, 0); - -@@ -2260,16 +2238,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 ("(?X)[\\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); -@@ -2279,28 +2257,11 @@ 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); -@@ -2308,22 +2269,20 @@ main (int argc, char *argv[]) - #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_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_FAIL ("abc(*FAIL:123)xyz", 0, G_REGEX_ERROR_BACKTRACKING_CONTROL_VERB_ARGUMENT_FORBIDDEN); - 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); -+ //TEST_NEW_FAIL ("(?i:A{1,}\\6666666666)", 0, G_REGEX_ERROR_NUMBER_TOO_BIG); - 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 -@@ -2447,40 +2406,40 @@ main (int argc, char *argv[]) - - TEST_MATCH("^b$", 0, 0, "a\nb\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\nb\nc", -1, 0, 0, TRUE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE, 0, "a\rb\rc", -1, 0, 0, TRUE); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\nb\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\nb\nc", -1, 0, 0, TRUE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\nb\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_LF, 0, "a\r\nb\r\nc", -1, 0, 0, FALSE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); -- 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_CRLF, 0, "a\r\nb\r\nc", -1, 0, 0, TRUE); -+ //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_MATCH_NEWLINE_CR, "a\nb\nc", -1, 0, 0, FALSE); -+ //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); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\nb\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CR, "a\r\nb\r\nc", -1, 0, 0, FALSE); - TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_LF, "a\r\nb\r\nc", -1, 0, 0, FALSE); -- TEST_MATCH("^b$", G_REGEX_MULTILINE, G_REGEX_MATCH_NEWLINE_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); -- 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_CRLF, "a\r\nb\r\nc", -1, 0, 0, TRUE); -+ //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_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); -- TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\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); -+ //TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_ANY, "a\r\nb\r\nc", -1, 0, 0, TRUE); - TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\nb\nc", -1, 0, 0, TRUE); - TEST_MATCH("^b$", G_REGEX_MULTILINE | G_REGEX_NEWLINE_CR, G_REGEX_MATCH_NEWLINE_LF, "a\rb\rc", -1, 0, 0, FALSE); -- 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\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); - - 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#\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); -- TEST_MATCH("a#\nb", G_REGEX_EXTENDED | G_REGEX_NEWLINE_CR, 0, "a", -1, 0, 0, TRUE); -+ //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); - TEST_MATCH("line\nbreak", G_REGEX_MULTILINE | G_REGEX_FIRSTLINE, 0, "first line\na line\nbreak", -1, 0, 0, FALSE); -@@ -2855,12 +2814,12 @@ main (int argc, char *argv[]) - TEST_MATCH_ALL1("a+", "aa", -1, 1, "a", 1, 2); - TEST_MATCH_ALL1("a+", "aa", 2, 1, "a", 1, 2); - TEST_MATCH_ALL1(".+", ENG, -1, 0, ENG, 0, 2); -- TEST_MATCH_ALL2("<.*>", "", -1, 0, "", 0, 6, "", 0, 3); -- TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1); -- TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2); -- TEST_MATCH_ALL3("<.*>", "", -1, 0, "", 0, 9, -- "", 0, 6, "", 0, 3); -- TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1); -+ //TEST_MATCH_ALL2("<.*>", "", -1, 0, "", 0, 6, "", 0, 3); -+ //TEST_MATCH_ALL2("a+", "aa", -1, 0, "aa", 0, 2, "a", 0, 1); -+ //TEST_MATCH_ALL2(".+", ENG EURO, -1, 0, ENG EURO, 0, 5, ENG, 0, 2); -+ // TEST_MATCH_ALL3("<.*>", "", -1, 0, "", 0, 9, -+ // "", 0, 6, "", 0, 3); -+ //TEST_MATCH_ALL3("a+", "aaa", -1, 0, "aaa", 0, 3, "aa", 0, 2, "a", 0, 1); - - /* NOTEMPTY matching */ - TEST_MATCH_NOTEMPTY("a?b?", "xyz", FALSE); diff --git a/glibmemdfx/gmemdfx.cpp b/glibmemdfx/gmemdfx.cpp new file mode 100644 index 0000000..7c36613 @@ -19324,10 +17663,10 @@ index 0000000..9908fd1 + +#endif /* __G_MODULE_CONF_H__ */ diff --git a/gobject/gclosure.c b/gobject/gclosure.c -index 6d41e6d..94a04dd 100644 +index 85002a2..701181c 100644 --- a/gobject/gclosure.c +++ b/gobject/gclosure.c -@@ -1278,7 +1278,11 @@ restart: +@@ -1302,7 +1302,11 @@ restart: g_value_set_boolean (gvalue, (gboolean) *int_val); break; case G_TYPE_STRING: @@ -19341,16 +17680,18 @@ index 6d41e6d..94a04dd 100644 g_value_set_schar (gvalue, (gint8) *int_val); diff --git a/gobject/glib-enumtypes.c b/gobject/glib-enumtypes.c new file mode 100644 -index 0000000..8e0c91d +index 0000000..5d5eaf6 --- /dev/null +++ b/gobject/glib-enumtypes.c -@@ -0,0 +1,317 @@ +@@ -0,0 +1,328 @@ + +/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ + +#include "config.h" +#include "glib-enumtypes.h" +#include ++ ++G_GNUC_BEGIN_IGNORE_DEPRECATIONS +/* enumerations from "../gobject/../glib/gunicode.h" */ +GType +g_unicode_type_get_type (void) @@ -19444,6 +17785,7 @@ index 0000000..8e0c91d + { G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, "G_UNICODE_BREAK_HANGUL_LV_SYLLABLE", "hangul-lv-syllable" }, + { G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, "G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE", "hangul-lvt-syllable" }, + { G_UNICODE_BREAK_CLOSE_PARANTHESIS, "G_UNICODE_BREAK_CLOSE_PARANTHESIS", "close-paranthesis" }, ++ { G_UNICODE_BREAK_CLOSE_PARENTHESIS, "G_UNICODE_BREAK_CLOSE_PARENTHESIS", "close-parenthesis" }, + { G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, "G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER", "conditional-japanese-starter" }, + { G_UNICODE_BREAK_HEBREW_LETTER, "G_UNICODE_BREAK_HEBREW_LETTER", "hebrew-letter" }, + { G_UNICODE_BREAK_REGIONAL_INDICATOR, "G_UNICODE_BREAK_REGIONAL_INDICATOR", "regional-indicator" }, @@ -19625,6 +17967,12 @@ index 0000000..8e0c91d + { G_UNICODE_SCRIPT_DIVES_AKURU, "G_UNICODE_SCRIPT_DIVES_AKURU", "dives-akuru" }, + { G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT, "G_UNICODE_SCRIPT_KHITAN_SMALL_SCRIPT", "khitan-small-script" }, + { G_UNICODE_SCRIPT_YEZIDI, "G_UNICODE_SCRIPT_YEZIDI", "yezidi" }, ++ { G_UNICODE_SCRIPT_CYPRO_MINOAN, "G_UNICODE_SCRIPT_CYPRO_MINOAN", "cypro-minoan" }, ++ { G_UNICODE_SCRIPT_OLD_UYGHUR, "G_UNICODE_SCRIPT_OLD_UYGHUR", "old-uyghur" }, ++ { G_UNICODE_SCRIPT_TANGSA, "G_UNICODE_SCRIPT_TANGSA", "tangsa" }, ++ { G_UNICODE_SCRIPT_TOTO, "G_UNICODE_SCRIPT_TOTO", "toto" }, ++ { G_UNICODE_SCRIPT_VITHKUQI, "G_UNICODE_SCRIPT_VITHKUQI", "vithkuqi" }, ++ { G_UNICODE_SCRIPT_MATH, "G_UNICODE_SCRIPT_MATH", "math" }, + { 0, NULL, NULL } + }; + GType g_define_type_id = @@ -19660,6 +18008,8 @@ index 0000000..8e0c91d + return static_g_define_type_id; +} + ++G_GNUC_END_IGNORE_DEPRECATIONS ++ +/* Generated data ends here */ + diff --git a/gobject/glib-enumtypes.h b/gobject/glib-enumtypes.h @@ -19693,103 +18043,3 @@ index 0000000..9844954 + +/* Generated data ends here */ + -diff --git a/meson.build b/meson.build -index 657c478..612255c 100644 ---- a/meson.build -+++ b/meson.build -@@ -1509,6 +1509,40 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang' - } - endif - -+if host_system == 'linux-gnu_ilp32' -+if g_sizet_compatibility['short'] -+ glibconfig_conf.set('glib_size_type_define', 'short') -+ glibconfig_conf.set_quoted('gsize_modifier', 'h') -+ glibconfig_conf.set_quoted('gssize_modifier', 'h') -+ glibconfig_conf.set_quoted('gsize_format', 'hu') -+ glibconfig_conf.set_quoted('gssize_format', 'hi') -+ glibconfig_conf.set('glib_msize_type', 'SHRT') -+elif g_sizet_compatibility['long'] -+ glibconfig_conf.set('glib_size_type_define', 'long') -+ glibconfig_conf.set_quoted('gsize_modifier', 'l') -+ glibconfig_conf.set_quoted('gssize_modifier', 'l') -+ glibconfig_conf.set_quoted('gsize_format', 'lu') -+ glibconfig_conf.set_quoted('gssize_format', 'li') -+ glibconfig_conf.set('glib_msize_type', 'LONG') -+elif g_sizet_compatibility['int'] -+ glibconfig_conf.set('glib_size_type_define', 'int') -+ glibconfig_conf.set_quoted('gsize_modifier', '') -+ glibconfig_conf.set_quoted('gssize_modifier', '') -+ glibconfig_conf.set_quoted('gsize_format', 'u') -+ glibconfig_conf.set_quoted('gssize_format', 'i') -+ glibconfig_conf.set('glib_msize_type', 'INT') -+elif g_sizet_compatibility['long long'] -+ glibconfig_conf.set('glib_size_type_define', 'long long') -+ glibconfig_conf.set_quoted('gsize_modifier', int64_m) -+ glibconfig_conf.set_quoted('gssize_modifier', int64_m) -+ glibconfig_conf.set_quoted('gsize_format', int64_m + 'u') -+ glibconfig_conf.set_quoted('gssize_format', int64_m + 'i') -+ glibconfig_conf.set('glib_msize_type', 'INT64') -+else -+ error('Could not determine size of size_t.') -+endif -+ -+else - if g_sizet_compatibility['short'] - glibconfig_conf.set('glib_size_type_define', 'short') - glibconfig_conf.set_quoted('gsize_modifier', 'h') -@@ -1540,6 +1574,7 @@ elif g_sizet_compatibility['long long'] - else - error('Could not determine size of size_t.') - endif -+endif - - if voidp_size == int_size - glibconfig_conf.set('glib_intptr_type_define', 'int') -@@ -1969,44 +2004,11 @@ if get_option('internal_pcre') - pcre = [] - use_system_pcre = false - else -- pcre = dependency('libpcre', version: '>= 8.31', required : false) # Should check for Unicode support, too. FIXME -- if not pcre.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 -- # is really a Release build with .PDB files. -- if vs_crt == 'debug' -- pcre = cc.find_library('pcred', required : false) -- else -- pcre = cc.find_library('pcre', required : false) -- endif -- endif -- endif -- use_system_pcre = pcre.found() -+ use_system_pcre = true -+ pcre2 = dependency('libpcre2-8', version: '>= 10.32', required : true) - endif - glib_conf.set('USE_SYSTEM_PCRE', use_system_pcre) - --use_pcre_static_flag = false -- --if host_system == 'windows' -- if not use_system_pcre -- use_pcre_static_flag = true -- else -- 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') -- if pcre_static -- use_pcre_static_flag = true -- endif -- endif --endif -- - libm = cc.find_library('m', required : false) - libffi_dep = dependency('libffi', version : '>= 3.0.0', fallback : ['libffi', 'ffi_dep']) - diff --git a/patch/backport-openharmony-dummy.patch b/patch/backport-openharmony-dummy.patch new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/patch/backport-regex-Actually-check-for-match-options-changes.patch b/patch/backport-regex-Actually-check-for-match-options-changes.patch new file mode 100644 index 0000000000000000000000000000000000000000..a87c890e419fc889726516e8ecde76b4be0eb730 --- /dev/null +++ b/patch/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/patch/backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch b/patch/backport-regex-Add-debug-strings-for-compile-and-match-option-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8ddc8ba3db1418f4975541250c3a3f1b9414ed5 --- /dev/null +++ b/patch/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/patch/backport-regex-Add-test-for-gtksourceview-regression.patch b/patch/backport-regex-Add-test-for-gtksourceview-regression.patch new file mode 100644 index 0000000000000000000000000000000000000000..b109dfebf0731f10680feac0649d17f60a75456a --- /dev/null +++ b/patch/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/patch/backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch b/patch/backport-regex-Avoid-allocating-offsets-until-we-ve-a-match.patch new file mode 100644 index 0000000000000000000000000000000000000000..f46b0af6db54a4acc59771f5f4a66a542b523f75 --- /dev/null +++ b/patch/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/patch/backport-regex-Compute-the-offsets-size-based-on-match-results.patch b/patch/backport-regex-Compute-the-offsets-size-based-on-match-results.patch new file mode 100644 index 0000000000000000000000000000000000000000..8579bdaf2316c9eee34096458a543d17257dbbd2 --- /dev/null +++ b/patch/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/patch/backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch b/patch/backport-regex-Do-not-mix-PCRE2-Compile-Match-Newline-and-BSR-flags.patch new file mode 100644 index 0000000000000000000000000000000000000000..d09aef854de1d5bcd697e02e4a4f1cd26b546789 --- /dev/null +++ b/patch/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/patch/backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch b/patch/backport-regex-Do-not-use-JIT-when-using-unsupported-match-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..57b4c7dcfad0e4f061c7bd0674ba70047f2b6bed --- /dev/null +++ b/patch/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/patch/backport-regex-Handle-JIT-errors-more-explicitly.patch b/patch/backport-regex-Handle-JIT-errors-more-explicitly.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1d61315551da8a10953994207457cd51bf915b7 --- /dev/null +++ b/patch/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/patch/backport-regex-Make-possible-to-test-replacements-with-options.patch b/patch/backport-regex-Make-possible-to-test-replacements-with-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..d9bed10e308f4d001c00099cdb671c362c9c3b7a --- /dev/null +++ b/patch/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/patch/backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch b/patch/backport-regex-Perform-more-tests-both-with-and-without-optimizations.patch new file mode 100644 index 0000000000000000000000000000000000000000..135e07602397c38d54023dfc1471f9a93fb33b1a --- /dev/null +++ b/patch/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/patch/backport-regex-Use-critical-messages-if-an-unexpected-NULL-parameter-is-provided.patch b/patch/backport-regex-Use-critical-messages-if-an-unexpected-NULL-parameter-is-provided.patch new file mode 100644 index 0000000000000000000000000000000000000000..5e56e26210eae2e60abb03569066ebf3d7849d5e --- /dev/null +++ b/patch/backport-regex-Use-critical-messages-if-an-unexpected-NULL-parameter-is-provided.patch @@ -0,0 +1,31 @@ +From 0f869ec5c6bc6cd37a6803cc2299a5845199e758 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= +Date: Wed, 21 Sep 2022 11:33:14 +0200 +Subject: [PATCH] regex: Use critical messages if an unexpected NULL parameter + is provided + +As programmer error we should be consistent in using criticals. + +Conflict:NA +Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/06caf952e48dbed40b5dcff01a94f57ba079b526c + +--- + glib/gregex.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glib/gregex.c b/glib/gregex.c +index fcc28d62f4..1baa4e2f18 100644 +--- a/glib/gregex.c ++++ b/glib/gregex.c +@@ -483,7 +483,7 @@ translate_match_error (gint errcode) + break; + case PCRE2_ERROR_NULL: + /* NULL argument, this should not happen in GRegex */ +- g_warning ("A NULL argument was passed to PCRE"); ++ g_critical ("A NULL argument was passed to PCRE"); + break; + case PCRE2_ERROR_BADOPTION: + return "bad options"; +-- +GitLab + diff --git a/patch/backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch b/patch/backport-regex-Use-size-types-more-in-line-with-PCRE2-returned-values.patch new file mode 100644 index 0000000000000000000000000000000000000000..2ad0033e9c956ff05543038175cbdaa1c5fee024 --- /dev/null +++ b/patch/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/patch/backport-replace-pcre1-with-pcre2.patch b/patch/backport-replace-pcre1-with-pcre2.patch new file mode 100644 index 0000000000000000000000000000000000000000..451313517748c940b134465f01164c4581ce38df --- /dev/null +++ b/patch/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/patch/backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch b/patch/backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch new file mode 100644 index 0000000000000000000000000000000000000000..247c3cf70f7e8385b35a8f3b1d28619b378c063e --- /dev/null +++ b/patch/backport-tests-Add-a-test-for-GFileMonitor-deadlocks.patch @@ -0,0 +1,97 @@ +From 1fc6a5c9b6a2b620ac4370d64c558f9b33aff063 Mon Sep 17 00:00:00 2001 +From: Philip Withnall +Date: Mon, 30 May 2022 17:55:43 +0100 +Subject: [PATCH 3/3] tests: Add a test for GFileMonitor deadlocks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This test is opportunistic in that it’s not possible to detect whether +the race condition has been hit (other than by hitting a deadlock). + +So the only approach we can take for testing is to loop over the code +which has previously been known to cause a deadlock a number of times. + +The number of repetitions is chosen from running the test with the +deadlock fix reverted. + +Signed-off-by: Philip Withnall + +Helps: #1941 +--- + gio/tests/testfilemonitor.c | 52 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/gio/tests/testfilemonitor.c b/gio/tests/testfilemonitor.c +index a47aeab38..082f0db26 100644 +--- a/gio/tests/testfilemonitor.c ++++ b/gio/tests/testfilemonitor.c +@@ -1036,6 +1036,57 @@ test_file_hard_links (Fixture *fixture, + g_object_unref (data.output_stream); + } + ++static void ++test_finalize_in_callback (Fixture *fixture, ++ gconstpointer user_data) ++{ ++ GFile *file = NULL; ++ guint i; ++ ++ g_test_summary ("Test that finalization of a GFileMonitor in one of its " ++ "callbacks doesn’t cause a deadlock."); ++ g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/1941"); ++ ++ file = g_file_get_child (fixture->tmp_dir, "race-file"); ++ ++ for (i = 0; i < 50; i++) ++ { ++ GFileMonitor *monitor = NULL; ++ GError *local_error = NULL; ++ ++ /* Monitor the file. */ ++ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error); ++ g_assert_no_error (local_error); ++ g_assert_nonnull (monitor); ++ ++ /* Create the file. */ ++ g_file_replace_contents (file, "hello", 5, NULL, FALSE, ++ G_FILE_CREATE_NONE, NULL, NULL, &local_error); ++ g_assert_no_error (local_error); ++ ++ /* Immediately drop the last ref to the monitor in the hope that this ++ * happens in the middle of the critical section in ++ * g_file_monitor_source_handle_event(), so that any cleanup at the end ++ * of that function is done with a now-finalised file monitor. */ ++ g_object_unref (monitor); ++ ++ /* Re-create the monitor and do the same again for deleting the file, to ++ * give a second chance at hitting the race condition. */ ++ monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &local_error); ++ g_assert_no_error (local_error); ++ g_assert_nonnull (monitor); ++ ++ /* Delete the file. */ ++ g_file_delete (file, NULL, &local_error); ++ g_assert_no_error (local_error); ++ ++ /* Drop the ref again. */ ++ g_object_unref (monitor); ++ } ++ ++ g_object_unref (file); ++} ++ + int + main (int argc, char *argv[]) + { +@@ -1047,6 +1098,7 @@ main (int argc, char *argv[]) + g_test_add ("/monitor/dir-not-existent", Fixture, NULL, setup, test_dir_non_existent, teardown); + g_test_add ("/monitor/cross-dir-moves", Fixture, NULL, setup, test_cross_dir_moves, teardown); + g_test_add ("/monitor/file/hard-links", Fixture, NULL, setup, test_file_hard_links, teardown); ++ g_test_add ("/monitor/finalize-in-callback", Fixture, NULL, setup, test_finalize_in_callback, teardown); + + return g_test_run (); + } +-- +2.41.0.windows.3 + diff --git a/patch/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch b/patch/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch deleted file mode 100644 index 0c99c60696ed9a64e6a9c7bb4ce42bb5e26ceb7f..0000000000000000000000000000000000000000 --- a/patch/backport-tests-Add-some-tests-for-g_string_append_vprintf.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d6ad10404f1d61d83803336ba5b64ec0bfd07da8 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Wed, 9 Mar 2022 14:09:57 +0000 -Subject: [PATCH] tests: Add some tests for g_string_append_vprintf() - -This adds coverage of one previously uncovered branch in `gstring.c`. -Real progress! - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/d6ad10404f1d61d83803336ba5b64ec0bfd07da8 - ---- - glib/tests/string.c | 39 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - -diff --git a/glib/tests/string.c b/glib/tests/string.c -index 24098d1be6..0229099e79 100644 ---- a/glib/tests/string.c -+++ b/glib/tests/string.c -@@ -215,6 +215,44 @@ test_string_append (void) - g_string_free (string, TRUE); - } - -+static void string_append_vprintf_va (GString *string, -+ const gchar *format, -+ ...) G_GNUC_PRINTF (2, 3); -+ -+/* Wrapper around g_string_append_vprintf() which takes varargs */ -+static void -+string_append_vprintf_va (GString *string, -+ const gchar *format, -+ ...) -+{ -+ va_list args; -+ -+ va_start (args, format); -+ g_string_append_vprintf (string, format, args); -+ va_end (args); -+} -+ -+static void -+test_string_append_vprintf (void) -+{ -+ GString *string; -+ -+ /* append */ -+ string = g_string_new ("firsthalf"); -+ -+ string_append_vprintf_va (string, "some %s placeholders", "format"); -+ -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wformat" -+#pragma GCC diagnostic ignored "-Wformat-extra-args" -+ string_append_vprintf_va (string, "%l", "invalid"); -+#pragma GCC diagnostic pop -+ -+ g_assert_cmpstr (string->str, ==, "firsthalfsome format placeholders"); -+ -+ g_string_free (string, TRUE); -+} -+ - static void - test_string_prepend_c (void) - { -@@ -571,6 +609,7 @@ main (int argc, - g_test_add_func ("/string/test-string-assign", test_string_assign); - g_test_add_func ("/string/test-string-append-c", test_string_append_c); - g_test_add_func ("/string/test-string-append", test_string_append); -+ g_test_add_func ("/string/test-string-append-vprintf", test_string_append_vprintf); - g_test_add_func ("/string/test-string-prepend-c", test_string_prepend_c); - g_test_add_func ("/string/test-string-prepend", test_string_prepend); - g_test_add_func ("/string/test-string-insert", test_string_insert); --- -GitLab diff --git a/patch/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch b/patch/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch deleted file mode 100644 index ed15c52b789373858ee19933205a0c6d89f9e0e4..0000000000000000000000000000000000000000 --- a/patch/backport-tests-Add-some-tests-for-g_vasprintf-invalid-format-strings.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 27e1509cd68e58d9057091eadf97de96165c2bea Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Wed, 9 Mar 2022 14:08:49 +0000 -Subject: [PATCH] tests: Add some tests for g_vasprintf() invalid format - strings - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/27e1509cd68e58d9057091eadf97de96165c2bea - ---- - glib/tests/test-printf.c | 40 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 40 insertions(+) - -diff --git a/glib/tests/test-printf.c b/glib/tests/test-printf.c -index 59a461ddb0..77eb76a4ab 100644 ---- a/glib/tests/test-printf.c -+++ b/glib/tests/test-printf.c -@@ -895,6 +895,44 @@ test_upper_bound (void) - g_assert_cmpint (res, ==, 20); - } - -+static gint test_vasprintf_va (gchar **string, -+ const gchar *format, -+ ...) G_GNUC_PRINTF (2, 3); -+ -+/* Wrapper around g_vasprintf() which takes varargs */ -+static gint -+test_vasprintf_va (gchar **string, -+ const gchar *format, -+ ...) -+{ -+ va_list args; -+ gint len; -+ -+ va_start (args, format); -+ len = g_vasprintf (string, format, args); -+ va_end (args); -+ -+ return len; -+} -+ -+static void -+test_vasprintf_invalid_format_placeholder (void) -+{ -+ gint len = 0; -+ gchar *buf = "some non-null string"; -+ -+ g_test_summary ("Test error handling for invalid format placeholder in g_vasprintf()"); -+ -+#pragma GCC diagnostic push -+#pragma GCC diagnostic ignored "-Wformat" -+#pragma GCC diagnostic ignored "-Wformat-extra-args" -+ len = test_vasprintf_va (&buf, "%l", "nope"); -+#pragma GCC diagnostic pop -+ -+ g_assert_cmpint (len, ==, -1); -+ g_assert_null (buf); -+} -+ - int - main (int argc, - char *argv[]) -@@ -935,5 +973,7 @@ main (int argc, - g_test_add_func ("/sprintf/test-positional-params", test_positional_params3); - g_test_add_func ("/sprintf/upper-bound", test_upper_bound); - -+ g_test_add_func ("/vasprintf/invalid-format-placeholder", test_vasprintf_invalid_format_placeholder); -+ - return g_test_run(); - } --- -GitLab diff --git a/patch/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch b/patch/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch deleted file mode 100644 index 59e1d327303d69827eb60703ea063d577627fcae..0000000000000000000000000000000000000000 --- a/patch/backport-tests-Add-unit-tests-for-GDBusMethodInvocation.patch +++ /dev/null @@ -1,441 +0,0 @@ -From a7750cd02004d5e5f2660426b4d6728a604ef1e2 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Thu, 17 Mar 2022 19:05:14 +0000 -Subject: [PATCH] tests: Add unit tests for GDBusMethodInvocation - -These should cover everything to do with returning a value or error from -a `GDBusMethodInvocation` object. - -Signed-off-by: Philip Withnall - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/a7750cd02004d5e5f2660426b4d6728a604ef1e2 - ---- - gio/tests/gdbus-method-invocation.c | 402 ++++++++++++++++++++++++++++ - gio/tests/meson.build | 1 + - 2 files changed, 403 insertions(+) - create mode 100644 gio/tests/gdbus-method-invocation.c - -diff --git a/gio/tests/gdbus-method-invocation.c b/gio/tests/gdbus-method-invocation.c -new file mode 100644 -index 0000000000..985fd45ced ---- /dev/null -+++ b/gio/tests/gdbus-method-invocation.c -@@ -0,0 +1,402 @@ -+/* GIO - GLib Input, Output and Streaming Library -+ * -+ * Copyright 漏 2022 Endless OS Foundation, LLC -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General -+ * Public License along with this library; if not, see . -+ * -+ * SPDX-License-Identifier: LGPL-2.1-or-later -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "gdbus-tests.h" -+ -+static const GDBusArgInfo foo_get_fds_in_args = -+{ -+ -1, -+ "type", -+ "s", -+ NULL -+}; -+static const GDBusArgInfo * const foo_get_fds_in_arg_pointers[] = {&foo_get_fds_in_args, NULL}; -+ -+static const GDBusArgInfo foo_get_fds_out_args = -+{ -+ -1, -+ "some_fd", -+ "h", -+ NULL -+}; -+static const GDBusArgInfo * const foo_get_fds_out_arg_pointers[] = {&foo_get_fds_out_args, NULL}; -+ -+static const GDBusMethodInfo foo_method_info_wrong_return_type = -+{ -+ -1, -+ "WrongReturnType", -+ NULL, /* in args */ -+ NULL, /* out args */ -+ NULL /* annotations */ -+}; -+static const GDBusMethodInfo foo_method_info_close_before_returning = -+{ -+ -1, -+ "CloseBeforeReturning", -+ NULL, /* in args */ -+ NULL, /* out args */ -+ NULL /* annotations */ -+}; -+static const GDBusMethodInfo foo_method_info_get_fds = -+{ -+ -1, -+ "GetFDs", -+ (GDBusArgInfo **) foo_get_fds_in_arg_pointers, -+ (GDBusArgInfo **) foo_get_fds_out_arg_pointers, -+ NULL /* annotations */ -+}; -+static const GDBusMethodInfo foo_method_info_return_error = -+{ -+ -1, -+ "ReturnError", -+ NULL, /* in args */ -+ NULL, /* out args */ -+ NULL /* annotations */ -+}; -+static const GDBusMethodInfo * const foo_method_info_pointers[] = { -+ &foo_method_info_wrong_return_type, -+ &foo_method_info_close_before_returning, -+ &foo_method_info_get_fds, -+ &foo_method_info_return_error, -+ NULL -+}; -+ -+static const GDBusPropertyInfo foo_property_info[] = -+{ -+ { -+ -1, -+ "InvalidType", -+ "s", -+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, -+ NULL -+ }, -+ { -+ -1, -+ "InvalidTypeNull", -+ "s", -+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, -+ NULL -+ }, -+ { -+ -1, -+ "InvalidValueType", -+ "s", -+ G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, -+ NULL -+ }, -+}; -+static const GDBusPropertyInfo * const foo_property_info_pointers[] = -+{ -+ &foo_property_info[0], -+ &foo_property_info[1], -+ &foo_property_info[2], -+ NULL -+}; -+ -+static const GDBusInterfaceInfo foo_interface_info = -+{ -+ -1, -+ "org.example.Foo", -+ (GDBusMethodInfo **) &foo_method_info_pointers, -+ NULL, /* signals */ -+ (GDBusPropertyInfo **) &foo_property_info_pointers, -+ NULL, /* annotations */ -+}; -+ -+/* ---------------------------------------------------------------------------------------------------- */ -+ -+static void -+test_method_invocation_return_method_call (GDBusConnection *connection, -+ const gchar *sender, -+ const gchar *object_path, -+ const gchar *interface_name, -+ const gchar *method_name, -+ GVariant *parameters, -+ GDBusMethodInvocation *invocation, -+ gpointer user_data) -+{ -+ gboolean no_reply = g_dbus_message_get_flags (g_dbus_method_invocation_get_message (invocation)) & G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED; -+ -+ if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && -+ g_str_equal (method_name, "Get")) -+ { -+ const gchar *iface_name, *prop_name; -+ -+ g_variant_get (parameters, "(&s&s)", &iface_name, &prop_name); -+ g_assert_cmpstr (iface_name, ==, "org.example.Foo"); -+ -+ /* Do different things depending on the property name. */ -+ if (g_str_equal (prop_name, "InvalidType")) -+ { -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Type of return value for property 'Get' call should be '(v)' but got '(s)'"); -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "this type is invalid")); -+ } -+ else if (g_str_equal (prop_name, "InvalidTypeNull")) -+ { -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Type of return value for property 'Get' call should be '(v)' but got '()'"); -+ g_dbus_method_invocation_return_value (invocation, NULL); -+ } -+ else if (g_str_equal (prop_name, "InvalidValueType")) -+ { -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Value returned from property 'Get' call for 'InvalidValueType' should be 's' but is 'u'"); -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(v)", g_variant_new_uint32 (123))); -+ } -+ else -+ { -+ g_assert_not_reached (); -+ } -+ -+ g_test_assert_expected_messages (); -+ } -+ else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && -+ g_str_equal (method_name, "Set")) -+ { -+ const gchar *iface_name, *prop_name; -+ GVariant *value; -+ -+ g_variant_get (parameters, "(&s&sv)", &iface_name, &prop_name, &value); -+ g_assert_cmpstr (iface_name, ==, "org.example.Foo"); -+ -+ if (g_str_equal (prop_name, "InvalidType")) -+ { -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Type of return value for property 'Set' call should be '()' but got '(s)'"); -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be unit")); -+ } -+ else -+ { -+ g_assert_not_reached (); -+ } -+ -+ g_test_assert_expected_messages (); -+ g_variant_unref (value); -+ } -+ else if (g_str_equal (interface_name, "org.freedesktop.DBus.Properties") && -+ g_str_equal (method_name, "GetAll")) -+ { -+ const gchar *iface_name; -+ -+ g_variant_get (parameters, "(&s)", &iface_name); -+ g_assert_cmpstr (iface_name, ==, "org.example.Foo"); -+ -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Type of return value for property 'GetAll' call should be '(a{sv})' but got '(s)'"); -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type")); -+ } -+ else if (g_str_equal (interface_name, "org.example.Foo") && -+ g_str_equal (method_name, "WrongReturnType")) -+ { -+ if (!no_reply) -+ g_test_expect_message ("GLib-GIO", G_LOG_LEVEL_WARNING, -+ "Type of return value is incorrect: expected '()', got '(s)'"); -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(s)", "should be a different type")); -+ } -+ else if (g_str_equal (interface_name, "org.example.Foo") && -+ g_str_equal (method_name, "CloseBeforeReturning")) -+ { -+ g_dbus_connection_close (connection, NULL, NULL, NULL); -+ -+ g_dbus_method_invocation_return_value (invocation, NULL); -+ } -+ else if (g_str_equal (interface_name, "org.example.Foo") && -+ g_str_equal (method_name, "GetFDs")) -+ { -+ const gchar *action; -+ GUnixFDList *list = NULL; -+ GError *local_error = NULL; -+ -+ g_variant_get (parameters, "(&s)", &action); -+ -+ list = g_unix_fd_list_new (); -+ g_unix_fd_list_append (list, 1, &local_error); -+ g_assert_no_error (local_error); -+ -+ if (g_str_equal (action, "WrongNumber")) -+ { -+ g_unix_fd_list_append (list, 1, &local_error); -+ g_assert_no_error (local_error); -+ } -+ -+ if (g_str_equal (action, "Valid") || -+ g_str_equal (action, "WrongNumber")) -+ g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, g_variant_new ("(h)"), list); -+ else -+ g_assert_not_reached (); -+ -+ g_object_unref (list); -+ } -+ else if (g_str_equal (interface_name, "org.example.Foo") && -+ g_str_equal (method_name, "ReturnError")) -+ { -+ g_dbus_method_invocation_return_dbus_error (invocation, "org.example.Foo", "SomeError"); -+ } -+ else -+ g_assert_not_reached (); -+} -+ -+static void -+ensure_result_cb (GObject *source, -+ GAsyncResult *result, -+ gpointer user_data) -+{ -+ GDBusConnection *connection = G_DBUS_CONNECTION (source); -+ GVariant *reply; -+ guint *n_outstanding_calls = user_data; -+ -+ reply = g_dbus_connection_call_finish (connection, result, NULL); -+ -+ /* We don鈥檛 care what the reply is. */ -+ g_clear_pointer (&reply, g_variant_unref); -+ -+ g_assert_cmpint (*n_outstanding_calls, >, 0); -+ *n_outstanding_calls = *n_outstanding_calls - 1; -+} -+ -+static void -+test_method_invocation_return (void) -+{ -+ GDBusConnection *connection = NULL; -+ GError *local_error = NULL; -+ guint registration_id; -+ const GDBusInterfaceVTable vtable = { -+ test_method_invocation_return_method_call, NULL, NULL, { 0 } -+ }; -+ guint n_outstanding_calls = 0; -+ -+ g_test_summary ("Test calling g_dbus_method_invocation_return_*() in various ways"); -+ -+ /* Connect to the bus. */ -+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error); -+ g_assert_no_error (local_error); -+ g_assert_nonnull (connection); -+ -+ /* Register an object which we can call methods on. */ -+ registration_id = g_dbus_connection_register_object (connection, -+ "/foo", -+ (GDBusInterfaceInfo *) &foo_interface_info, -+ &vtable, NULL, NULL, &local_error); -+ g_assert_no_error (local_error); -+ g_assert_cmpint (registration_id, !=, 0); -+ -+ /* Test a variety of error cases */ -+ { -+ const struct -+ { -+ const gchar *interface_name; -+ const gchar *method_name; -+ const gchar *parameters_string; -+ gboolean tests_undefined_behaviour; -+ } -+ calls[] = -+ { -+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidType')", TRUE }, -+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidTypeNull')", TRUE }, -+ { "org.freedesktop.DBus.Properties", "Get", "('org.example.Foo', 'InvalidValueType')", TRUE }, -+ { "org.freedesktop.DBus.Properties", "Set", "('org.example.Foo', 'InvalidType', <'irrelevant'>)", TRUE }, -+ { "org.freedesktop.DBus.Properties", "GetAll", "('org.example.Foo',)", TRUE }, -+ { "org.example.Foo", "WrongReturnType", "()", TRUE }, -+ { "org.example.Foo", "GetFDs", "('Valid',)", FALSE }, -+ { "org.example.Foo", "GetFDs", "('WrongNumber',)", TRUE }, -+ { "org.example.Foo", "ReturnError", "()", FALSE }, -+ { "org.example.Foo", "CloseBeforeReturning", "()", FALSE }, -+ }; -+ gsize i; -+ -+ for (i = 0; i < G_N_ELEMENTS (calls); i++) -+ { -+ if (calls[i].tests_undefined_behaviour && !g_test_undefined ()) -+ { -+ g_test_message ("Skipping %s.%s", calls[i].interface_name, calls[i].method_name); -+ continue; -+ } -+ else -+ { -+ g_test_message ("Calling %s.%s", calls[i].interface_name, calls[i].method_name); -+ } -+ -+ /* Call twice, once expecting a result and once not. Do the call which -+ * doesn鈥檛 expect a result first; message ordering should ensure that -+ * it鈥檚 completed by the time the second call completes, so we don鈥檛 -+ * have to account for it separately. -+ * -+ * That鈥檚 good, because the only way to get g_dbus_connection_call() -+ * to set %G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED is to not provide -+ * a callback function. */ -+ n_outstanding_calls++; -+ -+ g_dbus_connection_call (connection, -+ g_dbus_connection_get_unique_name (connection), -+ "/foo", -+ calls[i].interface_name, -+ calls[i].method_name, -+ g_variant_new_parsed (calls[i].parameters_string), -+ NULL, -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ NULL, /* no callback */ -+ NULL); -+ -+ g_dbus_connection_call (connection, -+ g_dbus_connection_get_unique_name (connection), -+ "/foo", -+ calls[i].interface_name, -+ calls[i].method_name, -+ g_variant_new_parsed (calls[i].parameters_string), -+ NULL, -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ ensure_result_cb, -+ &n_outstanding_calls); -+ } -+ } -+ -+ /* Wait until all the calls are complete. */ -+ while (n_outstanding_calls > 0) -+ g_main_context_iteration (NULL, TRUE); -+ -+ g_dbus_connection_unregister_object (connection, registration_id); -+ g_object_unref (connection); -+} -+ -+int -+main (int argc, -+ char *argv[]) -+{ -+ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL); -+ -+ g_test_add_func ("/gdbus/method-invocation/return", test_method_invocation_return); -+ -+ return session_bus_run (); -+} -diff --git a/gio/tests/meson.build b/gio/tests/meson.build -index 81ff551dda..c825b0cd7a 100644 ---- a/gio/tests/meson.build -+++ b/gio/tests/meson.build -@@ -333,6 +333,7 @@ if host_machine.system() != 'windows' - 'suite' : ['slow'], - }, - 'gdbus-introspection' : {'extra_sources' : extra_sources}, -+ 'gdbus-method-invocation' : {'extra_sources' : extra_sources}, - 'gdbus-names' : {'extra_sources' : extra_sources}, - 'gdbus-proxy' : {'extra_sources' : extra_sources}, - 'gdbus-proxy-threads' : { --- -GitLab diff --git a/patch/backport-tests-Make-the-642026-test-take-100x-less-time.patch b/patch/backport-tests-Make-the-642026-test-take-100x-less-time.patch deleted file mode 100644 index 572d790642fc96d1fbd761b7d0336c075cd95233..0000000000000000000000000000000000000000 --- a/patch/backport-tests-Make-the-642026-test-take-100x-less-time.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 80d3018c1d3e3abf3b2440140ceff8cefa5b8902 Mon Sep 17 00:00:00 2001 -From: Philip Withnall -Date: Fri, 4 Mar 2022 19:21:40 +0000 -Subject: [PATCH] =?UTF-8?q?tests:=20Make=20the=20642026=20test=20take=2010?= - =?UTF-8?q?0=C3=97=20less=20time?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -It’s a tradeoff of time against reproducibility of the failure conditions -this test is testing for. If this test is run 100× on CI (which it will -be every few weeks), that should be often enough to catch a regression -here. - -A regression in this code is unlikely, though. - -This change is motivated by the fact that periodically this test times -out, and even when it doesn’t, it takes on average 240s of CI runner -time during each CI run. That’s a lot of resources. - -See: https://gitlab.gnome.org/GNOME/glib/-/jobs/1862013 - -Conflict:NA -Reference:https://gitlab.gnome.org/GNOME/glib/-/commit/80d3018c1d3e3abf3b2440140ceff8cefa5b8902 - -Signed-off-by: Philip Withnall ---- - glib/tests/642026.c | 19 ++++++++++++++----- - 1 file changed, 14 insertions(+), 5 deletions(-) - -diff --git a/glib/tests/642026.c b/glib/tests/642026.c -index aface4ea02..6fed6cd08c 100644 ---- a/glib/tests/642026.c -+++ b/glib/tests/642026.c -@@ -16,10 +16,6 @@ - - #include - --/* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5 -- * iterations exhibited it 10/10 times in practice. YMMV. */ --#define ITERATIONS 100000 -- - static GStaticPrivate sp; - static GMutex *mutex; - static GCond *cond; -@@ -51,6 +47,19 @@ static gpointer thread_func (gpointer nil) - static void - testcase (void) - { -+ /* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5 -+ * iterations exhibited it 10/10 times in practice. YMMV. -+ * -+ * If running with `-m slow` we want to try hard to reproduce the bug 10/10 -+ * times. However, as of 2022 this takes around 240s on a CI machine, which -+ * is a long time to tie up those resources to verify that a bug fixed 10 -+ * years ago is still fixed. -+ * -+ * So if running without `-m slow`, try 100× less hard to reproduce the bug, -+ * and rely on the fact that this is run under CI often enough to have a good -+ * chance of reproducing the bug in 1% of CI runs. */ -+ const guint n_iterations = g_test_slow () ? 100000 : 1000; -+ - g_test_bug ("642026"); - - mutex = g_mutex_new (); -@@ -58,7 +67,7 @@ testcase (void) - - g_mutex_lock (mutex); - -- for (i = 0; i < ITERATIONS; i++) -+ for (i = 0; i < n_iterations; i++) - { - GThread *t1; - --- -GitLab -