GCancellable is meant to be used in multi-thread operations but all the
cancellable instances were sharing a single mutex to synchronize them
which can be less optimal when many instances are in place.
Especially when we're doing a lock/unlock dances that may leave another
thread to take the control of a critical section in an unexpected way.
This in fact was leading to some races in GCancellableSources causing
leaks because we were assuming that the "cancelled" callback was always
called before our dispose implementation.
As per this, use per-instance mutexes.
The lock is also now used only to protect the calls that may interact
with cancelled state or that depends on that, as per this we can just
reduce it to the cancel and reset case, other than to the connect one to
prevent the race that we could have when connecting to a cancellable
that is reset from another thread.
We don't really need to release the locks during callbacks now as they
are per instance, and there's really no function that we allowed to call
during a ::cancelled signal callback that may require an unlocked state.
This could been done in case with a recursive lock, that is easy enough
to implement but not really needed for this case.
Fixes: #2309, #2313
This fixes commit cdcb179808.
`dn_comp()` is needed to build fake DNS records for most of the tests in
this file. The new ownership test is no exception.
See https://gitlab.gnome.org/GNOME/glib/-/jobs/4058481
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
On Linux the error will be `G_IO_ERROR_CONNECTION_REFUSED`, but on macOS
it will be `G_IO_ERROR_TIMED_OUT`. Both errors seem reasonable to me, so
let’s not specifically require one of them.
See: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4104#note_2161451
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
For each test expected to return valid DNS records, test that the
record variants are not floating references.
Also add an test which checks this explicitly for a simple TXT record.
When the file name is too long (for example, more than 238 bytes on
ext4), this will cause the creation of the .trashinfo file to fail.
Let's shorten the .trashinfo filename in this case, after all the
trash specification only requires unique filenames (see
`Contents of a trash directory` section in
https://specifications.freedesktop.org/trash-spec/trashspec-latest.html).
This should test the limits of loading 4GB files on i386 platforms, such
as the Hurd CI runner. On such platforms, `sizeof(size_t) == 4`.
This should fix the compiler warning from
https://gitlab.gnome.org/GNOME/glib/-/jobs/3989442:
```
../gio/tests/file.c:2931:51: error: left shift count >= width of type [-Werror=shift-count-overflow]
2931 | static const gsize testfile_4gb_size = ((gsize) 1 << 32) + (1 << 16); /* 4GB + a bit */
| ^~
cc1: all warnings being treated as errors
```
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
They take too long to include in a normal test run. They’ll still be run
in CI once a week as part of our scheduled slow test job.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The tests - one for sync, one for async - create a sparse file for
this purpose, so this should be cheap on the fileystem.
Of course, the test still allocates >4GB of memory for the data that it
returns from g_file_load_contents(), I hope the CI test runners can deal
with that.
Disable tests that require update-desktop-database when it is missing.
It requires glib to build so it will be missing when bootstrapping glib.
Refactor the ifdef for Windows and MacOS while at it and reduce number
of ifdefs.
Ref: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3658
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
shared-mime-info required glib to build and will not be there during
bootstrap. Skip the test if it is missing.
ref: https://gitlab.gnome.org/GNOME/glib/-/issues/3317
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Previously it was mapped (as a default) to `G_IO_ERROR_FAILED`.
It’s the error that macOS returns when trying to connect to a socket which
is bound but not listened to. Linux returns `ECONNREFUSED` in this case.
It’s helpful if they both map to the same `GIOError` value.
This should fix the `/socket-client/connection-fail` test on macOS,
which is currently
[failing](https://gitlab.gnome.org/GNOME/glib/-/jobs/3970547) with:
```
# GLib-GIO-DEBUG: GSocketClient: Starting TCP connection attempt
# GLib-GIO-DEBUG: GSocketClient: Connection attempt failed: Can't assign requested address
# GLib-GIO-DEBUG: GSocketClient: Starting new address enumeration
# GLib-GIO-DEBUG: GSocketClient: Address enumeration completed (out of addresses)
# GLib-GIO-DEBUG: GSocketClient: Address enumeration failed: (null)
# GLib-GIO-DEBUG: GSocketClient: Connection failed: Could not connect to localhost: Can't assign requested address
not ok /socket-client/connection-fail - GLib-GIO:ERROR:../gio/tests/gsocketclient-slow.c:231:test_connection_failed: assertion failed (local_error == (g-io-error-quark, 39)): Could not connect to localhost: Can't assign requested address (g-io-error-quark, 0)
Bail out!
```
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
See: #3184Fixes: #3394
To avoid adding a large block of macros to gdbusprivate.h, I've only
added a subset of the well-known error names. I chose to draw the
line by adding constants for the errors emitted via their string names
in GDBusConnection, but not for error names that are only mentioned
in `gdbuserror.c` or in tests.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Most D-Bus interfaces are domain-specific, but these interfaces from the
D-Bus Specification are intended to be commonly used in any context for
which they are found to be appropriate.
Most of these use `gdbusprivate.h`. One exception is that
`gio/tests/gdbus-example-*` redefine the constants locally: due to these
files' dual role as part of the unit tests and as sample code, it seems
desirable to ensure that they can still be compiled outside GLib.
Signed-off-by: Simon McVittie <smcv@collabora.com>
These well-known flags and replies are part of the D-Bus Specification,
and also exist with the same names in libdbus header files.
Moving them into a private header means that unit tests like
gdbus-proxy-threads and gdbus-subscribe don't have to reinvent them.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Unlike the various functions to call D-Bus methods, these sort their
arguments in a non-obvious order (bus name, interface, signal, path),
presumably aiming to sort the most-likely-to-be-used arguments first.
Signed-off-by: Simon McVittie <smcv@collabora.com>
These function arguments are arranged in the obvious order from
conceptually largest to smallest: (bus name, path, interface, method).
Signed-off-by: Simon McVittie <smcv@collabora.com>
This test was subscribing to the NameOwnerChanged signal with an
incorrect object path, so the callback would never be called. In this
particular case it doesn't actually matter, because the callback does
nothing anyway (the purpose of this particular test was to test that
the user-data is freed on unsubscription).
Signed-off-by: Simon McVittie <smcv@collabora.com>
Almost identically to the previous commit, fix a similar latent bug in
`g_dbus_connection_export_action_group()`, which was not ready to handle
the fledgling `GActionGroupExporter` being freed early on an error
handling path.
See the previous commit message for details of the approach.
This includes a unit test.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3366
This latent bug wasn’t triggered until commit 3f30ec86c (or its
cherry-pick onto `glib-2-80`, 747e3af99, which was first released in
2.80.1).
That change means that `g_menu_exporter_free()` is now called on the
registration failure path by `g_dbus_connection_register_object()`
before it returns. The caller then tries to call `g_slice_free()` on the
exporter again. The call to `g_menu_exporter_free()` tries to
dereference/free members of the exporter which it expects to be
initialised — but because this is happening in an error handling path,
they are not initialised.
If it were to get any further, the `g_slice_free()` would then be a
double-free on the exporter allocation.
Fix that by making `g_menu_exporter_free()` robust to some of the
exporter members being `NULL`, and moving some of the initialisation
code higher in `g_dbus_connection_export_menu_model()`, and removing the
duplicate free code on the error handling path.
This includes a unit test.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3366
It's an array containing the list of sanitizers in use, normally it
contains a value, but in some cases may have more than one (e.g.
'address' and 'undefined').
And so use it to avoid repeated checks
It looks like that finally also valgrind notices the same leaks as
address sanitizer does. It does it more randomly but it still happens,
so better to inform about until #2309 is resolved.
The test case assumes signals will dispatched in a different order than
they're subscribed. In fact, signals can be dispatched in any order,
and are often dispatched in order.
This commit reorders the subscriptions so they're in order, which is
more logical, and also changes the code to only exit the event loops
when there are no pending handlers ready to dispatch.
GDBusConnection sends each signal to recipients in a separate idle
callback, and there's no particular guarantee about the order in which
they're scheduled or dispatched. For the NameOwnerChanged signal that
reports the name becoming unowned, it's possible that g_bus_watch_name()
gets its idle callback called before the GDBusProxy:g-name-owner
machinery has updated the name owner, in which case the assertion
will fail.
Fixing GNOME/glib#3268 introduced a new subscription to NameOwnerChanged
which can alter the order of delivery, particularly in the case where
G_DBUS_PROXY_FLAGS_NO_MATCH_RULE was used (as tested in
/gdbus/proxy/no-match-rule). The resulting test failure is intermittent,
but reliably appears within 100 repetitions of that test.
Fixes: 511c5f5b "tests: Wait for gdbus-testserver to die when killing it"
Signed-off-by: Simon McVittie <smcv@debian.org>
This was a bug that existed during development of this branch; make sure
it doesn't come back.
This test fails with a use-after-free and crash if we comment out the
part of name_watcher_unref_watched_name() that removes the name watcher
from `map_method_serial_to_name_watcher`.
It would also fail with an assertion failure if we asserted in
name_watcher_unref_watched_name() that get_name_owner_serial == 0
(i.e. that GetNameOwner is not in-flight at destruction).
Signed-off-by: Simon McVittie <smcv@collabora.com>
The vulnerability reported as GNOME/glib#3268 can be characterized
as: these signals from an attacker should not be delivered to either
the GDBusConnection or the GDBusProxy, but in fact they are (in at
least some scenarios).
Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268
Signed-off-by: Simon McVittie <smcv@collabora.com>
The expected result is that because TEST_CONN_SERVICE owns
ALREADY_OWNED_NAME but not (yet) OWNED_LATER_NAME, the signal will be
delivered to the subscriber for the former but not the latter.
Before #3268 was fixed, it was incorrectly delivered to both.
Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268 (partially)
Signed-off-by: Simon McVittie <smcv@collabora.com>
If a connection has two signal subscriptions active for the same signal,
one with arg0 matching and one without, a signal which doesn’t contain
an arg0 value (i.e. `g_dbus_message_get_arg0()` returns `NULL`) will
cause `NULL` to be passed to `strcmp()` when checking for a match
against the signal subscription which *has* arg0 matching, causing a
crash.
Fix that by adding the obvious `NULL` check, and add a unit test.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3342
D-Bus Activation allows passing an array of parameters. Allow apps to
export actions that accept tuples to match the number of elements in the
parameters so the full potential of the D-Bus interface can be used.
Closes: https://gitlab.gnome.org/GNOME/glib/-/issues/3333
Basically various trivial instances of the following MSVC compiler
warning:
```
../gio/gio-tool-set.c(50): warning C4267: '=': conversion from 'size_t' to 'int', possible loss of data
```
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
On GNOME/glib#3268 there was some concern about whether this would
allow an attacker to send signals and have them be matched to a
GDBusProxy in this situation, but it seems that was a false alarm.
Signed-off-by: Simon McVittie <smcv@collabora.com>