In my experience, it isn't actually useful to have the program
name as part of the thread name (we don't do that for other threads
that we create: pool-spawner, gmain, gdbus, ...) and the size limit
of 16 means that there really isn't enough space for it.
But what is somewhat useful is to have different threads have different
names, so number the pool threads: pool-0, pool-1, ...
`g_setenv()` is unsafe to use after any other threads have started,
which might have happened once GLib is initialised.
Avoid that problem by using `g_test_trap_subprocess_with_envp()` to
launch the existing subprocesses with the desired environment. This API
was added after these tests were written, but it’s a perfect fit for
them.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
systemd 257 will now set `DEBUG_INVOCATION=1` in the execution context
of services which need to be debugged — for example if they’ve failed
and been restarted (and `RestartMode=debug`).
If we handle `DEBUG_INVOCATION=1` as being equivalent to
`G_MESSAGES_DEBUG=all`, then any processes using GLib’s default log
writer function (or `g_log_writer_default_would_drop()`) automatically
gains support for this feature.
See https://mastodon.social/@pid_eins/113548825942383777
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The default value for max_unused_threads has been 2 since 2012.
Core counts have gone up since then, and nowadays, it would be
much better to keep more of the threads alive for a little while.
This commit bumps the max_unused_threads default value to 8.
Fixes: #3545
Previously `gi_object_info_find_signal()` used `gi_object_info_get_signal()`
to retrieve the *i*th signal and compare its name to the desired name.
However, `gi_object_info_get_signal()` returns an allocated object.
If the names were not matching, the allocated object was simply dropped,
and this resulted in a lot of unnecessary allocations compared to the
desired number of allocations, which is one.
To avoid much of the overhead pertaining to the creation of these allocated
`GISignalInfo` objects, introduce a new function that inspects the signal
blobs directly and returns an allocated `GISignalInfo` object just for the
matching signal. The function is largely a copy-and-paste of `gi_base_info_find_vfunc()`,
which does the same thing, only for virtual functions.
See https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/504
This fixes cases where calling `g_uri_to_string()` immediately after a
successful call to `g_uri_parse()` would cause an assertion failure for
URIs like `data:/.//` or `data:.///`.
These appear to be valid URIs. Their paths are normalised to `//` during
parsing as a result of the `remove_dot_segments()` algorithm. This then
falls foul of the restriction from
https://datatracker.ietf.org/doc/html/rfc3986#section-3 that
> When authority is not present, the path cannot begin with two slash
> characters ("//").
This is already encoded in an assertion at the top of
`g_uri_join_internal()`.
The approach of prefixing the path with `/.` should be harmless: it
guarantees the path starts with `/`, prevents `//` being a prefix, and
should always be removed by `remove_dot_segments()` when re-parsing the
URI. It’s the same approach as taken in the WhatWG URL spec for a
similar (but different) situation:
https://url.spec.whatwg.org/#url-serializing (see step 3).
See also: https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/415?commit_id=79cfd65c9bd8024cd45dd725c284766329873709
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
In 1e3b010 the behaviour of `g_bytes_new (NULL, 0)` was changed; before the
`g_bytes_get_data()` would return NULL as expected, but now it returns a pointer
outside the single GBytes allocation.
This breaks the fwupd self tests as we use a GBytes of NULL to signify that
the emulation data exists, but it has no content.
Catch this case and restore the old behaviour.
This fixes a heap buffer overflow read in `g_utf8_validate()` and
`g_str_is_ascii()`, at the cost of always calling `strlen()` on the
input string if its length isn’t known already.
The overflow read was not a security vulnerability, but getting valgrind
and asan to understand that, across all platforms and build
configurations, doesn’t seem to be possible with the resources available
to us. In particular, the `ifunc` approach doesn’t work on muslc, and
doesn’t work when statically linked.
The UTF-8 validation code should still be faster than the old approach
(GLib 2.82 and older), as `strlen()` is SIMD-accelerated in glibc, and
UTF-8 validation is SIMD accelerated in GLib. The combination of the two
should still be faster than the bytewise read loop we used to have.
Unfortunately, correctness and testability have to be prioritised over
absolute performance.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: #3493Fixes: #3511Fixes: #3526
This could potentially eventually become a public GLib API, but there
doesn’t seem to be a huge need for it right now (e.g. this file contains
the only use of `/proc/self/fd/%d` in GLib), so let’s keep it private
for now and avoid committing to API stability just yet.
This gives time for other platforms to add their platform-specific
implementations for it too, if they need. I’ve added a couple of
pointers to what I *think* the right APIs might be, from my research,
but I have not prototyped those implementations.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
The Debian 12.8 point release included a version of ninja that is
equivalent to the one we were building from source here.
This reverts commit dbd7280c5e.
Signed-off-by: Simon McVittie <smcv@debian.org>
When a conversion is finished, the code would return 0 from its write
vfunc. This is disallowed by the API of g_output_stream_write() and
causes g_output_stream_splice() as used by g_converter_convert_bytes()
to turn into an infinite loop.
Instead, raise a G_IO_ERROR_MESSAGE_TOO_LARGE error so that the calling
code can decide how to deal with it.
Testcase included.
Closes#3532
It is unused when compiling with `G_DISABLE_ASSERT`. That’s fine, but we
definitely want the `g_hash_table_remove()` call to still be made.
Fixes this CI failure: https://gitlab.gnome.org/GNOME/glib/-/jobs/4483098
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Testing this in a normal testcaes is a bit tricky, since
triggering a non-fatal assertion has the side-effect of
marking the test as failed.
So just don't run any testcases here, but check the side-effect
manually. Since we don't produce TAP output when not using
g_test_run(), tell meson that we're using the exitcode protocol.
There is a race between releasing and re-acquiring an interned
GRefString if this happens on two threads at the same time. This can
result in already freed memory to be returned from
g_ref_string_new_intern().
| Thread 1 | Thread 2 |
| ------------------------------ | ----------------------------- |
| g_ref_string_release() | g_ref_string_new_intern() |
| g_atomic_rc_box_release_full() | g_mutex_lock() |
| | g_hash_table_lookup() |
| remove_if_interned() | g_ref_string_acquire() |
| g_mutex_lock() | g_mutex_unlock() |
| g_hash_table_remove() | |
| g_mutex_unlock() | |
| g_free() | |
| | return res; // this is freed |
This use-after-free usually also gives a critical warning because
g_atomic_ref_count_inc() checks for the refcount having been 0
before incrementing.
It is not possible to safely implement weak references via garcbox.
To avoid this race do not implement weak references via garcbox but
instead implement the allocation of the string manually with a manually
managed reference count. This allows to safely resurrect the interned
string if the above race happens, and also avoids other races.
As a side-effect this also
* reduces the allocation size in addition to the actual string length
from 32 bytes to 16 bytes on 64 bit platforms and keeps it at 16 bytes
on 32 bit platforms,
* doesn't lock a mutex when freeing non-interned GRefStrings.