This is similar to the earlier commit which prevents child elements of a
variable-sized array from overlapping each other, but this time for
tuples. It is based heavily on ideas by William Manley.
Tuples are slightly different from variable-sized arrays in that they
contain a mixture of fixed and variable sized elements. All but one of
the variable sized elements have an entry in the frame offsets table.
This means that if we were to just check the ordering of the frame
offsets table, the variable sized elements could still overlap
interleaving fixed sized elements, which would be bad.
Therefore we have to check the elements rather than the frame offsets.
The logic of checking the elements up to the index currently being
requested, and caching the result in `ordered_offsets_up_to`, means that
the algorithmic cost implications are the same for this commit as for
variable-sized arrays: an O(N) cost for these checks is amortised out
over N accesses to O(1) per access.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2121
This reduces a few duplicate calls to `g_variant_type_info_query()` and
explains why they’re needed.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2121
If different elements of a variable sized array can overlap with each
other then we can cause a `GVariant` to normalise to a much larger type.
This commit changes the behaviour of `GVariant` with non-normal form data. If
an invalid frame offset is found all subsequent elements are given their
default value.
When retrieving an element at index `n` we scan the frame offsets up to index
`n` and if they are not in order we return an element with the default value
for that type. This guarantees that elements don't overlap with each
other. We remember the offset we've scanned up to so we don't need to
repeat this work on subsequent accesses. We skip these checks for trusted
data.
Unfortunately this makes random access of untrusted data O(n) — at least
on first access. It doesn't affect the algorithmic complexity of accessing
elements in order, such as when using the `GVariantIter` interface. Also:
the cost of validation will be amortised as the `GVariant` instance is
continued to be used.
I've implemented this with 4 different functions, 1 for each element size,
rather than looping calling `gvs_read_unaligned_le` in the hope that the
compiler will find it easy to optimise and should produce fairly tight
code.
Fixes: #2121
The following few commits will add a couple of new fields to
`GVariantSerialised`, and they should be zero-filled by default.
Try and pre-empt that a bit by zero-filling `GVariantSerialised` by
default in a few places.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2121
The timeout is just to stop the test hanging forever, so there’s no need
for it to be so short. It’s caused at least one spurious CI failure:
https://gitlab.gnome.org/GNOME/glib/-/jobs/2445023.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2837
This reverts commit 965061797d.
We are having trouble tracking down the cause of #2769. When the bug
occurs, we fail to set scheduler settings for the new thread pool
thread. This can have serious consequences and should not be ignored. In
retrospect, making this a critical instead of a fatal error has made it
more difficult to notice, debug, and fix. This operation needs to always
work, so let's crash when it fails.
This does not fix#2769, but will hopefully help.
Instead of a plain reference count check failure that is really hard to
understand, let's be explicit, and warn that manipulating an object's
notification queue during its finalization is not allowed.
GDesktopAppInfo never failed in the most simple of the cases: when a
desktop file or a command line app info was pointing to an invalid
executable (for the context).
The reason for this is that we're launching all the programs using
gio-launch-desktop which will always exist in a sane GLib installation,
and thus our call to execvp won't ever fail on failure.
This was partially mitigated by not allowing to create a desktop app
icon using a non-existent executable (even if not fully correctly) but
still did not work in case a custom PATH was provided in the launch
context.
To avoid this, use g_find_program_for_path() to find early if a program
that we're about to launch is available, and if it's not the case return
the same error that g_spawn_async_with_fds() would throw in such cases.
While this is slowing a bit our preparation phase, would avoid to leave
to the exec function the job to find where our program is.
Add tests simulating this behavior.
We used to launch applications with terminals using the normal program
finder logic that did not consider the context path nor the desktop file
working dir. Switch to g_find_program_for_path() to find terminals so we
can ensure that both conditions are true.
Update tests to consider this case too.
Split g_find_program_path() in g_find_program_for_path() that supports
passing path arguments and providing a custom working directory.
Adding tests to cover the cases we were not doing before.
If the user provided source_fds set contains internal fds, this is a
programmer mistake. We can avoid further damage by preventing this
situation.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
As recommended by GDB on Fedora, I have "set debuginfod enabled on" in
my .gdbinit. However, this make assert-msg-test time out.
Let's ignore user gdbinit for the test, as this shouldn't be required
and can easily break the test.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
The platform data comes from the parent process, which should normally
be considered trusted (if we don’t trust it, it can do all sorts of
other things to mess this process up, such as setting
`LD_LIBRARY_PATH`).
However, it can also come from any process which calls `CommandLine`
over D-Bus, so always has to be able to handle untrusted input. In
particular, `v`-typed `GVariant`s must always have their dynamic type
validated before having values of a static type retrieved from them.
Includes unit tests.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
They come from an external process, so they must be validated.
In particular, it’s always easy to forget to validate the type of a
`GVariant`, and just try to get the stored value using a well-known
type; but that’s a programming error if the `GVariant` actually stores a
different type. Always check the variant type first if loading from a
`v`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
These actions are activated as a result of receiving the `ActionInvoked`
signal from `org.freedesktop.Notifications`. As that’s received from
another process over D-Bus, it’s feasible that it could be malformed.
Without validating the action and its parameter, assertions will be hit
within the `GAction` code.
While we should be able to trust whatever process owns
`org.freedesktop.Notifications`, it’s possible that’s not the case, so
best validate what we receive.
Includes unit tests.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
This test is fairly pointless, but puts the infrastructure in place for
adding more tests for `GFdoNotificationBackend` in upcoming commits.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
Invoking an action on a notification should remove it (by default,
unless the `resident` hint is set, but GLib doesn’t currently support
that).
If, somehow, an invalid action is invoked on the notification, that
shouldn’t cause it to be removed though, because no action has taken
place. So change the code to do that.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
As with the previous commit, the arguments to `ActivateAction` have to
be validated before being passed to `g_action_group_activate_action()`.
As they come over D-Bus, they are coming from an untrusted source.
Includes unit tests for all D-Bus methods on `GApplication`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
The action name, parameter and new state are all controlled by an
external process, so can’t be trusted. Ensure they are validated before
being passed to functions which assert that they are correctly typed and
extant.
Add unit tests.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1904
Using `test_run_name` in the path for the isolated dir tree for a test
is fine on Unix, because the `/` separator from GTest paths is suitable
as a file system separator.
On Windows, however, it doesn‘t work when mixed and concatenated with
paths which use backslashes. In particular, byte-by-byte path
comparisons don’t work. There are likely also issues if running on a
system with non-UTF-8 file system encoding.
Fix that by storing a file system path version of `test_run_name`
separately, and using the correct `G_DIR_SEPARATOR` for the host OS.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
That file is created if running the `unstable_tests` suite succeeds. It
can fail, though, leaving that log file nonexistent. There’s no point in
failing the whole test run by bailing out if postprocessing the log file
fails.
Occasionally postprocessing can fail with a `FileNotFoundError`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Some applications (eg., gnome-photos) really want a large thumbnail,
if one can be created. Simply falling back to a smaller one (probably
created by an old nautilus), without giving the application a chance
to create a bigger thumbnail, is undesirable because they will appear
fuzzy.
Therefore, at separate attribute sets for all the thumbnail sizes
that are supported in the spec: normal/large/x-large/xx-large.
The old attribute will now return by default the biggest available, as
it used to be, but also including the x-large and xx-large cases.
Co-Authored-by: Marco Trevisan <mail@3v1n0.net>
Fixes: #621