The previous parsing code could read off the end of a URI if it had an
incorrect %-escaped character in.
Fix that, and more closely implement parsing for the syntax defined in
RFC 6874, which is the amendment to RFC 3986 which specifies zone ID
syntax.
This requires reworking some network-address tests, which were
previously treating zone IDs incorrectly.
oss-fuzz#23816
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Emptying trash over `gio trash` is a bit slow in comparison to plain
`rm -r`. On my system, it took about 3 min to empty the trash with a
folder containing 600 000 files, which is not ideal as `rm -r` call
took just a few seconds. I found that `g_file_delete` is implemented
differently for locations provided by the trash backend. The trash
backend prevents modifications of trashed content thus the delete
operation is allowed only for the top-level files and folders. So it
is not necessary to recursive delete all files as the permission
denied error is returned anyway. Let's call `g_file_delete` only for
top-level items, which reduces the time necessary for emptying trash
from minutes to seconds...
See: https://gitlab.gnome.org/GNOME/nautilus/-/issues/1589
Some filesystems don't have meaningful access times under at least some
circumstances (see #2189, #2205). In this situation the traditional stat()
and related kernel interfaces have to put something meaningless in the
st_atime field, and have no way to signal that it is meaningless.
However, statx() does have a way to signal that the atime is meaningless:
if the filesystem doesn't provide a useful access time, it will unset
the STATX_ATIME bit (as well as filling in the same meaningless value
for the stx_atime field that stat() would have used, for compatibility).
We don't actually *need* the atime, so never include it in the required
mask. This was already done for one code path in commit 6fc143bb
"gio: Allow no atime from statx" to fix#2189, but other callers were
left unchanged in that commit, and receive the same change here.
It is not actually guaranteed that *any* of the flags in the
returned stx_mask will be set (the only guarantee is that items in
STATX_BASIC_STATS have at least a harmless compatibility value, even if
their corresponding flag is cleared), so it might be better to follow
this up by removing the concept of the required mask entirely. However,
as of Linux 5.8 it looks as though STATX_ATIME is the only flag in
STATX_BASIC_STATS that might be cleared in practice, so this simpler
change fixes the immediate regression.
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/2205
Signed-off-by: Simon McVittie <smcv@collabora.com>
It is not allowed to be `NULL` or unset if requested by the file
attribute matcher. Derive it from the basename. This doesn’t handle the
situation of a failed UTF-16 to UTF-8 conversion very well, but will at
least return something.
Note that the `g_filename_display_basename()` function can’t be used as
`GWinHttpFile` provides its URI in UTF-16 rather than in the file system
encoding.
This fixes a crash when using GIMP on Windows. Thanks to lillolollo for
in-depth debugging assistance.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2194
For interoperability with libdbus, we want to use compatible timeouts.
In particular, this fixes a spurious failure of the `gdbus-server-auth`
test caused by libdbus and gdbus choosing to expire the key (cookie) at
different times, as diagnosed by Thiago Macieira. Previously, the libdbus
client would decline to use keys older than 7 minutes, but the GDBus
server would not generate a new key until the old key was 10 minutes old.
For completeness, also adjust the other arbitrary timeouts in the
DBUS_COOKIE_SHA1 mechanism to be the same as in libdbus. To make it
easier to align with libdbus, create internal macros with the same names
and values used in dbus-keyring.c.
* maximum time a key can be in the future due to clock skew between
systems sharing a home directory
- spec says "a reasonable time in the future"
- was 1 day
- now 5 minutes
- MAX_TIME_TRAVEL_SECONDS
* time to generate a new key if the newest is older
- spec says "If no recent keys remain, the server may generate a new
key", but that isn't practical, because in reality we need a grace
period during which an old key will not be used for new authentication
attempts but old authentication attempts can continue (in practice both
libdbus and GDBus implemented this logic)
- was 10 minutes
- now 5 minutes
- NEW_KEY_TIMEOUT_SECONDS
* time to discard old keys
- spec says "the timeout can be fairly short"
- was 15 minutes
- now 7 minutes
- EXPIRE_KEYS_TIMEOUT_SECONDS
* time allowed for a client using an old key to authenticate, before
that key gets deleted
- was at least 5 minutes
- now at least 2 minutes
- at least (EXPIRE_KEYS_TIMEOUT_SECONDS - NEW_KEY_TIMEOUT_SECONDS)
Based on a merge request by Philip Withnall.
Fixes: #2164
Thanks: Philip Withnall
Thanks: Thiago Macieira
Signed-off-by: Simon McVittie <smcv@collabora.com>
This doesn't trigger the cancellation assertion issue when run locally
(the task didn't return yet, so the error is simply overwritten), but
perhaps it ever does in CI. Anyhow, it's good to have a cancellation
test.
After a splice operation is finished, it attempts to 1) close input/output
streams, as per the given flags, and 2) return the operation result (maybe
an error, too).
However, if the operation gets cancelled early and the streams indirectly
closed, the splice operation will try to close both descriptors and return
on the task when both are already closed. The catch here is that getting the
streams closed under its feet is possible, so the completion callback would
find both streams closed after returning on the first close operation and
return the error, but then the second operation could be able to trigger
a second error which would be returned as well.
What happens here is up to further race conditions, if the task didn't
return yet, the returned error will be simply replaced (but the old one not
freed...), if it did already return, it'll result in:
GLib-GIO-FATAL-CRITICAL: g_task_return_error: assertion '!task->ever_returned' failed
Fix this by flagging the close_async() callbacks, and checking that both
close operations did return, instead of checking that both streams are
closed by who knows.
This error triggers a semi-frequent CI failure in tracker, see the summary at
https://gitlab.gnome.org/GNOME/tracker/-/issues/240
statx does not provide stx_atime when querying a file in a read-only
mounted file system. So call to statx should not expect it to be in
the mask. Otherwise we would fail with ERANGE for querying any file in
a read-only file system.
Fixes#2189.
The `make_pollfd()` call can’t fail because it only does so if
`cancellable == NULL`, and we’ve already checked that. Assert that’s the
case, to shut Coverity up and to catch behavioural changes in future.
Coverity CID: #1159433
Signed-off-by: Philip Withnall <withnall@endlessm.com>
`g_strsplit()` never returns `NULL`, although it can return an empty
strv (i.e. with its first element being `NULL`).
Drop a redundant `NULL` check.
Coverity CID: #1430976
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If `statx()` is supported, query it for the file creation time and use
that if returned.
Incorporating some minor code rearrangement by Philip Withnall
<withnall@endlessm.com>.
Fixes: #1970
This currently just implements the same functionality as the existing
`stat()`/`fstat()`/`fstatat()`/`lstat()` calls, although where a reduced
field set is requested it may return faster.
Helps: #1970
It turns out that our async write operation implementation is broken
on non-O_NONBLOCK pipes, because the default async write
implementation calls write() after poll() said there were some
space. However, the semantics of pipes is that unless O_NONBLOCK is set
then the write *will* block if the passed in write count is larger than
the available space.
This caused a deadlock in https://gitlab.gnome.org/GNOME/glib/-/issues/2182
due to the loop-back of the app stdout to the parent, but even without such
a deadlock it is a problem that we may block the mainloop at all.
In the particular case of g_subprocess_communicate() we have full
control of the pipes after starting the app, so it is safe to enable
O_NONBLOCK (i.e. we can ensure all the code using the fd after this can handle
non-blocking mode).
This fixes https://gitlab.gnome.org/GNOME/glib/-/issues/2182
This has almost the same semantics as WSAECONNRESET and for all
practical purposes is handled the same. The main difference is about
*who* reset the connection: the peer or something in the network.
For UDP sockets this happens when receiving packets and previously sent
packets returned an ICMP "Time(-to-live) expired" message. This is
similar to WSAECONNRESET, which on UDP sockets happens when receiving
packets and previously sent packets returned an ICMP "Port Unreachable"
message.
This is a step towards supporting `statx()`, which allows the set of
fields it returns to be specified by the caller. Currently, the existing
`stat()` and `fstat()` calls continue to be made, and there are no
behavioural changes — but the new wrapper functions will be extended in
future.
Helps: #1970
Don’t call `g_file_query_exists()` followed by `g_file_delete()`. Just
call `g_file_delete()` and check the error.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Make `G_URI_FLAGS_PARSE_RELAXED` available instead, for the
implementations which need to handle user-provided or incorrect URIs.
The default should nudge people towards being compliant with RFC 3986.
This required also adding a new `G_URI_PARAMS_PARSE_RELAXED` flag, as
previously parsing param strings *always* used relaxed mode and there
was no way to control it. Now it defaults to using strict mode, and the
new flag allows for relaxed mode to be enabled if needed.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2149
Add support for x-gvfs-notrash mount option, which allows to disable
trash functionality for certain mounts. This might be especially useful
e.g. to prevent trash folder creation on enterprise shares, which are
also accessed from Windows...
https://bugzilla.redhat.com/show_bug.cgi?id=1096200
There is already g_unix_mount_at function which allows to find certain
unix mount for given mount path. It would be useful to have similar
function for mount points, which will allow to replace custom codes in
gvfs. Let's add g_unix_mount_point_at.
_g_uri_parse_authority() can be replaced with g_uri_split_network() &
PARSE_STRICT. Keep the original error code, for compatibility reasons.
Notice that GUri uses gint for the port, and value -1 if the port value
is missing. However, GNetworkAddress::port is a guint.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
_g_uri_parse_authority() without argument is actually checking that the
URI is valid, by checking it parses successfully
We keep the existing error domain / code for compatibility reasons,
instead of raising the underlying G_URI_ERROR.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
_g_uri_from_authority() is doing the same work as g_uri_join(): taking
URI components and merging them in a legit URI string, with encoding.
It turns out g_uri_from_authority was unnecessarily complex, since no
caller used the userinfo field.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
It may be defined by the environment (we document that as being allowed)
— if so, individual files should not try to redefine it, as that causes
a preprocessor warning.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Where applicable. Where the current use of `g_file_set_contents()` seems
the most appropriate, leave that in place.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1302
Give GAppInfo a bunch of readonly properties, and
support them in GDesktopAppInfo. This makes app infos
more convenient to work with in GTK4, and in general.
g_task_set_name() was added in GLib 2.60, so only use it in the
overridden definition of g_task_set_source_tag() if the user has said
that they require GLib ≥ 2.60.
This is a follow up to commit b08bd04abe.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
There is no guarantee that this function would not be called
concurrently. Particularly since flatpak_info_read was set to TRUE
before /.flatpak-info is actually read from disk, there is a potential
race where a second thread would return default values for the various
flags set from that file.
Fixes#2159
Correct an off-by-one error in hex_unescape_string()'s computation of
the output string length.
(Turned into a git-format patch by Philip Withnall. Original patch
submitted on the Debian bug tracker, bug#962912.)
It's safe to assume an escaped string doesn't contain embedded null bytes,
but raw memory buffers (as returned by getxattr()) require more care.
If the length of the data to be escaped is known, use that knowledge instead
of invoking strlen().
(Turned into a git-format patch by Philip Withnall. One minor formatting
tweak. Original patch submitted on the Debian bug tracker, bug#962912.)
Fixes: #422
And improve them externally, where not otherwise set, by setting them
from the function name passed to `g_task_set_source_tag()`, if called by
third party code.
This should make profiling and debug output from GLib more useful.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
`complete_in_idle_cb()` shows up in a lot of sysprof traces, so it’s
quite useful to include the most specific contextual information we can
in it.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When an app is spawned using g_desktop_app_info_launch_uris_with_spawn
it will expand the various token in the app's commandline with the
URIs of the files to open. The expand_macro() function that is used for
this advances the pointer to the URI list to show up to which entries
it used.
To not loose the pointer to the list head a duplicate of the URI list
was actually passed to expand_macro(). However, it's not necessary to
create a copy of the URI list for that as expand_macro() will only
change which element the pointer will point to.
This behaviour actually caused the duplicated list to be leaked as the
the list pointer is NULL once all URIs are used up by expand_macro()
and thus nothing was freed at the end of the function.
In ostree based systems, such as flatpak and fedora silverblue, the
time of modification of every system file is epoch 0, including
giomodule.cache, which means that every module is loaded and unloaded
every time.
The solution is to use the change time of the file as well. In a typical
system, it is equal to the mtime, and in an ostree based system, since
the directory is mounted as read-only, the user cannot add a module and
we must assume that the cache file corresponds to the modules.
* Add g_tls_connection_get_channel_binding_data API call
* Add g_dtls_connection_get_channel_binding_data API call
* Add get_binding_data method to GTlsConnection class
* Add get_binding_data method to GDtlsConnection interface
* Add GTlsChannelBindingType enum with tls-unique and
tls-server-end-point types
* Add GTlsChannelBindingError enum and G_TLS_CHANNEL_BINDING_ERROR
quark
* Add new API calls to documentation reference gio-sections-common
This speeds up the `cancellable` test a little by stopping waiting for
the threads to start up as soon as they have started, rather than after
an arbitrary timeout.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1764
This should fix some sporadic test failures in this test, although I
can’t be sure as I was unable to reproduce the original failure.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #1764
It seems that allowing the GCancellable to be finalised in either the
main thread or the worker thread sometimes leads to crashes when running
on CI.
I cannot reproduce these crashes locally, and various analyses with
memcheck, drd and helgrind have failed to give any clues.
Fix this for this particular test case by deferring destruction of the
`GCancellable` instances until after the worker thread has joined.
That’s OK because this test is specifically checking a race between
`g_cancellable_cancel()` and disposal of a `GCancellableSource`.
The underlying bug remains unfixed, though, and I can only hope that we
eventually find a reliable way of reproducing it so it can be analysed
and fixed.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE is set to TRUE only for NFS
filesystem types currently. Let's add also SMB filesystem types. This
also changes g_local_file_is_nfs_home function logic to handle only
NFS filesystems.
The g_local_file_is_remote function is misleading as it works only for
NFS filesystem types and only for locations in home directorly. Let's
rename it to g_local_file_is_nfs_home to make it obvious.
statfs/statvfs is called several times when querying filesystem info.
This is because the G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE attribute is set
over is_remote_fs function, which calls statfs/statvfs again. Let's use
the already known fstype instead of redundant statfs/statvfs calls.
This also changes g_local_file_is_remote implementation to use
g_local_file_query_filesystem_info to obtain fstype, which allows to
remove duplicated code from is_remote_fs function.
The G_FILE_ATTRIBUTE_FILESYSTEM_REMOTE currently works only for locations
in the home directory. Let's make it work also for files outside the home
directory.
There are glocalfile.h and glocalfileprivate.h header files currently.
None of those header files is public, so it doesn't make sense to have
two private headers for glocalfile.c. Let's remove glocalfileprivate.h.
This was mostly machine generated with the following command:
```
codespell \
--builtin clear,rare,usage \
--skip './po/*' --skip './.git/*' --skip './NEWS*' \
--write-changes .
```
using the latest git version of `codespell` as per [these
instructions](https://github.com/codespell-project/codespell#user-content-updating).
Then I manually checked each change using `git add -p`, made a few
manual fixups and dropped a load of incorrect changes.
There are still some outdated or loaded terms used in GLib, mostly to do
with git branch terminology. They will need to be changed later as part
of a wider migration of git terminology.
If I’ve missed anything, please file an issue!
Signed-off-by: Philip Withnall <withnall@endlessm.com>
In glib-networking#127, it was reported that we don't properly implement
the documented behavior of these properties. However, we cannot fix it
because libsoup relies on the implemented behavior, and it's hard to
change that without cascading breakage. The practical solution is to
adjust our documentation to match reality. There should be no downsides
to this, and compat risk of changing the documentation is much smaller
than risk of changing the implementation, so I think this is the best we
can make of an unfortunate situation. See glib-networking#127 for full
discussion and glib-networking#129 for the regression when we attempted
to match the documented behavior.
Some editors automatically remove trailing blank lines, or
automatically add a trailing newline to avoid having a trailing
non-blank line that is not terminated by a newline. To avoid unrelated
whitespace changes when users of such editors contribute to GLib,
let's pre-emptively normalize all files.
Unlike more intrusive whitespace normalization like removing trailing
whitespace from each line, this seems unlikely to cause significant
issues with cherry-picking changes to stable branches.
Implemented by:
find . -name '*.[ch]' -print0 | \
xargs -0 perl -0777 -p -i -e 's/\n+\z//g; s/\z/\n/g'
Signed-off-by: Simon McVittie <smcv@collabora.com>
While these assertions look right at the first glance,
they actually crash the program. That's because GObject
insists on initializing all construct-only properties
to their default values, which results in
g_win32_registry_key_set_property() being called multiple
times with NULL string, once for each unset property.
If "path" is actually set by the caller, a subsequent
call to set "path-utf16" to NULL will fail an assertion,
since absolute_path is already non-NULL.
With assertions moved the set-to-NULL calls bail out before
an assertion is made.
This ensures that we do really export the symbols for Visual
Studio-style builds, by using _GLIB_EXTERN to decorate the generated
prototypes and including config.h so that we are sure the symbols are
actually exported.
This adds three options to gdbus-codegen so that we may be able to
use a self-defined symbol decorator, such as _GLIB_EXTERN, to decorate
the generated prototypes, to be used possibly to export the symbols, if
needed.
The other two options allows including headers that are required for the
specified symbol decorator to be usable and preprocessor macros that are
required for the symbol decorator to be defined appropriately, also when
needed.
Have the generated .c code decorate the prototypes with "G_MODULE_EXPORT"
instead of "extern" when --internal is not being used, so that we also
export the symbols from the generated code on Visual Studio-style
compilers. If --internal is used, we decorate the prototypes with
"G_GNUC_INTERNAL", as we did before.
Note that since the generated .c code does not attempt to include the
generated headers (if one is also generated), the gnerated headers are
still generated as they were before.
Sometimes this test was timing out due to the file monitor notifications
taking longer than the arbitrary 2s delay before ending the test and
checking its results at the end of `iclosed_cb()`.
Avoid that timing-dependence by ending the test when the expected file
monitor notifications are seen, or after a 10s timeout (if so, the test
is failed).
This makes the test run 4× faster in the normal case, as it’s no longer
waiting for a timeout to elapse if the file monitor notifications come
in sooner.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The test added for #1841 spawned 100000 threads. That was fine on a
desktop machine, but on a heavily loaded CI machine, it could result in
large (and unpredictable) slowdowns, resulting in the test taking over
120s in about 1 in 5 runs, and hence failing that CI pipeline due to a
timeout. When passing normally on CI, the test would take around 90s.
Here’s a histogram of time per iteration on a failing (timed out) test
run. Each iteration is one thread spawn:
Iteration duration (µs) | Frequency
------------------------+----------
≤100 | 0
100–200 | 30257
200–400 | 13696
400–800 | 1046
800–1000 | 123
1000–2000 | 583
2000–4000 | 3779
4000–8000 | 4972
8000–10000 | 1027
10000–20000 | 2610
20000–40000 | 650
40000–80000 | 86
80000–100000 | 10
100000–200000 | 2
>200000 | 0
There’s no actual need for the test to spawn 100000 threads, so rewrite
it to reuse a single thread, and pass new data to that thread.
Reverting the original commit (e4a690f5dd) reproduces the failure on
100 out of 100 test runs with this commit applied, so the test still
works.
The test now takes 3s, rather than 11s, to run on my computer, and has
passed when run with `meson test --repeat 1000 cancellable`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
An extra argument to g_win32_registry_key_get_value_w() and
g_win32_registry_key_get_value() indicates that RegLoadMUIStringW()
should be used instead of RegQueryValueExW(). It only works on
strings, and automatically resolves resource strings (the ones
that start with "@").
The extra argument is needed to find resource DLLs that are only
specified by their relative name.
It is critical to mention how the identity parameter is expected to be
handled. In particular, if identity is not passed, then the identity of
the server certificate will not be checked at all. This is in contrast
to the connection-level APIs, which are supposed to be fail-safe. The
database and certificate-level APIs are more manual.
There’s no need to call `access()` and then `stat()` on the keyring
directory to check that it exists, is a directory, and has the right
permissions. Just call `stat()`.
This eliminates one potential TOCTTOU race in this code.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1954
There was a time-of-check-to-time-of-use (TOCTTOU) race in the keyring
lock code, where it would check the existence of the lock file using
`access()`, then proceed to call `open(O_CREAT | O_EXCL)` to try and
create the lock file once `access()` showed that it didn’t exist.
The problem is that, because this is happening in a shared directory
(`~/.dbus-keyrings`), another process could quite legitimately create
the lock file in the meantime.
Instead, unconditionally call `open()` and ignore errors from it (which
will be returned if the lock file already exists) until it succeeds (or
the code times out).
This eliminates the TOCTTOU race, and simplifies the timeout behaviour
so there aren’t two loops (check for existence, try to create)
happening. It brings this code in line with what dbus.git does (see
`_dbus_keyring_lock()`).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1954
When multiple tests were run in parallel, this would race on its access
to `~/.dbus-keyrings` to authenticate with the D-Bus server, since the
keyring directory was not appropriately sandboxed to the unit test.
Use `G_TEST_OPTION_ISOLATE_DIRS` to automatically isolate each unit
test’s directory usage.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1954
Commit 721e385 left one remaining race in the filter test, with a
comment associated with it. Unfortunately, the (seemingly unrelated)
changes in #1841 to `GCancellable` seem to have made this remaining race
a lot more likely to fail on FreeBSD than before.
What’s likely to have happened (although I was unable to reproduce the
failure, due to not having a FreeBSD system; I was only able to
reproduce the problem as a 3/1000 failure on Linux, which is still worth
fixing) is that the atomic write of the `FilterData.serial` to be
expected by the filter function sometimes happened after the filter
function had executed, so the expected message was dropped and didn’t
result in an update to the `FilterData` state.
Rework the test so that instead of setting some expectations (on
`FilterData`) in one thread and then checking them in another thread,
the worker thread just unconditionally returns messages from the filter
function to the main thread, and then the main thread checks whether the
expected one has been filtered.
With this change applied, the `gdbus-connection` test passes 5000 times
in a row for me, on Linux; and doesn’t seem to fail any more on the
FreeBSD CI machines over a few runs. (Previously it failed on 4/5 runs.)
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2092Fixes: #1957
Mention in the documentation that (presumably for performance reasons)
the search results from `g_desktop_app_info_search()` are not filtered
by executable presence or hidden attribute.
Perhaps they should be in future, but for now we should at least
document it.
Spotted by Will Thompson.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
By default, meson builds glib with -Werror=format=2, which
implies -Werror=format-nonliteral. With these flags, clang errors
out on e.g. the g_message_win32_error function, due to "format
string is not a string literal". This function takes a format
string, and passes the va_list of the arguments onwards to
g_strdup_vprintf, which is annotated with printf attributes.
When passing a string+va_list to another function, GCC doesn't warn
with -Wformat-nonliteral. Clang however does warn, unless the
functions themselves (g_message_win32_error and set_error) are decorated
with similar printf attributes (to force the same checks upon the
caller) - see
https://clang.llvm.org/docs/AttributeReference.html#format
for reference.
Adding these attributes revealed one existing mismatched format string
(fixed in the preceding commit).
The GIO tests memory-monitor-dbus and memory-monitor-portal use a number
of third party Python modules that may not be present when running the
test case.
Instead of failing due to missing imports, catch the ImportError and
mock a test case that skips. This can't use the usual unittest.skip
logic because the test case class itself uses a 3rd party module.
Closes#2083.
There are two memory monitor tests that use Python's unittest module directly,
but GLib tests should be outputting TAP. Use the embedded TAPTestRunner to
ensure that TAP is output for these tests too.
The G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE attribute doesn't have to be
always set. See https://gitlab.gnome.org/GNOME/gvfs/-/merge_requests/68
for more details. In that case, the g_file_query_default_handler function
fails with the "No application is registered as handling this file" error.
Let's fallback to the "standard::fast-content-type" attribute instead to
fix issues when opening such files.
https://gitlab.gnome.org/GNOME/nautilus/-/issues/1425
Meson 0.54.0 added a new method meson.override_dependency() that must be
used to ensure dependency consistency. This patch ensures a project that
depends on glib will never link to a mix of system and subproject
libraries. It would happen in such cases:
The system has glib 2.40 installed, and a project does:
dependency('glib-2.0', version: '>=2.60',
fallback: ['glib', 'glib_dep'])
dependency('gobject-2.0')
The first call will configure glib subproject because the system libglib
is too old, but the 2nd call will return system libgobject.
By overriding 'gobject-2.0' dependency while configuring glib subproject
during the first call, meson knows that on the 2nd call it must return
the subproject dependency instead of system dependency.
This also has the nice side effect that with Meson >0.54.0 an
application depending on glib can declare the fallback without knowing
the dependency variable name: dependency('glib-2.0', fallback: 'glib').
Slightly unexpectedly, `g_icon_serialize()` doesn’t produce a floating
`GVariant`, it produces one with full ownership and returns that. That’s
not the convention for `GVariant` return values from functions which
build variants, but there’s nothing we can do to change this now as that
would be an API break.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
D-Bus filter functions run in a worker thread. The `gdbus-connection`
test was sharing a `FilterData` struct between the main thread and the
filter function, which was occasionally (on the order of 0.01% of test
runs) causing spurious test failures due to racing on reads/writes of
`num_handled`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #480
g_assert() can be compiled out with G_DISABLE_ASSERT, which renders the
test rather useless.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #480
If a username and password are specified by the caller, `GSocks5Proxy`
tells the server that it supports anonymous *and* username/password
authentication, and the server can choose which it prefers.
Otherwise, `GSocks5Proxy` only says that it supports anonymous
authentication. If that’s not acceptable to the server, the code was
previously returning `G_IO_ERROR_PROXY_AUTH_FAILED`. That error code
doesn’t indicate to the caller that authentication might succeed were
they to provide a username and password.
Change the error handling to make that clearer. A fuller solution would
be to expose more of the method negotiation in the `GSocks5Proxy` API,
so that the caller can specify ahead of time which authentication
methods they want to use. That can follow in issue #2059 though.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1988
They were not actually asynchronous, and hence caused blocking in the
main thread. Deleting them means the default implementation of those
vfuncs is used, which runs the sync implementation in a thread — which
is what is wanted here.
Spotted by Benjamin Otte.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2051
There’s a minor race condition between cancellation of a `GCancellable`,
and disposal/finalisation of a `GCancellableSource` in another thread.
Thread A Thread B
g_cancellable_cancel(C)
→cancellable_source_cancelled(C, S)
g_source_unref(S)
cancellable_source_dispose(S)
→→g_source_ref(S)
→→# S is invalid at this point; crash
Thankfully, the `GCancellable` sets `cancelled_running` while it’s
emitting the `cancelled` signal, so if `cancellable_source_dispose()` is
called while that’s high, we know that the thread which is doing the
cancellation has already started (or is committed to starting) calling
`cancellable_source_cancelled()`.
Fix the race by resurrecting the `GCancellableSource` in
`cancellable_source_dispose()`, and signalling this using
`GCancellableSource.resurrected_during_cancellation`. Check for that
flag in `cancellable_source_cancelled()` and ignore cancellation if it’s
set.
The modifications to `resurrected_during_cancellation` and the
cancellable source’s refcount have to be done with `cancellable_mutex`
held so that they are seen atomically by each thread. This should not
affect performance too much, as it only happens during cancellation or
disposal of a `GCancellableSource`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1841
`g_assert()` is compiled out if `G_DISABLE_ASSERT` is defined, and
`g_assert_*()` gives more detailed failure messages.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Guard against NULL type being passed to
g_content_type_get_generic_icon_name() just as we protect
g_content_type_get_description(), otherwise it will cause a crash.
See https://gitlab.gnome.org/GNOME/gtk/issues/2482
Distributions will likely want to update GLib before
GObject-Introspection, to avoid circular dependencies.
Signed-off-by: Simon McVittie <smcv@debian.org>
It was checking for the main SOCKS5 version number, rather than the
subnegotiation version number. The username/password authentication
protocol is described in https://tools.ietf.org/html/rfc1929.
Spotted and diagnosed by lovetox.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1986
Clang warns about string+int not appending to the string (to try and
catch newbie mistakes). While this test didn’t expect that to happen, it
was substituting the same constant string in multiple places for no good
reason. Switch to a single static const string, which should also fix
the compiler warning.
We have to define the string length since it’s used in various
stack-allocated array lengths. This is the easiest fix without more
major refactoring of the test to be less 90s.
Also make things a bit more static.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When running under CI, each iteration takes so long that the total test
time is around 200s. If the CI runner is highly loaded, this can tip it
over the timeout of 360s.
Reduce the iteration counts unless running the test thoroughly.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
Currently the test waits for 1s before deciding that a refcount has been
leaked. But slow test machines might take longer than that between
scheduling different threads to sort out the refcount, so increase the
timeout.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
Previously, if the `--address` option was passed to `gdbus-tool`, it
would treat the connection as peer to peer. However, almost all the
commands `gdbus-tool` supports require a message bus (introspection,
calling a method with a destination, etc.). Only the `signal` command
would ever work on a peer-to-peer connection (if no `--dest` was
specified).
So change the `--address` option to generally create message bus
connections.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #938
bindfs is part of the setup process, so if it fails (as can happen if
the `fuse` kernel module has not been loaded — not much we can do about
that) then skip the test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Add a note to the documentation of
`g_dbus_connection_signal_unsubscribe()`, `g_bus_unwatch_name()` and
`g_bus_unown_name()` warning about the need to continue iterating the
caller’s thread-default `GMainContext` until the
unsubscribe/unwatch/unown operation is complete.
See the previous few commits and #1515 for an idea of the insidious bugs
that can be caused by not iterating the `GMainContext` until
everything’s synchronised.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When testing that signals are delivered to the correct thread, and are
delivered the correct number of times, call `EmitSignal()` on the
`gdbus-testserver` to trigger a signal emission, and listen for that.
Previously, the code listened for `NameOwnerChanged` and connected to
the bus again to trigger emission of that. The problem with that is that
other things happening on the bus (for example, an old
`gdbus-testserver` instance disconnecting) can cause `NameOwnerChanged`
signal emissions. Sometimes, the `gdbus-threading` test was failing the
`signal_count == 1` assertion due to receiving more than one
`NameOwnerChanged` emission.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
This is equivalent, but makes the loop exit conditions a little clearer,
since they’re actually in a `while` statement, rather than being a
`g_main_loop_quit()` call in a callback somewhere else in the file.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
As with the previous commit, don’t stop iterating the `context` in
`test_delivery_in_thread_func()` until the unsubscription from a signal
is complete, and hence there’s a guarantee that no callbacks are pending
in the `thread_context`.
This commit uses the `GDestroyNotify` for
`g_dbus_connection_signal_subscribe()` as a synchronisation message from
the D-Bus worker thread to the `test_delivery_in_thread_func()` thread
to notify of signal unsubscription.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1515
Previously, the code in `ensure_gdbus_testserver_up()` created a proxy
object and watched its `name-owner` to see when the
`com.example.TestService` name appeared.
This ended up subscribing to three signals (one of them for name
ownership, and two unused for properties of the proxy), and was racy. In
particular, the `name-owner` property could be set before all D-Bus
messages had been processed — it could have been derived from getting
the owner of the name, for example.
This left unprocessed messages hanging around in the `context`, but that
context was never iterated again, which essentially leaked the
references held by those messages. That included a reference to the
`GDBusConnection`.
The first part of the fix is to simplify the code to use
`g_bus_watch_name_on_connection()`, so there’s only one signal
subscription to worry about.
The second part of the fix is to use the `GDestroyNotify` callback for
the watch data to be notified of when all D-Bus traffic has been
processed and the signal unsubscription is complete. At this point, it’s
guaranteed that there are no idle callbacks pending in the
`GMainContext`, since the `GDestroyNotify` callback is the last one
invoked on the `GMainContext`.
Essentially, this commit uses the `GDestroyNotify` callback as a
synchronisation message between the D-Bus worker thread and the thread
calling `ensure_gdbus_testserver_up()`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1515
Iterate the given `context` while waiting, rather than sleeping. This
ensures that if the errant `GDBusConnection` ref is held by some pending
callback in the given `context`, it will actually be released.
Typically `context` is going to be the global default main context.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
This introduces no functional changes, but makes the code a little more
explicit about which connection and main context it’s operating on.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
`CallDestroyNotifyData` never uses that `GMainContext`, and holding a
ref to it could cause reference count cycles if the `GMainContext` is no
longer being iterated.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1515
The fix for bgo#651133 (commit 7e0f890e38) introduced a kind of weak
ref, which had to be thread-safe due to the fact that `GDBusProxy`
operates in one thread but can emit signals in another.
Since that commit, `GWeakRef` was added, which does the same thing. Drop
the custom code in favour of it; this should be functionally equivalent,
but using an RW lock rather than a basic mutex, which should reduce
contention.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
These checks used to be a precondition on test_threaded_singleton(); but
the earlier tests could leave the refcount of the shared connection in a
bad state, and this wouldn’t be caught until later.
Factor out the check, increase the iteration count to 1000 (so the check
blocks for up to 1s rather than 100ms), and call it in more places.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1515
g_assert() can be compiled out with G_DISABLE_ASSERT, which renders the
test rather useless.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1515
mtab_file_changed_id is not currently removed when finalizing, which
could potentially lead to segfaults. Let's remove the source when
finalizing to avoid this.
mtab_file_changed_id might be set on thread default context, but it is
always cleared on the global context because of usage of g_idle_add. This
can cause the emission of redundant "mounts-change" signals. This should
not cause any issues to the client application, but let's attach the idle
source to the thread-default context instead to avoid those races for sure.
The `get_mounts_timestamp()` function uses `mount_poller_time` when
`proc_mounts_watch_source` is set, but the `mount_poller_time` is not
initialized in the same time as `proc_mounts_watch_source`. This may
cause that zero, or some outdated value is returned. Let's initialize
`mount_poller_time` to prevent invalid values to be returned.
The Nautilus test suite often crashes with "GLib-FATAL-CRITICAL:
g_source_is_destroyed: assertion 'g_atomic_int_get (&source->ref_count)
> 0' failed" if it is started with "GIO_USE_VOLUME_MONITOR=unix". This
is because GUnixMountMonitor is simultaneously used from multiple
threads over GLocalFile and GVolumeMonitor APIs. Let's add guards for
proc_mounts_watch_source and mount_poller_time variables to prevent
those crashes.
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2030
There was a slight race in name ownership: a gap between calling
`RequestName` (or receiving its reply) and subscribing to `NameLost`. In
that gap, another process could request and receive the name, and this
one wouldn’t know about it.
Fix that by subscribing to `NameAcquired` and `NameLost` before calling
`RequestName`, and then unsubscribing again if the subscriptions turn
out not to be necessary (if the process can’t own the requested name).
Spotted and diagnosed by Miika Karanki.
One of the tests needs an additional iteration of the main loop in order
to free all the signal closures before it can complete its checks.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1517
This is a fairly large refactoring. The highlights are:
- Removing in-progress connections/addresses from GSocketClientAsyncConnectData:
This caused issues where multiple ConnectionAttempt's would step over eachother
and modify shared state causing bugs like accidentally bypassing a set proxy.
Fixes#1871Fixes#1989Fixes#1902
- Cancelling address enumeration on error/completion
- Queuing successful TCP connections and doing application layer work serially:
This is more in the spirit of Happy Eyeballs but it also greatly simplifies
the flow of connection handling so fewer tasks are happening in parallel
when they don't need to be.
The behavior also should more closely match that of g_socket_client_connect().
- Better track the state of address enumeration:
Previously we were over eager to treat enumeration finishing as an error.
Fixes#1872
See also #1982
- Add more detailed documentation and logging.
Closes#1995
There were some problems about where to install `gio-launch-desktop` to
support multiarch systems without circular dependencies. Simon McVittie
suggested that, actually, given the current set of platforms supported
by `GDesktopAppInfo` (they’re all POSIX), we could just use `sh`.
That simplifies things nicely. `gio-launch-desktop` can always be
resurrected (and the multiarch debate continued and resolved) if needed
in future.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1633
Some CI platforms invoke these tests with euid != 0 but with
capabilities. Detect whether we have Linux CAP_DAC_OVERRIDE or other
OSs' equivalents, and skip tests that rely on DAC permissions being
denied if we do have that privilege.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2027
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2028
There were a couple of custom paths which could end up being relative,
rather than absolute, due to not properly prefixing them with
`get_option('prefix')`.
The use of `join_paths()` here correctly drops all path components
before the final absolute path in the list of arguments. So if someone
configures GLib with an absolute path for `gio_module_dir`, that will be
used unprefixed; but if someone configures with a relative path, it will
be prefixed by `get_option('prefix)`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1919
The loops should continue iterating if the timeout is non-zero and we're
still waiting for the updated value. Otherwise, if things break, we'll
be waiting until we receive a value that never arrives.
"gio info" output doesn't contain any information about mount points, but
that information can be useful when debugging issues in facilities that
depend on knowing about mount points, such as the trash API.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Co-authored-by: Ondrej Holy <oholy@redhat.com>
Documentation says that g_file_peek_path() returns exactly the same
what g_file_get_path(), but this is not true. Apart from that the code
segfaults for some uris (e.g. for "trash:///"), it returns target-uri
for trash and recent schemes. This is unexpected and can lead to various
issues among others because the target-uri paths are not automatically
translated back to GDaemonFile as it is done with gvfsd-fuse paths.
g_file_get_path() returns NULL for trash and recent schemes, because
fuse paths are not provided for those schemes. So g_file_peek_path()
should return NULL as well. It is up to the concrete application to
use target-uri when appropriate.
This change was made as a part of commit 4808a957, however, neither
the commit message, neither the corresponding bug doesn't mention this
crucial change and doesn't give any clear reasoning. So let's revert
this.
The GMemoryMonitor interface uses G_DECLARE_INTERFACE, which provides a
typedef for the interface dummy type. We declare the same type inside
the global giotypes.h header, which leads to typedef redeclaration
warnings on toolchains that do not support—intentionally or not—the C11
feature of typedef redefinition.
While we do have a toolchain requirement for C11 typedef redefinitions
listed on our wiki, we also suspended it temporarily to allow users of
non-C11 compilers to work on newer versions of GLib; so, let's keep them
working a while longer.
Python tuple comparisons actually do what we want for comparing major
and minor versions, so tidy things up by using that.
This introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This reverts commit b6d8efbebc.
This GLib API is good, but the implentation is not ready, so there's no
reason to commit to the API in GLib 2.64. We can reland again when the
implementation is ready.
There are three problems: (a) The glib-networking implementation normally
works, but the test has been broken for a long time. I'm not comfortable
with adding a major new feature without a working test. This is
glib-networking#104. (b) The WebKit implementation never landed. There
is a working patch, but it hasn't been accepted upstream yet. This API
isn't needed in GLib until WebKit is ready to start using it.
https://bugs.webkit.org/show_bug.cgi?id=200805. (c) Similarly, even if
the WebKit API was ready, that itself isn't useful until an application
is ready to start using it, and the Epiphany level work never happened.
Let's try again for GLib 2.66. Reverting this commit now just means we
gain another six months before committing to the API forever. No reason
to keep this in GLib 2.64 when nothing is using it yet.
Since we (optionally) require nanosecond precision for this
(utimes() is used on *nix), use SetFileTime(), which nominally
has 100ns granularity (actual filesystem might be coarser), instead of
g_utime (), which only has 1-second granularity.
Expand our private statbuf structure with st_mtim, st_atim and st_ctim
fields, which are structs that contain tv_sec and tv_nsec fields,
representing a timestamp with 1-second precision (same value as st_mtime, st_atime
and st_ctime) and a fraction of a second (in nanoseconds) that adds nanosecond
precision to the timestamp.
Because FILEETIME only has 100ns precision, this won't be very precise,
but it's better than nothing.
The private _g_win32_filetime_to_unix_time() function is modified
to also return the nanoseconds-remainder along with the seconds timestamp.
The timestamp struct that we're using is named gtimespec to ensure that
it doesn't clash with any existing timespec structs (MinGW-w64 has one,
MSVC doesn't).
This avoids a crash when starting Evolution, and fixes the
network-monitor and network-monitor-race test cases on my developer
workstation. (I assume the CI is not crashing due to lack of network
access there.)
Problem is that if a network already exists in the networks table,
g_hash_table_add() "destroys" (unrefs) it before adding the new one
(which we failed to ref before adding). This means we just accidentally
lost a ref. In practice, the network gets unexpectedly destroyed here
before returning.
Fixes#2020
This complements the `--glib-min-required` argument, just like the
`GLIB_MIN_REQUIRED` and `GLIB_MAX_ALLOWED` preprocessor defines which
control access to APIs in C.
Currently, it doesn’t affect code generation at all. When we next change
code generation, we will need to gate any new API usage on this
argument.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1993
This makes it consistent with the `GLIB_MIN_REQUIRED` defines which are
used for API stability/versioning in C code.
It doesn’t otherwise change the behaviour of the `--glib-min-version`
argument.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1993
Rather than using an array, which requires a lot of iteration over it to
check whether a particular network is present. Using a hash table only
requires iteration in the can_reach() case, where we need to match a
mask in the networks array, rather than equal it.
This should improve performance for large numbers of routes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1925
Following on from #978, it seems that #1232 is another instance of the
same problem: signals emitted across threads can’t guarantee their user
data is kept alive between committing to emitting the signal and
actually invoking the callback in the relevant thread.
Fix that by using weak refs to the `GDBusObjectManagerClient` as the
user data for its signals, rather than no refs. Strong refs would create
an unbreakable reference count cycle.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1232
It’s possible for `g_bus_unwatch_name()` to be called after a
name-appeared or name-vanished handler has been scheduled to be called
in another thread, but before that callback is actually invoked. If so,
the subscribing thread will receive a callback after it’s called
`g_bus_unwatch_name()`, which is unexpected and could cause bugs.
Double-check `client->cancelled` in the target thread before actually
invoking the callback.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #604
This fixes the following build failure on FreeBSD:
```
In file included from ../gio/tests/win32-appinfo.c:24:
/usr/include/malloc.h:3:2: error: "<malloc.h> has been replaced by <stdlib.h>"
#error "<malloc.h> has been replaced by <stdlib.h>"
```
Hopefully it doesn’t break Windows.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
As with all D-Bus signal subscriptions, it’s possible for a signal
callback to be invoked in one thread (T1) while another thread (T2) is
unsubscribing from that signal. In this case, T1 is the main thread, and
T2 is the D-Bus connection worker thread which is unsubscribing all
signals as it’s in the process of closing.
Due to this possibility, all `user_data` for signal callbacks needs to
be referenced outside the lifecycle of the code which
subscribes/unsubscribes the signal. In other words, it’s not safe to
subscribe to a signal, store the subscription ID in a struct,
unsubscribe from the signal when freeing the struct, and dereference the
struct in the signal callback. The data passed to the signal callback
has to have its own strong reference.
Instead, it’s safe to subscribe to a signal and add a strong reference
to the struct, store the subscription ID in that struct, and unsubscribe
from the signal when the last external reference to your struct is
dropped. That unsubscription should break the refcount cycle between the
signal connection and the struct, and allow the struct to be completely
freed. Only with that approach is it safe to dereference the struct in
the signal callback, if there’s any possibility that the signal might be
unsubscribed from a separate thread.
The tests need specific additional main loop cycles to completely emit
the NameLost signal callback. Ideally they need refactoring, but this
will do (1000 test cycles passed).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #978
This just removes a now-redundant intermediate array. This means that
the `SignalSubscriber` instances are now potentially freed a little
sooner, inside the locked segment, but they are already careful to only
call their `user_data_free_func` in the right thread. So that should not
deadlock.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #978
Instead of storing a copy of the `callback` and `user_data` from a
`SignalSubscriber` in a `SignalInstance` struct (which is the closure
for signal callback data as it’s sent from the D-Bus worker thread to
the thread which originally subscribed to a signal), store a strong
reference to the `SignalSubscriber` struct itself.
This keeps the `SignalSubscriber` alive until the emission is
complete, which ensures that the `user_data` is not freed prematurely.
It also slightly reduces the allocation size of `SignalInstance` (not
that it matters).
This is threadsafe because the fields in `SignalSubscriber` are all
immutable after construction.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #978
Tie the destruction of the `user_data` to the destruction of the
`SignalSubscriber` struct. This is tidier, and ensures that the fields
in `SignalSubscriber` are all immutable after being set, so the
structure can safely be used across threads without locking.
It doesn’t matter which thread we call `call_destroy_notify()` in, since
it always defers calling `user_data_free_func` to the user-provided
`GMainContext`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #978
The `SignalSubscriber` structs contain the callback and `user_data` of each
subscriber to a signal, along with the `guint id` token held by that
subscriber to identify their subscription. There are one or more
`SignalSubscriber` structs for a given signal match rule, which is
represented as a `SignalData` struct.
Previously, the `SignalSubscriber` structs were stored in a `GArray` in
the `SignalData` struct, to reduce the number of allocations needed
when subscribing to a signal.
However, this means that a `SignalSubscriber` struct cannot have a
lifetime which exceeds the `SignalData` which contains it. In order to
fix the race in #978, one thread needs to be able to unsubscribe from a
signal (destroying the `SignalData` struct) while zero or more other
threads are in the process of calling the callbacks from a previous
emission of that signal (using the callback and `user_data` from zero or
more `SignalSubscriber` structs). Multiple threads could be calling
callbacks because callbacks are invoked in the `GMainContext` which
originally made a subscription, and GDBus supports subscribing to a
signal from multiple threads. In that case, the callbacks are dispatched
to multiple threads.
In order to allow the `SignalSubscriber` structs to outlive the
`SignalData` which contained their old match rule, store them in a
`GPtrArray` in the `SignalData` struct, and refcount them individually.
This commit in itself should make no functional changes to how GDBus
works, but will allow following commits to do so.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #978
This adds support for specifying multiple directories in the
GSETTINGS_SCHEMA_DIR environment variable by separating the values
using G_SEARCHPATH_SEPARATOR_S (colon on UNIX-like systems).
While programs could already register multiple custom GSettings schema
directories, it was not possible to achieve the same without writing
custom code, e.g. when using the gsettings command line tool.
Fixes#1998.
1) When parsing the executable name out of the command line,
see if the executable is rundll32.exe. If that is the case,
use the DLL name from its first argument as the "executable"
(this is used only for matching, and Windows Registry matches
these programs by their DLLs, so this is correct; for running
the application GLib would still use the command line, with
rundll32).
2) If an app runs with rundll32, ensure that rundll32 arguments
can be safely quoted. Otherwise GLib will break them with its
protective quotation.
Currently the code generated by gdbus-codegen uses
G_DBUS_CALL_FLAGS_NONE in its D-Bus calls, which occur for each method
defined by the input XML, and for proxy_set_property functions. This
means that if the daemon which implements the methods checks for
G_DBUS_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION and only does interactive
authorization if that flag is present, users of the generated code have
no way to cause the daemon to use interactive authorization (e.g. polkit
dialogs).
If we simply changed the generated code to always use
G_DBUS_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION, its users would have no
way to disallow interactive authorization (except for manually calling
the D-Bus method themselves).
So instead, this commit adds a GDBusCallFlags argument to method call
functions. Since this is an API break which will require changes in
projects using gdbus-codegen code, the change is conditional on the
command line argument --glib-min-version having the value 2.64 or
higher.
The impetus for this change is that I'm changing accountsservice to
properly respect G_DBUS_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION, and
libaccountsservice uses generated code for D-Bus method calls. So
these changes will allow libaccountsservice to continue allowing
interactive authorization, and avoid breaking any users of it which
expect that. See
https://gitlab.freedesktop.org/accountsservice/accountsservice/merge_requests/46
It might make sense to also let GDBusCallFlags be specified for property
set operations, but that is not needed in the case of accountsservice,
and would require significant work and breaking API in multiple places.
Similarly, the generated code currently hard codes -1 as the timeout
value when calling g_dbus_proxy_call*(). Add a timeout_msec argument so
the user of the generated code can specify the timeout as well.
Also, test this new API. In gio/tests/codegen.py we test that the new
arguments are generated if and only of --glib-min-version is used with a
value greater than or equal to 2.64, and in gio/tests/meson.build we
test that the generated code with the new API can be linked against.
The test_unix_fd_list() test also needed modification to continue
working now that we're using gdbus-test-codegen.c with code generated
with --glib-min-version=2.64 in one test.
Finally, update the docs for gdbus-codegen to explain the effect of
using --glib-min-version 2.64, both from this commit and from
"gdbus-codegen: Emit GUnixFDLists if an arg has type `h` w/
min-version".
Notification id (notify_id) is generated by notification daemon and
is valid only while daemon is running. If notification backend will
resend/reuse existing notification id (replace_id) after notification
daemon has been restarted it could replace wrong notification as same
id now can be used by different notification.
Previously, the documentation indicated that it was possible to call
g_tls_connection_handshake() after an initial handshake to trigger a
rehandshake, but only if TLS 1.2 or older is in use. However, there is
no documented way to ensure TLS 1.2 gets used. Nowadays, TLS 1.3 is used
by default.
I'm removing support for rehandshaking from glib-networking, as part of
a large refactoring where keeping rehandshakes would have entailed
significant additional complexity. So let's update the documentation to
indicate this is no longer ever supported. Applications should not
notice any difference.
Also, sync some previous handshake and rehandshake changes from
GTlsConnection to GDtlsConnection that were missed by mistake. I
try to remember to always update GDtlsConnection when touching
GTlsConnection documentation, but it's easy to forget.
We used XML to markup when we should have used our own brand of markdown
instead. This fixes the example being unreadable unless we trimmed the
XML away from it.
For the check "if (error != NULL)" to work as expected, the
create_server() (and create_server_full()) functions need to make
sure to return an error for all the possible failures, but this
might not always be the case.
Catch all the failures by testing for a non-NULL return value if there
was no error.
This shouldn't make any difference, because this code should only ever
be running in the main context that was thread-default at the time the
task was created, so it should already match the task's context. But
let's make sure, just in case.
They didn’t match the prototype generated by `gdbus-codegen`, which
meant that the FD list was being iterated incorrectly. Secondly, the
document ID list returned by the method was not NULL terminated, which
could lead to reading off the end of the list.
Somehow, neither of these bugs caused problems on Linux, but they did
cause problems on FreeBSD.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1983
Sadly, I forgot to update the documentation of
g_dtls_connection_handshake() last time I touched
g_tls_connection_handshake().
Let's also drop mention of STARTTLS, since that would use normal TLS,
not DTLS.
Reduce the number of iterations of things sent over a mock session bus
from different threads, to avoid the test spending quite so long
contested over the `gsignal.c` lock.
The test now takes about 10 seconds, according to `time`, rather than
around 100 or longer.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
By removing the cached global proxy in gdocumentportal.c, we can
re-enable the checks for proper shutdown of the session bus connection
in the dbus-appinfo.c test.
We can't use session_bus_down() in the test since gdocumentportal.c
holds a reference to the session bus connection, preventing it from
being finalised.
There are some GVfs locations (i.e. google-drive://, recent://), where
G_FILE_ATTRIBUTE_STANDARD_NAME is something tottaly different than
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME. Thus it would be nice to have
an easy way to show the display names. The only way currently to show
the display names is to use --attributes option, which is a bit
cumbersome. Let's add new --show-display-names option.
https://gitlab.gnome.org/GNOME/gvfs/issues/402
Those tests require Python, gobject-introspection and python-dbusmock
making them unsuitable to be run within the uninstalled test suite.
There are no restrictions of dependencies when it comes to installed
tests so use those to exercise GMemoryMonitor.
With debug enabled, g_dbus_connection_call_done() will throw a
g_warning() if the call failed (on purpose or not) while trying to the
serial of a non-existant reply.
(/builds/GNOME/glib/_build/gio/tests/gdbus-connection:26921): GLib-GIO-CRITICAL **: 10:10:16.311: g_dbus_message_get_reply_serial: assertion 'G_IS_DBUS_MESSAGE (message)' failed
This is a reimplementation of commit
4aba03562b from Will Thompson, but
conditional on the caller passing `--glib-min-version 2.64` to
`gdbus-codegen` to explicitly opt-in to the new behaviour.
From the commit message for that commit:
Previously, if a method was not annotated with org.gtk.GDBus.C.UnixFD
then the generated code would never contain GUnixFDList parameters, even
if the method has 'h' (file descriptor) parameters. However, in this
case, the generated code is essentially useless: the method cannot be
called or handled except in degenerate cases where the file descriptors
are missing or ignored.
Check the argument types for 'h', and if present, generate code as if
org.gtk.GDBus.C.UnixFD annotation were specified.
Includes a unit test too.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1726
This can be used by callers to opt-in to backwards-incompatible changes
to the behaviour or output of `gdbus-codegen` in future. This commit
doesn’t introduce any such changes, though.
Documentation and unit tests included.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1726
We got a complaint here that trashing via the
portal deletes the target of a symlink, not the
symlink itself. It turns out that following the
symlink already happens on the glib side.
https://github.com/flatpak/xdg-desktop-portal/issues/412
Skipped tests use "77" as the return value, so return 77 instead of 0
when the static-link.py test gets skipped because of a missing
environment variable.
If the fuse module is loaded but /dev/fuse doesn't exist, it's likely
that we're running in a rootless container, or a badly setup one, and we
won't be able to use fuse, so skip this test.
This happened on my local system using podman running as a normal user,
but this apparently works as expected in our CI[1].
[1]: https://gitlab.gnome.org/GNOME/glib/merge_requests/466
gtk-doc switched from DocBook to Markdown ages ago. There is no Markdown
equivalent for `<warning>`, so just drop it. It wasn’t adding anything
particularly valuable to the documentation.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1130
gtk-doc long since switched to Markdown, so we shouldn’t be emitting
DocBook `<link>` tags.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1130
Add a Python-based test wrapper for the `gdbus-codegen` executable,
similar to the existing tests for `glib-mkenums` and friends.
Add a few basic tests to begin with, but this doesn’t approach anywhere
near full coverage.
The next step is to move the existing Meson-based `gdbus-codegen` tests
from `gio/tests/meson.build` into the Python test suite.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1612
Previously, running `gdbus-codegen` with no arguments would exit
successfully with no output. While technically correct, that seems
unhelpful.
Require at least one interface file to be specified, so the user gets an
error message if they don’t specify any.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It’s not particularly useful to put the gdbus-codegen version or the
name of the input file into the output from `gdbus-codegen`, and it
makes the output less reproducible. Drop it.
Also clarify the licensing.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1612
If not doing this it might happen that the cancelled signal is emitted
between reaching a reference count of 0 and finalizing the GSource, at
which point part of the GSource is already freed and calling any GSource
functions is dangerous.
Instead do this from the dispose function. At this time the GSource is
not partially freed yet and calling any GSource API is safe as long as
we ensure that we have a strong reference to the GSource before calling
any GSource API.
_kqsub_free assumes the caller has called _kqsub_cancel before calling
it. It checks if both 'deps' and 'fd' have been freed and aborts when
the condition is not met. Since the only caller of _kqsub_free is
g_kqueue_file_monitor_finalize, which does call _kqsub_cancel before
calling _kqsub_free, it seems to be correct for _kqsub_free to assert
values of these two members there.
However, it is possible for _kqsub_cancel to return early without
freeing any resource _kqsub_free expects to be freed. When the kevent
call fails, _kqsub_cancel does not free anything and _kqsub_free aborts
with assertion failure. This is an unexpected behavior, and it can be
fixed by always freeing resources in _kqsub_cancel.
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/1935
"gio mount" doesn't print anything in case of success, however "gio mount -d"
prints "Mounted [id] at [mount_path]", which is inconsistent. It might probably
make sense for fstab volumes, but "gio mount -d" now support UUIDs which are
heavily used for daemon mounts and I think that it is not wise to print
"/run/user/$UID/gvfs" mount paths. The mount path can be still found over
"gio mount -l". Let's remove this message to make it more consistent.
"gio mount" only allows mounting volumes using device files, but not using
UUIDs. Volume monitors for various GVfs locations usually supports just UUIDs.
It would be handy to support them also for testing purposes (because
"g_file_mount_enclosing_volume()" does something else than "g_volume_mount()"
in case of shares provided by GOA volume monitor for example). Let's update
"-d" option to support also UUIDs.
https://gitlab.gnome.org/GNOME/gvfs/issues/251
It’s possible that one VFS operation will happen from a worker thread at
the same time as another is happening from the main thread, in which
case the static buffer which getpwnam() uses will be overwritten.
There’s a chance this will corrupt the results that one of the threads
receives.
Fix that by using the thread-safe getpwnam_r() version, via the new
g_unix_get_passwd_entry() function.
Fix the indentation of the surrounding block while we’re there.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1687
Those tests seem to regularly fail because a timeout (which we're
measuring outside the function that times out) is too long, which can
happen when the system is busy.
Don't run those tests unless "thorough" tests are requested. This
disables those tests by default.
Bail out! GLib-GIO:ERROR:../gio/tests/socket.c:1167:test_timed_wait: assertion failed (poll_duration < 112000): (114254 < 112000)
Bail out! GLib-GIO:ERROR:../gio/tests/cancellable.c:167:on_mock_operation_ready: assertion failed (error == (g-io-error-quark, 19)): error is NULL
Now we're returning the file type again, we need to mask it out to
compare with the mode. We can also check that the statbuf said the file
is a regular file.
Related: #1934
This reverts commit bfdc5fc4fc.
This changes the semantics of G_FILE_ATTRIBUTE_ID_UNIX_MODE, and we've
already found one user of the previous semantics (ostree).
Closes#1934
This function has numerous undocumented limitations. In particular, it
is not possible to ensure this function actually does anything. Document
these problems.
For many years after SSL 3.0 support was removed, we used this function
to indicate that we should perform protocol version fallback to the
lowest-supported protocol version, to workaround protocol version
intolerance. Nowadays this is no longer needed, and support has been
removed from glib-networking, so update the documentation.
GTlsConnection:rehandshake-mode has been deprecated since 2.60 using
the G_PARAM_DEPRECATED flag, but I forgot to add the right annotation to
the documentation. Oops.
The associated getter/setter functions were both deprecated properly.
This is the analogue of commit 7c4e6e9fbe, but applied to the
`GDBusMessage` parser, which does its own top-level parsing of the
variant format in D-Bus messages.
Previously, this code allowed arbitrary recursion of variant containers,
which could lead to a stack overflow. Now, that recursion is limited to
64 levels, as per the D-Bus specification:
https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature
This includes a new unit test.
oss-fuzz#14870
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Tools like this should be configurable in a cross or native file. In
particular, if we are cross-compiling (with an executable wrapper like
qemu-arm), the build system ld is not necessarily able to manipulate
host system objects.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Otherwise we'll never test the EXTERNAL-only mode, because that relies
on testing the private macros
G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED and
G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED.
Fixes: 9f962ebe "Add a test for GDBusServer authentication"
Signed-off-by: Simon McVittie <smcv@collabora.com>
This bypasses any issues we might have with containers where IPv6 is
returned by name resolution (particularly since GNOME/glib!616) but
doesn't necessarily actually work.
This comes at a minor test-coverage cost: we don't test GDBusServer's
default behaviour when told to listen on "tcp:" or "nonce-tcp:", and
on systems where IPv6 is available, we don't test it. If we want to
do those, we should perhaps do them in separate tests, and disable
those tests when binding to ::1 doesn't work.
Mitigates: GNOME/glib#1912
Signed-off-by: Simon McVittie <smcv@collabora.com>
Whitelist a safe set of characters for use in header guards instead of
maintaining a (growing) blacklist.
The whitelist is intentionally short since reading up on all
peculiarities of the C and C++ standard for identifiers is not my idea
of fun. :)
Fixes#1379
g_assert() is compiled out by `G_DISABLE_ASSERT` and doesn’t give such
useful messages on failure.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
No need to clear it to NULL before every time it’s used, since we assert
that it’s never set.
This introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This avoids failure to listen on the given address on non-Linux Unix
kernels, where abstract sockets do not exist and so unix:tmpdir is
equivalent to unix:dir.
To avoid bugs like this one recurring, run most of these tests using
the unix:dir address type, where Linux is equivalent to other Unix
kernels; just do one unix:tmpdir test, to check that we still
interoperate with libdbus when using abstract sockets on Linux.
Resolves: GNOME/glib#1920
Fixes: 9f962ebe "Add a test for GDBusServer authentication"
Signed-off-by: Simon McVittie <smcv@collabora.com>
Previously, we used unix:tmpdir, except in tests that verify that a
particular address type works (notably unix:dir). Now we use unix:dir
most of the time, and unix:tmpdir gets its own test instead.
This helps to ensure that the tests continue to work on non-Linux Unix
kernels, where abstract sockets do not exist and so unix:tmpdir is
equivalent to unix:dir, even in the common case where the developer has
only tried the test on Linux.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Otherwise, since GNOME/glib!1193, the listening socket won't be deleted,
and if we are not using abstract sockets (for example on *BSD), g_rmdir
will fail with ENOTEMPTY.
Fixes: 8e32b8e8 "gdbusserver: Delete socket and nonce file when stopping server"
Resolves: GNOME/glib#1921
Signed-off-by: Simon McVittie <smcv@collabora.com>
The `on_run()` function could be executed in any worker thread from the
`GThreadedSocketListener`, but didn’t previously hold a strong reference
to the `GDBusServer`, which meant the server could be finalised in
another thread while `on_run()` was still running.
This was not ideal.
Hold a strong reference to the `GDBusServer` while the socket listener
is listening, i.e. between every paired call to `g_dbus_server_start()`
and `g_dbus_server_stop()`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1318
Rather than when finalising it. They should be automatically recreated
if the server is re-started.
This is important for ensuring that all externally visible behaviour of
the `GDBusServer` is synchronised with calls to
g_dbus_server_{start,stop}(). Finalisation of the server object could
happen an arbitrarily long time after g_dbus_server_stop() is called.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1318
So that the tests all end up using separate `.dbus-keyring` directories,
and hence not racing to create and acquire lock files, use
`G_TEST_OPTION_ISOLATE_DIRS` to ensure they all run in separate
disposable directories.
This has the added benefit of meaning they don’t touch the developer’s
actual `$HOME` directory.
This reduces the false-failure rate of `gdbus-peer` by a factor of 9 for
me on my local machine.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1912
There’s actually no need for them to be global or reused between unit
tests, so move them inside the test functions.
This is one step towards eliminating shared state between the unit
tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1912
If the directory is overridden, for example when running tests, the
parent directory of `.dbus-keyrings` (i.e. the fake `$HOME` directory)
might not exist. Create it automatically.
This should realistically not have an effect on non-test code.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1912
These can be hit in the tests (if multiple tests run in parallel are
racing for `~/.dbus-keyrings/org_gtk_gdbus_general.lock` for a prolonged
period) and will cause spurious test failures due to the use of
`G_DEBUG=fatal-warnings`.
Instead, allow the error messages to be inspected programmatically.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1912
In particular, if libbdus is available, we test interoperability with
a libdbus client: see GNOME/glib#1831. Because that issue describes a
race condition, we do each test repeatedly to try to hit the failing
case.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Conceptually, a D-Bus server is really trying to determine the credentials
of (the process that initiated) a connection, not the credentials that
the process had when it sent a particular message. Ideally, it does
this with a getsockopt()-style API that queries the credentials of the
connection's initiator without requiring any particular cooperation from
that process, avoiding a class of possible failures.
The leading '\0' in the D-Bus protocol is primarily a workaround
for platforms where the message-based credentials-passing API is
strictly better than the getsockopt()-style API (for example, on
FreeBSD, SCM_CREDS includes a process ID but getpeereid() does not),
or where the getsockopt()-style API does not exist at all. As a result
libdbus, the reference implementation of D-Bus, does not implement
Linux SCM_CREDENTIALS at all - it has no reason to do so, because the
SO_PEERCRED socket option is equally informative.
This change makes GDBusServer on Linux more closely match the behaviour
of libdbus.
In particular, GNOME/glib#1831 indicates that when a libdbus client
connects to a GDBus server, recvmsg() sometimes yields a SCM_CREDENTIALS
message with cmsg_data={pid=0, uid=65534, gid=65534}. I think this is
most likely a race condition in the early steps to connect:
client server
connect
accept
send '\0' <- race -> set SO_PASSCRED = 1
receive '\0'
If the server wins the race:
client server
connect
accept
set SO_PASSCRED = 1
send '\0'
receive '\0'
then everything is fine. However, if the client wins the race:
client server
connect
accept
send '\0'
set SO_PASSCRED = 1
receive '\0'
then the kernel does not record credentials for the message containing
'\0' (because SO_PASSCRED was 0 at the time). However, by the time the
server receives the message, the kernel knows that credentials are
desired. I would have expected the kernel to omit the credentials header
in this case, but it seems that instead, it synthesizes a credentials
structure with a dummy process ID 0, a dummy uid derived from
/proc/sys/kernel/overflowuid and a dummy gid derived from
/proc/sys/kernel/overflowgid.
In an unconfigured GDBusServer, hitting this race condition results in
falling back to DBUS_COOKIE_SHA1 authentication, which in practice usually
succeeds in authenticating the peer's uid. However, we encourage AF_UNIX
servers on Unix platforms to allow only EXTERNAL authentication as a
security-hardening measure, because DBUS_COOKIE_SHA1 relies on a series
of assumptions including a cryptographically strong PRNG and a shared
home directory with no write access by others, which are not necessarily
true for all operating systems and users. EXTERNAL authentication will
fail if the server cannot determine the client's credentials.
In particular, this caused a regression when CVE-2019-14822 was fixed
in ibus, which appears to be resolved by this commit. Qt clients
(which use libdbus) intermittently fail to connect to an ibus server
(which uses GDBusServer), because ibus no longer allows DBUS_COOKIE_SHA1
authentication or non-matching uids.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: https://gitlab.gnome.org/GNOME/glib/issues/1831
On Linux, if getsockopt SO_PEERCRED is used on a TCP socket, one
might expect it to fail with an appropriate error like ENOTSUP or
EPROTONOSUPPORT. However, it appears that in fact it succeeds, but
yields a credentials structure with pid 0, uid -1 and gid -1. These
are not real process, user and group IDs that can be allocated to a
real process (pid 0 needs to be reserved to give kill(0) its documented
special semantics, and similarly uid and gid -1 need to be reserved for
setresuid() and setresgid()) so it is not meaningful to signal them to
high-level API users.
An API user with Linux-specific knowledge can still inspect these fields
via g_credentials_get_native() if desired.
Similarly, if SO_PASSCRED is used to receive a SCM_CREDENTIALS message
on a receiving Unix socket, but the sending socket had not enabled
SO_PASSCRED at the time that the message was sent, it is possible
for it to succeed but yield a credentials structure with pid 0, uid
/proc/sys/kernel/overflowuid and gid /proc/sys/kernel/overflowgid. Even
if we were to read those pseudo-files, we cannot distinguish between
the overflow IDs and a real process that legitimately has the same IDs
(typically they are set to 'nobody' and 'nogroup', which can be used
by a real process), so we detect this situation by noticing that
pid == 0, and to save syscalls we do not read the overflow IDs from
/proc at all.
This results in a small API change: g_credentials_is_same_user() now
returns FALSE if we compare two credentials structures that are both
invalid. This seems like reasonable, conservative behaviour: if we cannot
prove that they are the same user, we should assume they are not.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Otherwise we’ll end up using the host’s `objcopy`, which will output
object files in the wrong format.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1916
This reverts commit 4aba03562b, preserving
the new tests but adjusting them to assert that the old behaviour is
restored.
As expected, there were a few projects which broke because of this.
Unfortunately, in one case the breakage crosses a project boundary:
sysprof ships D-Bus introspection XML, which is consumed by mutter and
passed through gdbus-codegen.
Since sysprof cannot add this annotation without breaking its existing
users, a warning is also not appropriate.
https://gitlab.gnome.org/GNOME/jhbuild/issues/41https://gitlab.gnome.org/GNOME/sysprof/issues/17https://gitlab.gnome.org/GNOME/glib/issues/1726
Previously we were keeping a pointer to the `GFileMonitor` in a
`GFileMonitorSource` instance, but since we weren’t keeping a strong
reference, that `GFileMonitor` instance could be finalised from another
thread at any point while the source was referring to it. Not good.
Use a weak reference, and upgrade it to a strong reference whenever the
`GFileMonitorSource` is referring to the file monitor.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1903
It’s not enough to unref the monitor, since the GLib worker thread might
still hold a reference to it.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1903
`DesktopFileDir` pointers are passed around between threads: they are
initially created on the main thread, but a pointer to them is passed to
the GLib worker thread in the file monitor callback
(`desktop_file_dir_changed()`).
Accordingly, the `DesktopFileDir` objects either have to be
(1) immutable;
(2) reference counted; or
(3) synchronised between the two threads
to avoid one of them being used by one thread after being freed on
another. Option (1) changed with commit 99bc33b6 and is no longer an
option. Option (3) would mean blocking the main thread on the worker
thread, which would be hard to achieve and is against the point of
having a worker thread. So that leaves option (2), which is implemented
here.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1903
When the _g_dbus_worker_flush_sync() schedules the 'data' and releases
the worker->write_lock, it is possible for the GDBus worker thread thread
to finish the D-Bus call and acquire the worker->write_lock before
the _g_dbus_worker_flush_sync() re-acquires it in the if (data != NULL) body.
When that happens, the ostream_flush_cb() increases the worker->write_num_messages_flushed
and then releases the worker->write_lock. The write lock is reacquired by
the _g_dbus_worker_flush_sync(), which sees that the while condition is satisfied,
thus it doesn't enter the loop body and immediately clears the data members and
frees the data structure itself. The ostream_flush_cb() is still ongoing, possibly
inside flush_data_list_complete(), where it accesses the FlushData, which can be
in any stage of being freed.
Instead, add an explicit boolean flag indicating when the flush is truly finished.
Closes#1896
`-1` isn’t a valid member of the enum, so cast to `int` first. This
fixes a compiler warning on Android.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Mounts are currently completed only if the prefix looks like scheme,
however, this doesn't work well if the mounts have also path component.
Let's always include them to fix this issue. The mounts are cached by the
volume monitors, so it should not significantly affect the performance.
Currently, "gio mount google-drive<tab>" isn't completed even though
that volume exists for google-drive://oholy@redhat.com/. Let's use
"gio mount -li" output to complete also activation roots of volumes.
Currently, "gio list file:///h<tab>" doesn't complete "file:///home"
because the result of "dirname file:///h" is not "file:///" but "file:/",
which breaks the consequent logic. Let's subtract basename from the
path in order to workaround this issue.
Fixes build failure:
../gio/gunixmounts.c: In function ‘_g_get_unix_mounts’:
../gio/gunixmounts.c:742:53: error: ‘struct mnttab’ has no member named ‘mnt_opts’; did you mean ‘mnt_mntopts’?
742 | mntent.mnt_opts,
| ^~~~~~~~
| mnt_mntopts
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
g_date_time_add_seconds() and g_date_time_add_full() use floating-point
seconds, which can result in the value varying slightly from what's
actually on disk. This causes intermittent test failures in
gio/tests/g-file-info.c on Debian i386, where we set a file's mtime
to be 50µs later, then read it back and sometimes find that it is only
49µs later than the previous value.
I've only seen this happen on i386, which means it might be to do with
different floating-point rounding when a value is stored in the 80-bit
legacy floating point registers rather than in double precision.
g_date_time_add() takes a GTimeSpan, which is in microseconds;
conveniently, that's exactly what we get from the GFileInfo.
Bug-Debian: https://bugs.debian.org/941547
Signed-off-by: Simon McVittie <smcv@collabora.com>
If we're cross-compiling, the installed-tests are useful even if we
can't run them on the build machine: we can copy them to the host
machine (possibly via a distro package like Debian's libglib2.0-tests)
and run them there.
While I'm changing the build-tests condition anyway, deduplicate it.
Based on a patch by Helmut Grohne.
Bug-Debian: https://bugs.debian.org/941509
Signed-off-by: Simon McVittie <smcv@collabora.com>
Skip it on systems which don’t support it, rather than compiling it out.
That gives us more information from test runs about which tests are
being run on which architectures.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
As with the previous commit, `st_mode` contains both the file type
(regular file, directory, symlink, special, etc.) and the file mode. For
`G_FILE_ATTRIBUTE_ID_UNIX_MODE`, we only want the file mode — so mask
`st_mode` with `~S_IFMT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
chmod() technically only accepts file modes, not the file type and mode
as returned by stat(). Filter by `S_IFMT` to avoid sending the file
type (regular file, directory, symbolic link, etc.).
In practice, chmod() ignores anything except the file mode, but we might
as well comply with the specification.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
`GFile` always checks whether these vfuncs are `NULL` before calling
them, so document that it’s safe for implementations of `GFile` to not
implement them.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The caller assumes that an unimplemented vfunc means that copying is
unsupported (and falls back to its internal copy implementation), so
there’s no point in implementing the vfunc just to unconditionally
return `G_IO_ERROR_NOT_SUPPORTED`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Rather than defining a vfunc which only ever returns
`G_IO_ERROR_NOT_SUPPORTED`, just don’t define the vfunc at all. The
caller in `GFile` interprets this as symlinks not being supported — so
we get the same behaviour, but without spending a vfunc call on it.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The string is already translated in `GLocalFile`, so this doesn’t
introduce a new translatable string.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This sets the `G_FILE_COPY_DEFAULT_PERMS` flag on the operation,
creating the copied file with default permissions rather than the same
permissions as the source file.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #174
If a copy operation is started with `G_FILE_COPY_TARGET_DEFAULT_PERMS`,
don’t create the destination file as private. Instead, create it with
the process’ current umask (i.e. ‘default permissions’).
This is a partial re-work of commit d8f8f4d637, with
input from Ondrej Holy.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #174
The actual parameter name in g_file_attribute_matcher_new()
attributes, so change the param reference to match. This way,
doc tools can create a proper link.
g_file_info_set_modification_time() and
g_file_info_set_modification_date_time() set the
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attribute in addition to
G_FILE_ATTRIBUTE_TIME_MODIFIED, so microsecond precision is available
when provided by the caller, so mention both attributes in the docs.
Currently, there is no quick way to find whether and element is already
part of a list store, except for manually writing a for-loop and calling
`g_list_model_get_item()` and breaking when you find the item.
This is mostly just a small API addition to support this use case.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/1011
When compiling GLib with `-Wsign-conversion`, we get various warnings
about the atomic calls. A lot of these were fixed by
3ad375a629, but some remain. Fix them by
adding appropriate casts at the call sites.
Note that `g_atomic_int_{and,or,xor}()` actually all operate on `guint`s
rather than `gint`s (which is what the rest of the `g_atomic_int_*()`
functions operate on). I can’t find any written reasoning for this, but
assume that it’s because signedness is irrelevant when you’re using an
integer as a bit field. It’s unfortunate that they’re named a
`g_atomic_int_*()` rather than `g_atomic_uint_*()` functions.
Tested by compiling GLib as:
```
CFLAGS=-Wsign-conversion jhbuild make -ac |& grep atomic
```
I’m not going to add `-Wsign-conversion` to the set of default warnings
for building GLib, because it mostly produces false positives throughout
the rest of GLib.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1565
They provide more detailed failure messages, and aren’t compiled out
when building with `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When future porting deprecated code to use
g_file_info_get_modification_date_time() we risk a number of breakages
because the current implementation also requires the additional use of
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC. This handles that situation gracefully
and returns a GDateTime with less precision.
Applications that want the additional precision, are already using the
additional attribute.
(Minor tweaks by Philip Withnall.)
This should make the code a bit easier to reason about, and squash some
static analysis warnings.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
The macros for the probes confuse the static analyser, and are often
called with arguments which the analyser things shouldn’t be used any
more (for example, the address of a block of memory which has just been
freed).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
These squash various warnings from `scan-build`. None of them are
legitimate bugs, but some of them do improve code readability a bit.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
Previously, if a method was not annotated with org.gtk.GDBus.C.UnixFD
then the generated code would never contain GUnixFDList parameters, even
if the method has 'h' (file descriptor) parameters. However, in this
case, the generated code is essentially useless: the method cannot be
called or handled except in degenerate cases where the file descriptors
are missing or ignored.
Check the argument types for 'h', and if present, generate code as if
org.gtk.GDBus.C.UnixFD annotation were specified.
This change will break any existing code which refers to the (useless)
wrappers for such methods. The workaround for such code is to add the
org.gtk.GDBus.C.UnixFD annotation, which will cause the same generated
code to be emitted before and after this change.
If this is found to cause widespread problems, we can explore a
different approach (perhaps emitting a warning from the code generator,
or annotating the symbols as deprecated).
https://gitlab.gnome.org/GNOME/glib/issues/1726
Instead of letting each directory to find its way to link with libdl,
it is easier to put the check in the top level, so its result can be
used by all directories.
It is a follow-up of https://gitlab.gnome.org/GNOME/glib/merge_requests/810.
The header file was installed when building using autotools, but was
inadvertently omitted in the meson targets.
Luckily, ABI is not impacted, since gnativesocketaddress.c was always
compiled and linked into libgio.
Fixes: #1854
The gobject introspection comments have a reference to an incorrect
class: they have, as 'self', the GSubprocess class instead of
GSubprocessLauncher.
This patch fixes this.
g_settings_backend_watch() uses a weak notify for keeping track of
the target. There's an explanation why this is supposed to be safe but
that explanation is wrong.
The following could happen before:
1. We have the target stored in the watch list
2. The last reference to the target is dropped in thread A and we end up
in g_settings_backend_watch_weak_notify() right before the mutex
3. g_settings_backend_dispatch_signal() is called from another thread B
and gets the mutex before 2.
4. g_weak_ref_init() is called on the target from thread B, which at
this point has a reference count of exactly one (see g_object_unref()
where it calls the weak notifies)
5. Thread A continues at 3. and drops the last reference and destroys
the object. Now the GWeakRef from 4. points to a destroyed object. Note
that GWeakRefs would be cleared before the weak notifies are called
6. At some later point another thread g_weak_ref_get() is called by
g_settings_backend_invoke_closure() and accesses an already destroyed
object with refcount 0 from the GWeakRef created in 4. by thread B (or
worse, already freed memory that was reused).
Solve this by actually storing a GWeakRef of the target in the watch
list and only access the target behind it via the GWeakRef API, and then
pass a strong reference to the notification dispatch code.
The weak notify is only used to remove the (potentially with empty
GWeakRef) target from the list of watches and the only place that
compares the target by pointer instead of going through the GWeakRef
API.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/1870
If we fail to create a GWinhttpFile for a URI (for example, because it’s
an invalid URI or is badly encoded), don’t just return NULL. Instead,
fall back to the wrapped VFS which might be able to handle it instead.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1819
It can return NULL if the URI was badly encoded or couldn’t be handled
by Windows’ API.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1819
It cannot return a NULL value, as none of its callers have error
handlng. Add an assertion to check the values returned by the VFS
implementations.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1819
This fixes use of `GIO_USE_VOLUME_MONITOR=help`, and simplifies the
code. The reason this wasn’t used already seems to just be because it
was missed when `_g_io_module_get_default_type()` was introduced in
2013. The previous `get_default_native_class()` code in
`gunionvolumemonitor.c` was introduced in 2007.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #1881
Deletes the skip annotation from g_cancellable_source_new(). This was
originally added because GSource wasn't introspectable, but this is no
longer an issue as G_TYPE_SOURCE was added in 2.30.
Fixes: #1877
When resetting a key in the delayed settings backend,
g_settings_backend_changed() was not called to notify the backend of
the change.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1309
This fix build error for projects that use gnome.compile_resources()
when glib is built as a subproject and not installed on the build
machine.
Note that this is not working for cross compilation cases, because it
would require to compile everything twice (for host and build machines).
A better solution would be to rewrite those tools in python. See #1859.
They use the deprecated GTimeVal type, which is not year 2038 safe, so
have to be deprecated.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
These are alternatives to g_file_info_{get,set}_modification_time(),
which will soon be deprecated due to using the deprecated GTimeVal
type, which is not year 2038 safe.
The new APIs take a GDateTime instead.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
The event source used to handle inactivity_timeout doesn't hold a
reference on the application. Therefore, it is possible for callback
function of the event source to run after the application has been
freed, leading to use-after-free problem. To avoid the problem, we
should remove the event source before the application is freed.
This should fix SIGBUS crash of gio/tests/gapplication on FreeBSD.
https://gitlab.gnome.org/GNOME/glib/issues/1846#note_566550
These are here to prevent linker errors, since `gcontenttype.[ch]`
aren’t compiled on Windows or macOS.
The implementations are stubs to be filled out by someone who knows each
platform, at some point in the future.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1791
We're using the `install` argument for configure_file() all over the
place.
The support for an `install` argument for configure_file() was added in
Meson 0.50, but we haven't bumped the minimum version of Meson we
require, yet; which means we're getting compatibility warnings when
using recent versions of Meson, and undefined behaviour when using older
versions.
The configure_file() object defaults to `install: false`, unless an
install directory is used. This means that all instances of an `install`
argument with an explicit `true` or `false` value can be removed,
whereas all instances of `install` with a value determined from a
configuration option must be turned into an explicit conditional.
The comment previously said ‘never %NULL’, but it wasn’t clear whether
this meant `(not nullable)` or `(not optional)`. From looking at the
code, it means `(not optional)`.
Clarify things by removing the prose. The annotations themselves should
be clear and explicit enough.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #1836