upgrade glib from 2.68.1-10.oe2203 to 2.72.2-5.oe2203sp1

Signed-off-by: cyberbox <468042667@qq.com>
This commit is contained in:
cyberbox
2024-02-01 21:28:31 +08:00
parent b028fb783a
commit 3a5ee41439
114 changed files with 12091 additions and 5686 deletions
+1 -1
View File
@@ -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, wed 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
+2 -2
View File
@@ -138,7 +138,7 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name=".*COPYING" desc="License File"/>
<filteritem type="filepath" name="glib2.spec" desc="RPM description"/>
<filteritem type="filepath" name="README.OpenSource" desc="OpenSource README, not linked."/>
<filteritem type="filepath" name="glib-2.68.1.tar.xz" desc="OpenEuler:glib2 code. The files involved in compilation are the LGPL protocol.They are used in dynamic link mode."/>
<filteritem type="filepath" name="glib-2.72.2.tar.xz" desc="OpenEuler:glib2 code. The files involved in compilation are the LGPL protocol.They are used in dynamic link mode."/>
</filefilter>
<filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
<filteritem type="filename" name="Amsterdam-fat" desc="This file is distributed under the same license as the PACKAGE package."/>
@@ -158,7 +158,7 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="glib2.spec" desc="openEuler:glib2 spec."/>
<filteritem type="filepath" name="patch.tar.gz" desc="openEuler:glib2 origin patch."/>
<filteritem type="filepath" name="backport-patch.log" desc="openEuler:glib2 origin patch files name."/>
<filteritem type="filepath" name="glib-2.68.1.tar.xz" desc="openEuler:glib2 code."/>
<filteritem type="filepath" name="glib-2.72.2.tar.xz" desc="openEuler:glib2 code."/>
</filefilter>
</filefilterlist>
</oatconfig>
+1 -1
View File
@@ -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."
}
+55 -11
View File
@@ -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.
(<https://gitlab.gnome.org/GNOME/glib/issues/new>). 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 [GNOMEs 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 <incoming+gnome-glib-658-issue-@gitlab.gnome.org>,
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
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):
Please follow the [contribution guide](./CONTRIBUTING.md) to know how to
start contributing to GLib.
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
```
+6
View File
@@ -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.
+4 -68
View File
@@ -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.
+78
View File
@@ -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 GLibs 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).
+71 -62
View File
@@ -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
+1 -1
View File
@@ -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": {
Binary file not shown.
Binary file not shown.
+171 -83
View File
@@ -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
Source0: https://download.gnome.org/sources/glib/2.71/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
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 <hanhuihui5@huawei.com> - 2.72.2-13
- fix pcre2 error , memory leak and log domains error
* Mon Sep 25 2023 liningjie <liningjie@xfusion.com> - 2.72.2-12
- glocalfilemonitor: Avoid file monitor destruction from event thread
* Sat Aug 19 2023 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-11
- fix double unref and fix group comment management
* Sat Apr 1 2023 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-10
- fix CVE-2023-24593 and CVE-2023-25180
* Tue Mar 14 2023 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-9
- fix a use-after-free of GDBusMethodInvocation
* Thu Feb 16 2023 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-8
- backport some patches from community
* Tue Jan 10 2023 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-7
- adjust pcre2 requires
* Tue Dec 27 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-6
- fix some pcre2 error
* Wed Nov 9 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-5
- separate the test and static package from devel package
* Sat Oct 15 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-4
- backport some patches from community
* Mon Sep 5 2022 hanhuihui <hanhuihui5@huawei.com> - 2.72.2-3
- replace pcre1 with pcre2
* Sat Jun 18 2022 zhujunhao <zhujunhao11@huawei.com> - 2.72.2-2
- remove gnutls require
* Mon Jun 6 2022 lin zhang <lin.zhang@turbolinux.com.cn> - 2.72.2-1
- Update to 2.72.2
* Thu Jun 2 2022 lin zhang <lin.zhang@turbolinux.com.cn> - 2.72.0-1
- Update to 2.72.0
* Thu Apr 28 2022 yanan <yanan@huawei.com> - 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 <hanhui15@h-partners.com> - 2.68.1-11
- DESC:fix gfileenumerator/gdbusobjectmanagerservice/gdbusauth of memory leak
* Fri Mar 11 2022 weijin deng <weijin.deng@turbolinux.com.cn> - 2.68.1-10
- Type:bugfix
- DESC:solve glib2 enable "glib2_debug" option causes gnome-calendar reopen
+6 -4
View File
@@ -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
BIN
View File
Binary file not shown.
@@ -1,219 +0,0 @@
From 34ce204fd758e2ce0ab6bf152051534f46cdb336 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 isnt 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 doesnt
+ * 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 "
+ "doesnt cause problems when racing with method callbacks "
+ "in another thread for that object or subtree");
+
+ /* Run iterations of the test until its likely weve hit the race. Limit the
+ * number of iterations so the test doesnt 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.
+ * Dont fail the test, though, as we cant 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
@@ -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,
@@ -1,26 +0,0 @@
From 6ec432386ef98e26e5079b060ad823277e10f41f Mon Sep 17 00:00:00 2001
From: Loic Le Page <llepage@fluendo.com>
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
@@ -0,0 +1,39 @@
From cabc49407371800733ada202fab721c9091b6fe6 Mon Sep 17 00:00:00 2001
From: Pavel Sobolev <paveloom@riseup.net>
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
@@ -1,52 +0,0 @@
From 9f1c59eef2e21b5a80c22d44deec2cba884cdfce Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -0,0 +1,227 @@
From 329843f682d1216d4f41aab7b5711f21ef280b71 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
<SUBSECTION>
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
<SUBSECTION>
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
@@ -0,0 +1,228 @@
From 4f79f0712cd5c67301e60e758a2f6c60b44e7a0e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Mon, 28 Mar 2022 12:55:20 +0100
Subject: [PATCH] gversionmacros: Add version macros for GLib 2.74
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
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 @@
<title>Index of new symbols in 2.72</title>
<xi:include href="xml/api-index-2.72.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-74" role="2.74">
+ <title>Index of new symbols in 2.74</title>
+ <xi:include href="xml/api-index-2.74.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
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 @@
<title>Index of new symbols in 2.72</title>
<xi:include href="xml/api-index-2.72.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-74" role="2.74">
+ <title>Index of new symbols in 2.74</title>
+ <xi:include href="xml/api-index-2.74.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
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
</SECTION>
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 @@
<title>Index of new symbols in 2.72</title>
<xi:include href="xml/api-index-2.72.xml"><xi:fallback /></xi:include>
</index>
+ <index id="api-index-2-74" role="2.74">
+ <title>Index of new symbols in 2.74</title>
+ <xi:include href="xml/api-index-2.74.xml"><xi:fallback /></xi:include>
+ </index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
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
@@ -1,140 +0,0 @@
From 63873c0eb114faf6696874fe577912af687d67cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
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), &registered_data);
+ g_signal_connect (app, "notify::is-registered", G_CALLBACK (on_registered_notify), &registered_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 (&registered_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 (&registered_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 (&registered_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
@@ -1,28 +0,0 @@
From b71117d89434db83d34bc1b981ca03d4be299576 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
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 <raj.khem@gmail.com>
---
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 its 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
-27
View File
@@ -1,27 +0,0 @@
From df500c68a4d0741d1d6cf8ec3f8039a0d1f4b174 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
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
@@ -1,44 +0,0 @@
From 65b4bc30eb38b1484533a2ee08f7229a9e961af8 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
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
@@ -1,55 +0,0 @@
From 374a1895b62b2504d0b6ae1c404237802e73ddb6 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann <tobias@stoeckmann.org>
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
@@ -1,279 +0,0 @@
From 995823b9d9e866ffb133cf3ff53e7e09da9f13d6 Mon Sep 17 00:00:00 2001
From: Mark Weaver <mark@blushingpenguin.com>
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
@@ -1,27 +0,0 @@
From 2b29495bcb59ba00bec808c509112dae6e019fd7 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
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
{
@@ -1,54 +0,0 @@
From a497fdf302bf67e4df2e1474389c0ff2152f1e99 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Fri, 24 Sep 2021 08:58:42 +0100
Subject: [PATCH] gdbusconnection: Add some ownership annotations
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
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
@@ -0,0 +1,877 @@
From 4900ea5215e329fbfe893be7975cf05ff153ef81 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,194 +0,0 @@
From 50fbf05d61db500df9052bb682d9c01e0bf51ffb Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,62 +0,0 @@
From 117b748e44e0ec930fcb9641e3f808572d4a41f2 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,136 +0,0 @@
From c8c2ed4af5cdf8d77af2cd9a2a4b4f6ac8d1fc70 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,94 +0,0 @@
From 310f2c1632e05c4f32be033c009642012741d876 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -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
@@ -1,53 +0,0 @@
From c74177337dae7b06383261b2bedabf1f12d816b5 Mon Sep 17 00:00:00 2001
From: Sebastian Wilhelmi <wilhelmi@google.com>
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
@@ -1,30 +0,0 @@
From 7143457076d6469f76185a2f1d7071aca40a591e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
Date: Thu, 17 Mar 2022 19:03:15 +0000
Subject: [PATCH] gdbusmethodinvocation: Drop redundant quote from warning
message
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
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
@@ -1,66 +0,0 @@
From a3b8846e54c7132056411605f815b67e831833d2 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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 (&parameters));
#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
@@ -1,81 +0,0 @@
From 76f5460107c86a44be6387c159b34ae50aa1e623 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,43 +0,0 @@
From 719484a5754cca036d123ae4c2ae3d150bacef32 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
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);
}
@@ -1,32 +0,0 @@
From be57c5d14c771361482917f4cb35851a07d19a8e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,29 +0,0 @@
From 8bfc2998135ee9c4460520febb3af720c61438a5 Mon Sep 17 00:00:00 2001
From: Michael Catanzaro <mcatanzaro@gnome.org>
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);
}
@@ -1,72 +0,0 @@
From 49cc9b96f4c19a98ddf6e9b7417c7019ebc28ca3 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -0,0 +1,58 @@
From cef780e9ef86b1d9545db892c6b8340488da21d9 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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
@@ -0,0 +1,82 @@
From f59e02a1439c70616547d51abf0a6da33e095e80 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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
@@ -0,0 +1,53 @@
From cc528f6c2e336a3484c920fe2d11337388829dbe Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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
@@ -0,0 +1,59 @@
From c49502582faedecc7020155d95b16c7a1d78d432 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
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
@@ -0,0 +1,536 @@
From f74589f53041abff29d538a5d9884c3202f2c00a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
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?= <gael@xfce.org>
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
@@ -0,0 +1,97 @@
From 51dfb3c229c0478b3615f486fbbc36de2586bd52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABl=20Bonithon?= <gael@xfce.org>
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
@@ -1,28 +0,0 @@
From 5a032f32ea77d81c012841dde88b070f55037f25 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -0,0 +1,96 @@
From 222f6ceada3c54cddf1cfa7a3b846716bafe244c Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
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 <g.inotify_lock_lock>) at ../glib/gthread-posix.c:1493
#2 0x00007fea69222062 in g_mutex_lock (mutex=mutex@entry=0x7fea6911e148 <g.inotify_lock_lock>) 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=<optimized out>) 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=<optimized out>, child=0x7fea64001460 "spawned-1", rename_to=rename_to@entry=0x0, other=other@entry=0x0, event_time=<optimized out>) at ../gio/glocalfilemonitor.c:457
#10 0x00007fea6907fe0e in ih_event_callback (event=0x7fea64001420, sub=0x1492620, file_event=<optimized out>) 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=<optimized out>, 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 <ip_event_callback>, user_data=<optimized out>) 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=<optimized out>) 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=<optimized out>) at ../glib/gmain.c:6176
#21 0x00007fea691f9c2d in g_thread_proxy (data=0x1487cc0) at ../glib/gthread.c:827
#22 0x00007fea68d93b1a in start_thread (arg=<optimized out>) 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
@@ -0,0 +1,76 @@
From 57bde3c9bda9cfdf1e55fd6ddc1c354bde1ee654 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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`.
Im not sure if that can currently happen, but it could with future
refactoring, so its best to address the possibility now while were
thinking about this bit of code.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
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 its 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
@@ -0,0 +1,157 @@
From 0d4e401ede234a3ce25e6098776ef5e966ad080b Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Thu, 23 Jun 2022 10:18:08 +0100
Subject: [PATCH] gmarkup: Add G_MARKUP_PARSE_FLAGS_NONE
Signed-off-by: Simon McVittie <smcv@collabora.com>
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
@@ -0,0 +1,128 @@
From 71f6d4c129fc729a5ead08637924d8c0973f2fe9 Mon Sep 17 00:00:00 2001
From: Alexander Slobodeniuk <aslobodeniuk@fluendo.com>
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 <aslobodeniuk@fluendo.com>
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<<G_LOG_LEVEL_USER_SHIFT, "foo"));
+ g_setenv ("G_MESSAGES_DEBUG", "foobar", TRUE);
+
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+
+ g_setenv ("G_MESSAGES_DEBUG", "foobar bar", TRUE);
+
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+
+ g_setenv ("G_MESSAGES_DEBUG", "foobar bar barfoo", TRUE);
+
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+
+ g_setenv ("G_MESSAGES_DEBUG", "foobar bar foo barfoo", TRUE);
+
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "baz"));
+
+ g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
+
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "baz"));
+
+ g_setenv ("G_MESSAGES_DEBUG", "foo", TRUE);
+
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foobarbaz"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "barfoobaz"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "barbazfoo"));
+
+ g_setenv ("G_MESSAGES_DEBUG", " foo bar foobaz ", TRUE);
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "foo"));
+ g_assert_false (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "bar"));
+ g_assert_true (g_log_writer_default_would_drop (G_LOG_LEVEL_DEBUG, "baz"));
+
exit (0);
}
--
GitLab
@@ -1,29 +0,0 @@
From 9dc7475f93c5c63fff66999d228407e13a47d5d3 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -1,39 +0,0 @@
From 969eb835dc2f07c34ae8ca45ddbc41590a2e2f8e Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,38 +0,0 @@
From 7329c6e09bf59ccae2d8d3e788ce43bb6af6c3db Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -1,47 +0,0 @@
From a50e605d52534f604776e56fd181ace98b6a0166 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -0,0 +1,679 @@
From 879b9cd669f03ecd69f0c6913f06275d9c1973c6 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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 ("(?<!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 boobar", 0, &match);
@@ -1646,7 +1647,7 @@ test_lookbehind (void)
g_regex_unref (regex);
error = NULL;
- regex = g_regex_new ("(?<=bullock|donkey) poo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=bullock|donkey) poo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "don poo, and bullock poo", 0, &match);
@@ -1659,17 +1660,17 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<!dogs?|cats?) x", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<!dogs?|cats?) x", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex == NULL);
g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND);
g_clear_error (&error);
- regex = g_regex_new ("(?<=ab(c|de)) foo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=ab(c|de)) foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex == NULL);
g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND);
g_clear_error (&error);
- regex = g_regex_new ("(?<=abc|abde)foo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=abc|abde)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abfoo, abdfoo, abcfoo", 0, &match);
@@ -1681,7 +1682,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("^.*+(?<=abcd)", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("^.*+(?<=abcd)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abcabcabcabcabcabcabcabcabcd", 0, &match);
@@ -1690,7 +1691,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3})(?<!999)foo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=\\d{3})(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1702,7 +1703,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3}...)(?<!999)foo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=\\d{3}...)(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1714,7 +1715,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3}(?!999)...)foo", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=\\d{3}(?!999)...)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1726,7 +1727,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=(?<!foo)bar)baz", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?<=(?<!foo)bar)baz", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "foobarbaz barfoobaz barbarbaz", 0, &match);
@@ -1751,7 +1752,7 @@ test_subpattern (void)
gint start;
error = NULL;
- regex = g_regex_new ("cat(aract|erpillar|)", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("cat(aract|erpillar|)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 1);
@@ -1769,7 +1770,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("the ((red|white) (king|queen))", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("the ((red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
@@ -1793,7 +1794,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("the ((?:red|white) (king|queen))", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("the ((?:red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "the white queen", 0, &match);
@@ -1813,7 +1814,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(Sat)(ur)|(Sun))day (morning|afternoon)", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?|(Sat)(ur)|(Sun))day (morning|afternoon)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
@@ -1833,7 +1834,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(abc)|(def))\\1", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?|(abc)|(def))\\1", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_max_backref (regex), ==, 1);
@@ -1851,7 +1852,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(abc)|(def))(?1)", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("(?|(abc)|(def))(?1)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abcabc abcdef defabc defdef", 0, &match);
@@ -1868,7 +1869,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|(?<DN>Sat)(?:urday)?", G_REGEX_OPTIMIZE|G_REGEX_DUPNAMES, 0, &error);
+ regex = g_regex_new ("(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|(?<DN>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+)(?<OPEN>\\()?[^()]+(?(<OPEN>)\\))(b+)$", G_REGEX_OPTIMIZE, 0, &error);
+ regex = g_regex_new ("^(a+)(?<OPEN>\\()?[^()]+(?(<OPEN>)\\))(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> \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_OPTIMIZE|G_REGEX_EXTENDED, 0, &error);
+ regex = g_regex_new ("^(?<pn> \\( ( [^()]++ | (?&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, "<ab<01<23<4>>>>", 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<hello>.*)", 0, 0);
- TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS, 0);
- TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0);
- TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES, 0);
- TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES | G_REGEX_OPTIMIZE, 0);
+ TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
+ TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT);
+ TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT);
+ TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT);
+ TEST_NEW("(?P<A>x)|(?P<A>y)", 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
@@ -0,0 +1,57 @@
From a164b49532957359c781ab56c3e1690f65f40788 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
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
@@ -0,0 +1,47 @@
From aee84cb45caf42e336dee5183d561b89eb44f8f3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 18:56:39 +0200
Subject: [PATCH] gregex: Avoid re-allocating if we have no size change
This is handled by the syscall underneath, but we can just avoid a call
cheaply.
---
glib/gregex.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 84c4245753..cf86f0fe0d 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -832,6 +832,7 @@ recalc_match_offsets (GMatchInfo *match_info,
GError **error)
{
PCRE2_SIZE *ovector;
+ uint32_t pre_n_offset;
uint32_t i;
if (pcre2_get_ovector_count (match_info->match_data) > G_MAXUINT32 / 2)
@@ -842,11 +843,17 @@ recalc_match_offsets (GMatchInfo *match_info,
return FALSE;
}
+ pre_n_offset = match_info->n_offsets;
match_info->n_offsets = pcre2_get_ovector_count (match_info->match_data) * 2;
ovector = pcre2_get_ovector_pointer (match_info->match_data);
- match_info->offsets = g_realloc_n (match_info->offsets,
- match_info->n_offsets,
- sizeof (gint));
+
+ if (match_info->n_offsets != pre_n_offset)
+ {
+ match_info->offsets = g_realloc_n (match_info->offsets,
+ match_info->n_offsets,
+ sizeof (gint));
+ }
+
for (i = 0; i < match_info->n_offsets; i++)
{
match_info->offsets[i] = (int) ovector[i];
--
GitLab
@@ -0,0 +1,56 @@
From 1f88976610d5bcc15ad58c9345848d736d64fd55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 17:16:07 +0200
Subject: [PATCH] gregex: Do not try access the undefined match offsets if we
have no match
In case we're getting NO-MATCH "errors", we were still recomputing the
match offsets and taking decisions based on that, that might lead to
undefined behavior.
Avoid this by just returning early a FALSE result (but with no error) in
case there's no result to proceed on.
Fixes: #2741
---
glib/gregex.c | 6 ++++++
glib/tests/regex.c | 6 ++++++
2 files changed, 12 insertions(+)
diff --git a/glib/gregex.c b/glib/gregex.c
index 219d9cee34..f2a5b5fd1c 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -1073,6 +1073,12 @@ g_match_info_next (GMatchInfo *match_info,
match_info->regex->pattern, match_error (match_info->matches));
return FALSE;
}
+ else if (match_info->matches == PCRE2_ERROR_NOMATCH)
+ {
+ /* We're done with this match info */
+ match_info->pos = -1;
+ return FALSE;
+ }
else
if (!recalc_match_offsets (match_info, error))
return FALSE;
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 10daa7814a..291c21b4c7 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -1669,6 +1669,12 @@ test_class (void)
res = g_match_info_next (match, NULL);
g_assert (!res);
+ /* Accessing match again should not crash */
+ g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
+ "*match_info->pos >= 0*");
+ g_assert_false (g_match_info_next (match, NULL));
+ g_test_assert_expected_messages ();
+
g_match_info_free (match);
g_regex_unref (regex);
}
--
GitLab
@@ -0,0 +1,40 @@
From 664ee9ca6afcc3e08c99f0918982e9d2e22f34a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
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
@@ -0,0 +1,50 @@
From 13ad4296ea8ba66f5620288b2fd06315852e73ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 17:20:45 +0200
Subject: [PATCH] gregex: Fix a potential PCRE2 code leak on reallocation
failures
In case recalc_match_offsets() failed we were just returning, but in
such case, per the documentation we should still set the match_info (if
provided) and free the pcre2 code instance.
So let's just break the loop we're in it, as if we we've no matches set.
This also avoids re-allocating the offsets array and potentially
accessing to unset data.
---
glib/gregex.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index f2a5b5fd1c..6f3ee88122 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -2337,13 +2337,6 @@ g_regex_match_all_full (const GRegex *regex,
info->match_data,
info->match_context,
info->workspace, info->n_workspace);
-
- if (!recalc_match_offsets (info, error))
- {
- g_match_info_free (info);
- return FALSE;
- }
-
if (info->matches == PCRE2_ERROR_DFA_WSSIZE)
{
/* info->workspace is too small. */
@@ -2370,6 +2363,11 @@ g_regex_match_all_full (const GRegex *regex,
_("Error while matching regular expression %s: %s"),
regex->pattern, match_error (info->matches));
}
+ else if (info->matches > 0)
+ {
+ if (!recalc_match_offsets (info, error))
+ info->matches = PCRE2_ERROR_NOMATCH;
+ }
}
pcre2_code_free (pcre_re);
--
GitLab
@@ -0,0 +1,36 @@
From 6c93ac876f71d7221a172e430ca450b6c0b8b699 Mon Sep 17 00:00:00 2001
From: Marco Trevisan <mail@3v1n0.net>
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
@@ -0,0 +1,51 @@
From 11521972f4d345d9a3f68df719f5980085197e47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 18:26:12 +0200
Subject: [PATCH] gregex: Handle the case we need to re-allocate the match data
In case PCRE2 returns an empty match
This can be easily tested by initializing the initial match data to a
value that is less than the expected match values (e.g. by calling
pcre2_match_data_create (1, NULL)), but we can't do it in our tests
without bigger changes.
---
glib/gregex.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index b886b24e2a..84c4245753 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -1027,7 +1027,7 @@ g_match_info_next (GMatchInfo *match_info,
{
gint prev_match_start;
gint prev_match_end;
- gint opts;
+ uint32_t opts;
g_return_val_if_fail (match_info != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@@ -1075,6 +1075,19 @@ g_match_info_next (GMatchInfo *match_info,
match_info->regex->pattern, match_error (match_info->matches));
return FALSE;
}
+ else if (match_info->matches == 0)
+ {
+ /* info->offsets is too small. */
+ match_info->n_offsets *= 2;
+ match_info->offsets = g_realloc_n (match_info->offsets,
+ match_info->n_offsets,
+ sizeof (gint));
+
+ pcre2_match_data_free (match_info->match_data);
+ match_info->match_data = pcre2_match_data_create (match_info->n_offsets, NULL);
+
+ return g_match_info_next (match_info, error);
+ }
else if (match_info->matches == PCRE2_ERROR_NOMATCH)
{
/* We're done with this match info */
--
GitLab
@@ -0,0 +1,27 @@
From 1185a1304a88319b58359105f2c1038ae4d7edce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 16:46:13 +0200
Subject: [PATCH] gregex: Mark g_match_info_get_regex as transfer none
Since it had no explicit annotation, g-i was defaulting to transfer-full
while in this case the GRegex is owned by the GMatchInfo.
---
glib/gregex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 2eb9b858ea..219d9cee34 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -912,7 +912,7 @@ enable_jit_with_match_options (GRegex *regex,
* and must not be freed. Use g_regex_ref() if you need to keep it
* after you free @match_info object.
*
- * Returns: #GRegex object used in @match_info
+ * Returns: (transfer none): #GRegex object used in @match_info
*
* Since: 2.14
*/
--
GitLab
@@ -0,0 +1,34 @@
From 4fca3bba8f38627ee13b99b0b5093b73a2052e77 Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@endlessos.org>
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 <pwithnall@endlessos.org>
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
@@ -0,0 +1,187 @@
From 6caf952e48dbed40b5dcff01a94f57ba079b526c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
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
@@ -0,0 +1,27 @@
From a2b5b9e906256f43b0bac702424613ea0e7ddcb0 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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
@@ -0,0 +1,49 @@
From 6535c77b00a444750148d9d658e4d47214bb4562 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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
@@ -0,0 +1,85 @@
From c05d09044fb71bdea599c81bf0ae896a5503e76a Mon Sep 17 00:00:00 2001
From: Marco Trevisan <mail@3v1n0.net>
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
@@ -0,0 +1,44 @@
From 5cd94a0982e4a910ee33ec58f7678429ec067b6f Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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
@@ -0,0 +1,120 @@
From 406f85a48f1ec41cda15ae617a979f7df749cb27 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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 <philip@tecnocode.co.uk>
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
@@ -0,0 +1,166 @@
From 842a105464f6390a433da8791d7b19b65df16f47 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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 <aleksei@rybalkin.org>
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
@@ -0,0 +1,678 @@
From bcd8cb3e142bf7f1c92583aa81c34fe8ff8521c0 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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 ("(?<!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 boobar", 0, &match);
@@ -1648,7 +1649,7 @@ test_lookbehind (void)
g_regex_unref (regex);
error = NULL;
- regex = g_regex_new ("(?<=bullock|donkey) poo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=bullock|donkey) poo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "don poo, and bullock poo", 0, &match);
@@ -1661,17 +1662,17 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<!dogs?|cats?) x", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<!dogs?|cats?) x", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex == NULL);
g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND);
g_clear_error (&error);
- regex = g_regex_new ("(?<=ab(c|de)) foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=ab(c|de)) foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex == NULL);
g_assert_error (error, G_REGEX_ERROR, G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND);
g_clear_error (&error);
- regex = g_regex_new ("(?<=abc|abde)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=abc|abde)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abfoo, abdfoo, abcfoo", 0, &match);
@@ -1683,7 +1684,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("^.*+(?<=abcd)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("^.*+(?<=abcd)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abcabcabcabcabcabcabcabcabcd", 0, &match);
@@ -1692,7 +1693,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3})(?<!999)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=\\d{3})(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1704,7 +1705,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3}...)(?<!999)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=\\d{3}...)(?<!999)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1716,7 +1717,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=\\d{3}(?!999)...)foo", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=\\d{3}(?!999)...)foo", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "999foo 123abcfoo 123foo", 0, &match);
@@ -1728,7 +1729,7 @@ test_lookbehind (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<=(?<!foo)bar)baz", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<=(?<!foo)bar)baz", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "foobarbaz barfoobaz barbarbaz", 0, &match);
@@ -1753,7 +1754,7 @@ test_subpattern (void)
gint start;
error = NULL;
- regex = g_regex_new ("cat(aract|erpillar|)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("cat(aract|erpillar|)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 1);
@@ -1771,7 +1772,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("the ((red|white) (king|queen))", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("the ((red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
@@ -1795,7 +1796,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("the ((?:red|white) (king|queen))", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("the ((?:red|white) (king|queen))", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "the white queen", 0, &match);
@@ -1815,7 +1816,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(Sat)(ur)|(Sun))day (morning|afternoon)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?|(Sat)(ur)|(Sun))day (morning|afternoon)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_capture_count (regex), ==, 3);
@@ -1835,7 +1836,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(abc)|(def))\\1", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?|(abc)|(def))\\1", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
g_assert_cmpint (g_regex_get_max_backref (regex), ==, 1);
@@ -1853,7 +1854,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?|(abc)|(def))(?1)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?|(abc)|(def))(?1)", G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT, &error);
g_assert (regex);
g_assert_no_error (error);
res = g_regex_match (regex, "abcabc abcdef defabc defdef", 0, &match);
@@ -1870,7 +1871,7 @@ test_subpattern (void)
g_match_info_free (match);
g_regex_unref (regex);
- regex = g_regex_new ("(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|(?<DN>Sat)(?:urday)?", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("(?<DN>Mon|Fri|Sun)(?:day)?|(?<DN>Tue)(?:sday)?|(?<DN>Wed)(?:nesday)?|(?<DN>Thu)(?:rsday)?|(?<DN>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+)(?<OPEN>\\()?[^()]+(?(<OPEN>)\\))(b+)$", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("^(a+)(?<OPEN>\\()?[^()]+(?(<OPEN>)\\))(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) (?<byte> 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> \\( ( [^()]++ | (?&pn) )* \\) )$", G_REGEX_EXTENDED, G_REGEX_MATCH_DEFAULT, &error);
+ regex = g_regex_new ("^(?<pn> \\( ( [^()]++ | (?&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, "<ab<01<23<4>>>>", 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<hello>.*)", G_REGEX_DEFAULT, G_REGEX_MATCH_DEFAULT);
TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS, G_REGEX_MATCH_DEFAULT);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
TEST_NEW("(123\\d*)[a-zA-Z]+(?P<hello>.*)", G_REGEX_CASELESS | G_REGEX_OPTIMIZE, G_REGEX_MATCH_DEFAULT);
-G_GNUC_END_IGNORE_DEPRECATIONS
TEST_NEW("(?P<A>x)|(?P<A>y)", G_REGEX_DUPNAMES, G_REGEX_MATCH_DEFAULT);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
TEST_NEW("(?P<A>x)|(?P<A>y)", 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
@@ -0,0 +1,35 @@
From 710ccee65c010e4548ded487cdc191658f6a1f35 Mon Sep 17 00:00:00 2001
From: Mamoru TASAKA <mtasaka@fedoraproject.org>
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
@@ -0,0 +1,55 @@
From 2c2e059cd354a9020ce9188e58e3ab0683008d08 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
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
@@ -0,0 +1,211 @@
From 7045260c226e409530e4f961f613f8c7d6f6725a Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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
@@ -1,73 +0,0 @@
From b32727d43d9d11aa017f1f29648ad5019376537c Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -1,110 +0,0 @@
From 40a46d1346fdd4e07c648ba1ee78dedd9bfa33ad Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
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
@@ -1,192 +0,0 @@
From d98a52254b4a681569a44f6be2aeceeaed58202c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
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 <io.h>
+#include <fcntl.h>
+#include <windows.h>
#endif
#include <glib.h>
@@ -44,8 +46,8 @@
#include "glibintl.h"
-#ifdef G_OS_WIN32
-#include <windows.h>
+#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
File diff suppressed because it is too large Load Diff
@@ -1,27 +0,0 @@
From d129395fe2f22f12004526bc11ca7d407f42e4ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?GOUJON=20=C3=89van?= <goujon.evan@gmail.com>
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
@@ -0,0 +1,64 @@
From 5e164c661537f6b6ef5adcf0fac949959ef9ffd5 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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
@@ -1,35 +0,0 @@
From 5419228f632af830d9117c142a1c7c1a9708cc08 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -1,77 +0,0 @@
From 36f7684d56c5d6182398b5db992c1e81ef6cb2f5 Mon Sep 17 00:00:00 2001
From: Rozhuk Ivan <rozhuk.im@gmail.com>
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 its 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
@@ -1,97 +0,0 @@
From 9adbdd45d7101405eb05487bdf6a2015af9f8afd Mon Sep 17 00:00:00 2001
From: Chen Guanqiao <chen.chenchacha@foxmail.com>
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 <chen.chenchacha@foxmail.com>
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
@@ -1,58 +0,0 @@
From bb40105fe95b5d95e31715ddb210380d381a1e26 Mon Sep 17 00:00:00 2001
From: Jamie Bainbridge <jamie.bainbridge@gmail.com>
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 <jamie.bainbridge@gmail.com>
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
@@ -0,0 +1,31 @@
From 1a979ab4947fc259af01ea65263aaa4d417553fb Mon Sep 17 00:00:00 2001
From: Philip Withnall <pwithnall@gnome.org>
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 <pwithnall@gnome.org>
---
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
@@ -1,41 +0,0 @@
From 78dc1cc3cd669e9fb92ae7847bab2b308c0a8628 Mon Sep 17 00:00:00 2001
From: Christoph Niethammer <christoph.niethammer@gmail.com>
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 <christoph.niethammer@gmail.com>
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
@@ -1,34 +0,0 @@
From 05dffc1a7f562e9c8c6c21b67f99204f7a7b4e27 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -1,61 +0,0 @@
From 7f6ce4d8d234996b523b71abef139f1c80c88254 Mon Sep 17 00:00:00 2001
From: Egor Bychin <e.bychin@drweb.com>
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
@@ -1,54 +0,0 @@
From 77233f6f0779fe0c1cb48861d7deded4ae413567 Mon Sep 17 00:00:00 2001
From: Sebastian Wilhelmi <wilhelmi@google.com>
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
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
From d4966911e6b35d8923bc6cd58e7cb8a1b0e09d4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 21:44:12 +0200
Subject: [PATCH] tests/regex: Actually check for match options changes
---
glib/tests/regex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index 567b6e2202..abf27e619e 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -105,7 +105,7 @@ test_new (gconstpointer d)
data = g_new0 (TestNewData, 1); \
data->pattern = _pattern; \
data->compile_opts = _compile_opts; \
- data->match_opts = 0; \
+ data->match_opts = _match_opts; \
data->expected_error = 0; \
data->check_flags = TRUE; \
data->real_compile_opts = _real_compile_opts; \
--
GitLab
@@ -0,0 +1,193 @@
From 23c1b401d8c78c2c66d55b94d7d833210d518853 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 14:21:27 +0200
Subject: [PATCH] tests/regex: Add debug strings for compile and match option
flags
In case of failures they give a better info.
---
glib/tests/regex.c | 132 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 122 insertions(+), 10 deletions(-)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index acb082b704..567b6e2202 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -184,6 +184,108 @@ test_match_simple (gconstpointer d)
#define TEST_MATCH_NOTEMPTY_ATSTART(_pattern, _string, _expected) \
TEST_MATCH_SIMPLE_NAMED("notempty-atstart", _pattern, _string, 0, G_REGEX_MATCH_NOTEMPTY_ATSTART, _expected)
+static char *
+compile_options_to_string (GRegexCompileFlags compile_flags)
+{
+ GStrvBuilder *builder = g_strv_builder_new();
+ GStrv strv;
+ char *ret;
+
+ if (compile_flags & G_REGEX_DEFAULT)
+ g_strv_builder_add (builder, "default");
+ if (compile_flags & G_REGEX_CASELESS)
+ g_strv_builder_add (builder, "caseless");
+ if (compile_flags & G_REGEX_MULTILINE)
+ g_strv_builder_add (builder, "multiline");
+ if (compile_flags & G_REGEX_DOTALL)
+ g_strv_builder_add (builder, "dotall");
+ if (compile_flags & G_REGEX_EXTENDED)
+ g_strv_builder_add (builder, "extended");
+ if (compile_flags & G_REGEX_ANCHORED)
+ g_strv_builder_add (builder, "anchored");
+ if (compile_flags & G_REGEX_DOLLAR_ENDONLY)
+ g_strv_builder_add (builder, "dollar-endonly");
+ if (compile_flags & G_REGEX_UNGREEDY)
+ g_strv_builder_add (builder, "ungreedy");
+ if (compile_flags & G_REGEX_RAW)
+ g_strv_builder_add (builder, "raw");
+ if (compile_flags & G_REGEX_NO_AUTO_CAPTURE)
+ g_strv_builder_add (builder, "no-auto-capture");
+ if (compile_flags & G_REGEX_OPTIMIZE)
+ g_strv_builder_add (builder, "optimize");
+ if (compile_flags & G_REGEX_FIRSTLINE)
+ g_strv_builder_add (builder, "firstline");
+ if (compile_flags & G_REGEX_DUPNAMES)
+ g_strv_builder_add (builder, "dupnames");
+ if (compile_flags & G_REGEX_NEWLINE_CR)
+ g_strv_builder_add (builder, "newline-cr");
+ if (compile_flags & G_REGEX_NEWLINE_LF)
+ g_strv_builder_add (builder, "newline-lf");
+ if (compile_flags & G_REGEX_NEWLINE_CRLF)
+ g_strv_builder_add (builder, "newline-crlf");
+ if (compile_flags & G_REGEX_NEWLINE_ANYCRLF)
+ g_strv_builder_add (builder, "newline-anycrlf");
+ if (compile_flags & G_REGEX_BSR_ANYCRLF)
+ g_strv_builder_add (builder, "bsr-anycrlf");
+
+ strv = g_strv_builder_end (builder);
+ ret = g_strjoinv ("|", strv);
+
+ g_strfreev (strv);
+ g_strv_builder_unref (builder);
+
+ return ret;
+}
+
+static char *
+match_options_to_string (GRegexMatchFlags match_flags)
+{
+ GStrvBuilder *builder = g_strv_builder_new();
+ GStrv strv;
+ char *ret;
+
+ if (match_flags & G_REGEX_MATCH_DEFAULT)
+ g_strv_builder_add (builder, "default");
+ if (match_flags & G_REGEX_MATCH_ANCHORED)
+ g_strv_builder_add (builder, "anchored");
+ if (match_flags & G_REGEX_MATCH_NOTBOL)
+ g_strv_builder_add (builder, "notbol");
+ if (match_flags & G_REGEX_MATCH_NOTEOL)
+ g_strv_builder_add (builder, "noteol");
+ if (match_flags & G_REGEX_MATCH_NOTEMPTY)
+ g_strv_builder_add (builder, "notempty");
+ if (match_flags & G_REGEX_MATCH_PARTIAL)
+ g_strv_builder_add (builder, "partial");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_CR)
+ g_strv_builder_add (builder, "newline-cr");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_LF)
+ g_strv_builder_add (builder, "newline-lf");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_CRLF)
+ g_strv_builder_add (builder, "newline-crlf");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_ANY)
+ g_strv_builder_add (builder, "newline-any");
+ if (match_flags & G_REGEX_MATCH_NEWLINE_ANYCRLF)
+ g_strv_builder_add (builder, "newline-anycrlf");
+ if (match_flags & G_REGEX_MATCH_BSR_ANYCRLF)
+ g_strv_builder_add (builder, "bsr-anycrlf");
+ if (match_flags & G_REGEX_MATCH_BSR_ANY)
+ g_strv_builder_add (builder, "bsr-any");
+ if (match_flags & G_REGEX_MATCH_PARTIAL_SOFT)
+ g_strv_builder_add (builder, "partial-soft");
+ if (match_flags & G_REGEX_MATCH_PARTIAL_HARD)
+ g_strv_builder_add (builder, "partial-hard");
+ if (match_flags & G_REGEX_MATCH_NOTEMPTY_ATSTART)
+ g_strv_builder_add (builder, "notempty-atstart");
+
+ strv = g_strv_builder_end (builder);
+ ret = g_strjoinv ("|", strv);
+
+ g_strfreev (strv);
+ g_strv_builder_unref (builder);
+
+ return ret;
+}
+
static void
test_match (gconstpointer d)
{
@@ -191,6 +293,9 @@ test_match (gconstpointer d)
GRegex *regex;
gboolean match;
GError *error = NULL;
+ gchar *compile_opts_str;
+ gchar *match_opts_str;
+ gchar *match_opts2_str;
regex = g_regex_new (data->pattern, data->compile_opts, data->match_opts, &error);
g_assert (regex != NULL);
@@ -199,31 +304,35 @@ test_match (gconstpointer d)
match = g_regex_match_full (regex, data->string, data->string_len,
data->start_position, data->match_opts2, NULL, NULL);
+ compile_opts_str = compile_options_to_string (data->compile_opts);
+ match_opts_str = match_options_to_string (data->match_opts);
+ match_opts2_str = match_options_to_string (data->match_opts2);
+
if (data->expected)
{
if (!match)
- g_error ("Regex '%s' (with compile options %u and "
- "match options %u) should have matched '%.*s' "
- "(of length %d, at position %d, with match options %u) but did not",
- data->pattern, data->compile_opts, data->match_opts,
+ g_error ("Regex '%s' (with compile options '%s' and "
+ "match options '%s') should have matched '%.*s' "
+ "(of length %d, at position %d, with match options '%s') but did not",
+ data->pattern, compile_opts_str, match_opts_str,
data->string_len == -1 ? (int) strlen (data->string) :
(int) data->string_len,
data->string, (int) data->string_len,
- data->start_position, data->match_opts2);
+ data->start_position, match_opts2_str);
g_assert_cmpint (match, ==, TRUE);
}
else
{
if (match)
- g_error ("Regex '%s' (with compile options %u and "
- "match options %u) should not have matched '%.*s' "
- "(of length %d, at position %d, with match options %u) but did",
- data->pattern, data->compile_opts, data->match_opts,
+ g_error ("Regex '%s' (with compile options '%s' and "
+ "match options '%s') should not have matched '%.*s' "
+ "(of length %d, at position %d, with match options '%s') but did",
+ data->pattern, compile_opts_str, match_opts_str,
data->string_len == -1 ? (int) strlen (data->string) :
(int) data->string_len,
data->string, (int) data->string_len,
- data->start_position, data->match_opts2);
+ data->start_position, match_opts2_str);
}
if (data->string_len == -1 && data->start_position == 0)
@@ -232,6 +341,9 @@ test_match (gconstpointer d)
g_assert_cmpint (match, ==, data->expected);
}
+ g_free (compile_opts_str);
+ g_free (match_opts_str);
+ g_free (match_opts2_str);
g_regex_unref (regex);
}
--
GitLab
@@ -0,0 +1,33 @@
From df66951b96fdb800c0b6bd11292bb23fbcd6ed85 Mon Sep 17 00:00:00 2001
From: Aleksei Rybalkin <aleksei@rybalkin.org>
Date: Thu, 1 Sep 2022 18:19:11 +0200
Subject: [PATCH] tests/regex: Add test for gtksourceview regression
---
glib/tests/regex.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/glib/tests/regex.c b/glib/tests/regex.c
index ce946d0592..10daa7814a 100644
--- a/glib/tests/regex.c
+++ b/glib/tests/regex.c
@@ -2434,6 +2434,16 @@ main (int argc, char *argv[])
TEST_NEW_FAIL ("\\k", 0, G_REGEX_ERROR_MISSING_NAME);
TEST_NEW_FAIL ("a[\\NB]c", 0, G_REGEX_ERROR_NOT_SUPPORTED_IN_CLASS);
TEST_NEW_FAIL ("(*:0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEFG)XX", 0, G_REGEX_ERROR_NAME_TOO_LONG);
+ /* See https://gitlab.gnome.org/GNOME/gtksourceview/-/issues/278 */
+ TEST_NEW_FAIL ("(?i-x)((?:(?i-x)[^\\x00\\t\\n\\f\\r \"'/<=>\\x{007F}-\\x{009F}" \
+ "\\x{FDD0}-\\x{FDEF}\\x{FFFE}\\x{FFFF}\\x{1FFFE}\\x{1FFFF}" \
+ "\\x{2FFFE}\\x{2FFFF}\\x{3FFFE}\\x{3FFFF}\\x{4FFFE}\\x{4FFFF}" \
+ "\\x{5FFFE}\\x{5FFFF}\\x{6FFFE}\\x{6FFFF}\\x{7FFFE}\\x{7FFFF}" \
+ "\\x{8FFFE}\\x{8FFFF}\\x{9FFFE}\\x{9FFFF}\\x{AFFFE}\\x{AFFFF}" \
+ "\\x{BFFFE}\\x{BFFFF}\\x{CFFFE}\\x{CFFFF}\\x{DFFFE}\\x{DFFFF}" \
+ "\\x{EFFFE}\\x{EFFFF}\\x{FFFFE}\\x{FFFFF}\\x{10FFFE}\\x{10FFFF}]+)" \
+ "\\s*=\\s*)(\\\")",
+ G_REGEX_RAW, G_REGEX_ERROR_HEX_CODE_TOO_LARGE);
/* These errors can't really be tested easily:
* G_REGEX_ERROR_EXPRESSION_TOO_LARGE
--
GitLab
@@ -0,0 +1,38 @@
From fe1c2628d52ca67ffe59420a0b4d371893795e62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 6 Sep 2022 19:19:03 +0200
Subject: [PATCH] regex: Avoid allocating offsets until we've a match
There's no much point of pre-allocating offsets given that we're doing
this when needed if only have matches to store.
So let's just allocate the spaces for the dummy offset we depend on,
while allocate the others on demand.
---
glib/gregex.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/glib/gregex.c b/glib/gregex.c
index 8a3be9076b..7d403ad53d 100644
--- a/glib/gregex.c
+++ b/glib/gregex.c
@@ -806,15 +806,11 @@ match_info_new (const GRegex *regex,
{
/* These values should be enough for most cases, if they are not
* enough g_regex_match_all_full() will expand them. */
- match_info->n_offsets = 24;
match_info->n_workspace = 100;
match_info->workspace = g_new (gint, match_info->n_workspace);
}
- else
- {
- match_info->n_offsets = (match_info->n_subpatterns + 1) * 3;
- }
+ match_info->n_offsets = 2;
match_info->offsets = g_new0 (gint, match_info->n_offsets);
/* Set an invalid position for the previous match. */
match_info->offsets[0] = -1;
--
GitLab

Some files were not shown because too many files have changed in this diff Show More