Fix a regression from commit abddb42d14, where it could pass `NULL` to
`g_task_get_cancellable()`, triggering a critical warning. This could
happen because the lifetime of `data->task` is not as long as the
lifetime of the `ConnectionAttempt`, but the code assumed it was.
Fix the problem by keeping a strong ref to that `GCancellable` around
until the `ConnectionAttempt` is finished being destroyed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2687
It doesn't make sense for a proxy resolver to return NULL without an
error on the first call. Whereas a DNS resolver would do this to
indicate that a query completed successfully but found no results, a
proxy resolver should return "direct://" instead. Therefore, if we are
going to return NULL, we ought to have an error as well. Let's make sure
this actually happens by adding some fallback errors just in case
GProxyResolver feeds us weird results.
Additionally, we should not return any errors except
G_IO_ERROR_CANCELLED after the very first iteration. This is an API
contract of GSocketAddressEnumerator. Let's add some checks to ensure
this.
Note that we have inadequate test coverage for GProxyAddressEnumerator.
It's tested here only via GSocketClient. We could do a bit better by
testing it directly as well. For example, I've added tests to see what
happens when GProxyResolver returns both a valid and an invalid URI, but
it's not so interesting here because GSocketClient always uses the valid
result and ignores the error from GProxyAddressEnumerator.
(Backport to 2.72: Dropped new translatable strings in error messages to
avoid additional translation work on a stable branch. The error messages
are unlikely to be seen by users.)
Fixes#2597
`GSocketClient` chains its internal `GCancellable` objects to ones
provided by the caller in two places using `g_cancellable_connect()`.
However, it never calls `g_cancellable_disconnect()`, instead relying
(incorrectly) on the `GCancellable` provided by the caller being
short-lived.
In the (valid) situation where a caller reuses one `GCancellable` for
multiple socket client calls, or for calls across multiple socket
clients, this will cause the internal `GCancellable` objects from those
`GSocketClient`s to accumulate, with one reference left each (which is
the reference from the `g_cancellable_connect()` closure).
These `GCancellable` instances aren’t technically leaked, as they will
all be freed when the caller’s `GCancellable` is disposed, but they are
no longer useful and there is no bound on the number of them which will
hang around.
For a program doing a lot of socket operations, this still-reachable
memory usage can become significant.
Fix the problem by adding paired `g_cancellable_disconnect()` calls.
It’s not possible to add a unit test as we can’t measure still-reachable
memory growth before the end of a unit test when everything has to be
freed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2670
This re-applies a chunk from commit e63262d49d40a36060 which was
accidentally lost when upstreaming the commit to xdgmime (as
https://gitlab.freedesktop.org/xdg/xdgmime/-/merge_requests/10).
The upstreamed commit was then re-backported to GLib as a1bfe899abe,
without the missing chunk.
The missing chunk is potentially causing incorrect content type results
for `file://` URIs when used from webkitgtk.
Thanks to Stephen Jung and Michael Catanzaro for investigating.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2639
This test is opportunistic in that it’s not possible to detect whether
the race condition has been hit (other than by hitting a deadlock).
So the only approach we can take for testing is to loop over the code
which has previously been known to cause a deadlock a number of times.
The number of repetitions is chosen from running the test with the
deadlock fix reverted.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1941
This should prevent unbounded growth of the `event_queue` in the
unlikely case that the `GSource` is removed from its `GMainContext` and
destroyed separately from the `GFileMonitor`.
I’m not sure if that can currently happen, but it could with future
refactoring, so it’s best to address the possibility now while we’re
thinking about this bit of code.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1941
Taking a reference to the GFileMonitor when handling events may cause
object destruction from th worker thread that calls the function. This
condition happens if the surrounding code drops the otherwise last
reference ot the GFileMonitor. The series of events causes destruction
from an unrelated worker thread and also triggers g_file_monitor_cancel
to be called from g_file_monitor_source_handle_event.
For the inotify backend, this results in a deadlock as cancellation
needs to take a lock that protects data structures from being modified
while events are dispatched.
One alternative to this approach might be to add an RCU (release, copy,
update) approach to the lists contained in the wd_dir_hash and
wd_file_hash hash tables.
Fixes: #1941
An example stack trace of this happening is:
Thread 2 (Thread 0x7fea68b1d640 (LWP 260961) "gmain"):
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1 0x00007fea692215dc in g_mutex_lock_slowpath (mutex=mutex@entry=0x7fea6911e148 <g.inotify_lock_lock>) at ../glib/gthread-posix.c:1493
#2 0x00007fea69222062 in g_mutex_lock (mutex=mutex@entry=0x7fea6911e148 <g.inotify_lock_lock>) at ../glib/gthread-posix.c:1517
#3 0x00007fea6908025a in _ih_sub_cancel (sub=0x1492620) at ../gio/inotify/inotify-helper.c:131
#4 0x00007fea6907f9da in g_inotify_file_monitor_cancel (monitor=0x14a3550) at ../gio/inotify/ginotifyfilemonitor.c:75
#5 0x00007fea68fae959 in g_file_monitor_cancel (monitor=0x14a3550) at ../gio/gfilemonitor.c:241
#6 0x00007fea68fae9dc in g_file_monitor_dispose (object=0x14a3550) at ../gio/gfilemonitor.c:123
#7 0x00007fea69139341 in g_object_unref (_object=<optimized out>) at ../gobject/gobject.c:3636
#8 g_object_unref (_object=0x14a3550) at ../gobject/gobject.c:3553
#9 0x00007fea6907507a in g_file_monitor_source_handle_event (fms=0x14c3560, event_type=<optimized out>, child=0x7fea64001460 "spawned-1", rename_to=rename_to@entry=0x0, other=other@entry=0x0, event_time=<optimized out>) at ../gio/glocalfilemonitor.c:457
#10 0x00007fea6907fe0e in ih_event_callback (event=0x7fea64001420, sub=0x1492620, file_event=<optimized out>) at ../gio/inotify/inotify-helper.c:218
#11 0x00007fea6908075c in ip_event_dispatch (dir_list=dir_list@entry=0x14c14c0, file_list=0x0, event=event@entry=0x7fea64001420) at ../gio/inotify/inotify-path.c:493
#12 0x00007fea6908094e in ip_event_dispatch (event=0x7fea64001420, file_list=<optimized out>, dir_list=0x14c14c0) at ../gio/inotify/inotify-path.c:448
#13 ip_event_callback (event=0x7fea64001420) at ../gio/inotify/inotify-path.c:548
#14 ip_event_callback (event=0x7fea64001420) at ../gio/inotify/inotify-path.c:530
#15 0x00007fea69081391 in ik_source_dispatch (source=0x14a2bf0, func=0x7fea69080890 <ip_event_callback>, user_data=<optimized out>) at ../gio/inotify/inotify-kernel.c:327
#16 0x00007fea691d0824 in g_main_dispatch (context=0x14a2cc0) at ../glib/gmain.c:3417
#17 g_main_context_dispatch (context=0x14a2cc0) at ../glib/gmain.c:4135
#18 0x00007fea691d0b88 in g_main_context_iterate (context=context@entry=0x14a2cc0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/gmain.c:4211
#19 0x00007fea691d0c2f in g_main_context_iteration (context=0x14a2cc0, may_block=may_block@entry=1) at ../glib/gmain.c:4276
#20 0x00007fea691d0c81 in glib_worker_main (data=<optimized out>) at ../glib/gmain.c:6176
#21 0x00007fea691f9c2d in g_thread_proxy (data=0x1487cc0) at ../glib/gthread.c:827
#22 0x00007fea68d93b1a in start_thread (arg=<optimized out>) at pthread_create.c:443
#23 0x00007fea68e18650 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
As per meson spec, returncode() produces unspecified data if
compiled() == false. Check compiled() first to avoid relying
upon unspecified data.
In addition, muon -- an implemetation of meson written in C goes
further and forbids returning unspecified data. This is a good
decision, but also makes it harder to support applications which
wrongly use meson API. Therefore, application needs to be fixed.
`path` was used in building the error message after it had been freed.
Spotted by scan-build.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1767
Tested using:
```sh
touch ~/foo
gio set ~/foo -t bytestring user::test "\x00\x00"
```
(it doesn’t matter that this fails; the bytestring is still decoded)
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1474407
When I enabled unix socketpair test on win32, I left the existing
g_close(fds[1]), but _g_win32_socketpair() returns native sockets
descriptors that must be closed with closesocket() on win32.
Let GSocket handle the socket pair cleanup.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The pipe must be closed, or the child PID watch doesn't get triggered.
We should remove the message callback source on EOF, as EOF during main
loop run will reach a bad assert in the callback.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
...for certain Windows locales, since the formats accepted for
g_date_set_parse() will vary depending on the current system locale. For
instance, g_date_set_parse(gdate, "dd/mm/yy") is accepted on locales such
as zh-HK (Chinese (Hong Kong SAR)) but is rejected on zh-TW (Chinese
(Taiwan)).
One can tell from the "date format" settings in the Windows system
control panel whether there is a "dd/MM/YYYY" or "dd/MM/YY" option from the
drop-down list of date formats to display for the locale, which will indicate
whether g_date_set_parse(gdate, "dd/mm/yy") is accepted, which is true for
zh-HK but is not true for zh-TW.
If g_date_set_parse(gdate, "dd/mm/yy") is not accepted, try again with
g_date_set_parse(gdate, "yy/mm/dd") thereafter for the 2-digit-year tests.