When getting a child from a serialised variable array, check its offset
against the length of the serialised data of the array (excluding the
length of the offset table). The offset was already checked against the
length of the entire serialised array (including the offset table) — but a
child should not be able to start inside the offset table.
A test is included.
oss-fuzz#9803
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Previously, GVariant has allowed ‘arbitrary’ recursion on GVariantTypes,
but this isn’t really feasible. We have to deal with GVariants from
untrusted sources, and the nature of GVariantType means that another
level of recursion (and hence, for example, another stack frame in your
application) can be added with a single byte in a variant type signature
in the input. This gives malicious input sources far too much leverage
to cause deep stack recursion or massive memory allocations which can
DoS an application.
Limit recursion to 128 levels (which should be more than enough for
anyone™), document it and add a test. This is, handily, also the limit
of 64 applied by the D-Bus specification (§(Valid Signatures)), plus a
bit to allow wrapping of D-Bus messages in additional layers of
variants.
oss-fuzz#9857
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When checking whether a serialised GVariant tuple is in normal form,
it’s possible for `offset_ptr -= offset_size` to underflow and wrap
around, resulting in gvs_read_unaligned_le() reading memory outside the
serialised GVariant bounds.
See §(Tuples) in gvariant-serialiser.c for the documentation on how
tuples are serialised. Briefly, all variable-length elements in the
tuple have an offset to their end stored in an array of offsets at the
end of the tuple. The width of each offset is in offset_size. offset_ptr
is added to the start of the serialised tuple to get the offset which is
currently being examined. The offset array is in reverse order compared
to the tuple elements, hence the subtraction.
The bug can be triggered if a tuple contains a load of variable-length
elements, each of whose length is actually zero (i.e. empty arrays).
Includes a unit test.
oss-fuzz#9801
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Emulated futexes are slower than real ones; if they were not, there
would be no point in using the real futexes. On some machines they
are sufficiently slow to cause test timeouts.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fedora is using https://fedoraproject.org/wiki/Changes/Annobin
to try to ensure that all objects are built with hardening flags.
Pass down `CFLAGS` to ensure the SystemTap objects use them.
Without gatomic.h, build fails on:
In file included from garcbox.c:24:0:
garcbox.c: In function ‘g_atomic_rc_box_acquire’:
grefcount.h:101:13: error: implicit declaration of function ‘g_atomic_int_get’; did you mean ‘__atomic_store’? [-Werror=implicit-function-declaration]
(void) (g_atomic_int_get (rc) == G_MAXINT ? 0 : g_atomic_int_inc ((rc))); \
^
garcbox.c:292:3: note: in expansion of macro ‘g_atomic_ref_count_inc’
g_atomic_ref_count_inc (&real_box->ref_count);
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
All pool threads are named "pool" and this a bit annoying when looking
at system-wide traces or statistics for a system where several
applications use thread pools. Include the prgname in the thread names
to get a better default name. The total length including the "pool-"
prefix is limited to 16 bytes in order for it to work on all systems.
Change-Id: I473a9f534c4630f3e81da72ff96d8f593c60efac
A double paren forces the compiler to assume that the
statement is right. That may not be the case.
This is essentially reverting b44fba25fb.
See https://bugzilla.gnome.org/show_bug.cgi?id=760215.
It's more morth to allow find common mistakes (= instead of ==
in conditionals) than masking them to make some rarely used
code work.
We still clear the key/value on removal, but since we're growing the
arrays with realloc() now, we can't guarantee that incoming memory is
cleared. There's no reason it should be either, since we check the
hashes array (which is always in a defined state) before accessing the
other arrays.
When g_hash_table_resize() gets called, we clear out tombstones and grow
the table at the same time if needed. However, the threshold was set too
low, so we'd grow if the load was greater than .5 after subtracting
tombstones. Increase this threshold to ~.75.
When resizing, we were keeping both the old and new hash, key and value
arrays around while we reinserted entries, resulting in a peak memory
overhead of 50%. Using a temporary bookkeeping array with one bit per
entry we can now grow and shrink the main arrays using realloc() and an
eviction scheme, reducing the overhead to .625% (assuming 64-bit keys and
values). Tests show the CPU overhead is negligible.
If int is smaller than void * on our arch, we start out with
int-sized keys and values and resize to pointer-sized entries as
needed. This saves a good amount of memory when the HT is being
used with e.g. GUINT_TO_POINTER().
I’m fed up of trying to read these and having my head done in by mixed
tabs and spaces.
This introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This avoids the convenience library being treated as though it was
an installed static library (objects not included in the dependent
static library, and convenience library being listed in the pkg-config
metadata), both of which would make static linking impossible.
This is a workaround for meson not having
https://github.com/mesonbuild/meson/pull/3939 merged yet.
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/1536
Signed-off-by: Simon McVittie <smcv@collabora.com>
Previously, it was installed unmodified by the Meson build system.
We don't need to define @bindir@, because gtester-report never
actually referred to it. We also don't need a definition of
GTESTER_REPORT for use by GLib itself, because its last use was removed
in 2013 (https://bugzilla.gnome.org/show_bug.cgi?id=709995).
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/1544
Signed-off-by: Simon McVittie <smcv@collabora.com>
This makes it easier to debug test failures, by ensuring that g_debug()
and g_test_message() are printed as TAP diagnostics.
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/1528
Signed-off-by: Simon McVittie <smcv@collabora.com>
The text about deallocation of GArrays with elements containing
dynamically-allocated memory was confusing. It initially mentioned
clear_func, but later said elements with dynamically allocated memory
"should be freed separately".
Clarify this by using the same structure as g_ptr_array_free —
highlight the need to set a clear_func by consolidating the text about
it in a separate paragraph.
https://gitlab.gnome.org/GNOME/glib/merge_requests/348
Previously, in the case where 'kf' has more than one ref, calling
g_key_file_free(kf) would break it. For example, calling
g_key_file_has_key(kf, ...) would hit the following assertion:
g_hash_table_lookup: assertion 'hash_table != NULL' failed
This is because g_key_file_free() calls g_key_file_clear() which sets
self->groups and other fields to NULL; most lookup functions assume
these fields are non-NULL.
One fix would be to call g_key_file_init() right after
g_key_file_clear() in g_key_file_free(). However, in the case where
there are no other refs to the keyfile, this would mean allocating
many new hash tables which will be immediately destroyed when
g_key_file_unref() removes the last ref. Instead, inline the unref, and
re-initialize the internal state when the keyfile is still alive.
1) Creating a directory with 0666 does not prevent
traversal on Windows (ACL determines the possibility
of traversal, and Windows mkdir() does not translate
permission bits into ACL). Don't do the traversal check on Windows.
2) Creating a file with 0555 also isn't translated into
read-only ACL, Windows sets the read-only attribute instead,
which blocks all changes, including changes to file times.
Add the write permissions on Windows before changing file times.
It turns out that UCRT (which is the C runtime that Visual Studio
uses by default these days) quietly changed the semantics for
stat() functions and its variants. Previously they provided data
for the symlink (if the file queried was a symlink), now they
provide data for the target of the symlink.
glib used to call _wstat64() to get certain stat-ish data about
files, such as st_dev, since it was deemed that computing that
data in glib using custom code would be pointless, as _wstat64()
worked just fine.
With UCRT this is no longer true. This commit drops _wstat64() in
favour of a bunch of custom calls that populate the stat buffer
manually. This way glib correctly gets information about a symlink,
not its target.
The _fstat64() call is still being used, as it does not suffer
from this problem and thus remains untouched.
Even if we're using a prime modulo for the initial probe, our table is
power-of-two-sized, meaning we can set the mask simply by subtracting one
from the size.
Sequential integers would be densely packed in the table, leaving the
high-index buckets unused and causing abnormally long probes for many
operations. This was especially noticeable with failed lookups and
when "aging" the table by repeatedly inserting and removing integers
from a narrow range using g_direct_hash() as the hashing function.
The solution is to multiply the hash by a small prime before applying
the modulo. The compiler optimizes this to a few left shifts and adds, so
the constant overhead is small, and the entries will be spread out,
yielding a lower average probe count.
Extended path prefix looks like "\\?\",
and NT object path prefix looks like "\??\".
Strip them only if they are followed by a character
(any character) and a colon (:), indicating that
it's a DOS path with a drive.
Otherwise stripping such prefix might result in a patch
that looks like a relative path.
For example, "\\?\Volume{GUID}\" becomes "Volume{GUID}\",
which is a valid directory name.
Currently it's up to the user to make sense of such paths.
When running a test as a subprocess and matching its output, it’s very
annoying for GLib to tell you that the output didn’t match your pattern,
*but not actually say what the output was*. Fix that.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Expands to the GNU C fallthrough statement attribute if the compiler is gcc.
This allows declaring case statement to explicitly fall through in switch
statements. To enable this feature, use -Wimplicit-fallthrough during
compilation.
It might not be immediately obvious that this is the case. Let's record
it in the description of `GTimeVal` itself and also in
`g_time_val_from_iso8601`.
We also drop an incorrect statement in the documentation for
`g_time_val_from_iso8601` stating that years up to 3000 were supported;
this is also not true for the same reason.
Related: #1509
On 32 bit systems, the size of a long might be the same as the size of
an int. In that case, we won't be able to get an overflow when
converting from a GTimeVal to a time_t. Skip the test for this in that
case.
Closes#1509
Test a few situations where NULL values for optional out parameters
weren’t being tested. This takes the branch coverage of GHashTable up to
100% (ignoring g_return_if_fail() branches).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If the given key is not found, clear the orig_key and value arguments to
NULL as well as returning FALSE. Then the caller can unconditionally
check them.
This makes the behaviour of g_hash_table_lookup_extended() consistent
with g_hash_table_steal_extended().
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This eliminates some ‘discards const qualifier’ warnings when compiling
on Solaris with --enable-dtrace.
See the log files in
https://gitlab.gnome.org/GNOME/glib/issues/1493#note_299037.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The goal of this commit is to reduce differences between the autotools and meson build.
With autotools AC_FUNC_ALLOCA was used which defines HAVE_ALLOCA_H, HAVE_ALLOCA,
C_ALLOCA. meson tried to replicate that with has_function() but alloca can be a macro
and and is named _alloca under Windows. Since we require a working alloca anyway
and only need to know if the header exists replace AC_FUNC_ALLOCA with a simple
AC_CHECK_HEADERS.
There is still one user of HAVE_ALLOCA in the embedded gnulib, but since alloca is
always provided through galloca.h just force define HAVE_ALLOCA there and add a comment.
The docs were mentioning alloca as an example for cross compiling. Since that variable no
longer exists now replace it with another one.
The new typeof() macro version of g_clear_pointer() was evaluating its
pointer argument more than once, meaning any side effects would be
evaluated multiple times.
The existing (other) macro version of g_clear_pointer() was evaluating
its argument exactly once. This mismatch could have confused people or
lead to subtle bugs.
See https://gitlab.gnome.org/GNOME/glib/issues/1494.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
These functions may be OK to leave the G_GNUC_MALLOC attribute on,
because the only valid pointers in the storage areas they return are,
themselves, new pointers.
However, it’s a lot easier to remove the attributes now than to try and
diagnose miscompilations in future. The performance impact of this is
likely to be unmeasurable. If there are performance problems caused by
this, then they can be profiled and fixed case-by-case in future,
bearing in mind the possibility for miscompilation if G_GNUC_MALLOC is
readded.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1465
These are our most critically incorrect uses of G_GNUC_MALLOC. See the
previous commit for details.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1465
Thanks to some great investigation by Benjamin Moody, it’s clear that
our documentation and usage of G_GNUC_MALLOC has fallen behind GCC’s
interpretation of the malloc attribute, meaning that recent versions of
GCC could miscompile code which uses G_GNUC_MALLOC incorrectly.
Update the documentation of G_GNUC_MALLOC to match the current GCC
documentation (for GCC 8.2). Following commits will drop our use of
G_GNUC_MALLOC from inappropriate functions.
Specifically, the change in GCC’s interpretation of the malloc attribute
which could cause miscompilation is that returned storage areas are now
assumed to not contain valid pointers — so realloc() cannot have the
malloc attribute, and neither can a function which returns a newly
allocated structure with fields initialised to other pointers.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1465
Clarify that we actually raise SIGTRAP rather than calling abort(). We
haven’t called abort() since about 2011, when commit
a04efe6afb changed the logic to use
SIGTRAP to make it possible to skip past fatal log messages in the
debugger if they weren’t relevant to the problem being debugged.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1448
The size of stat depends on various macros on Windows which leads to
the problem of size mismatches when glib is built with a different configuration
than a program using it.
For example the autotools build defaults to _FILE_OFFSET_BITS=64 and a program
not defining _FILE_OFFSET_BITS will allocate a too small struct on the stack,
leading to stack corruption when glib writes to it.
To make the size the user sees always match the default mingw build define GStatBuf
as _stat64 (same as _FILE_OFFSET_BITS=64) under mingw+64bit.
Some of the test vectors don’t specify a timezone, so the local one is
used; the comparisons to the expected results (which are in UTC) then
fail.
See discussion in
https://gitlab.gnome.org/GNOME/glib/merge_requests/225.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When calculating the value of a timezone offset, ensure that any offsets
done with negative numbers are done in a signed integer.
oss-fuzz#9815
Signed-off-by: Philip Withnall <withnall@endlessm.com>
token_stream_prepare() was over-reading at the start of bytestring
literals (`b'blah'`).
Add tests for that, and for some other situations regarding bytestring
literal parsing, in order to try and get full branch coverage of that
bit of code.
oss-fuzz#9805
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The token_stream_peek() functions were not doing any bounds checking, so
could potentially read 1 byte off the end of the input blob. This was
never noticed, since the input stream is almost always a nul-terminated
string. However, g_variant_parse() does allow non-nul-terminated strings
to be used with a @limit parameter, and the bugs become apparent under
valgrind if that parameter is used.
This includes modifications to the test cases to cover the
non-nul-terminated case.
Spotted by ossfuzz.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
(Tweaked by Philip Withnall <withnall@endlessm.com> to fix some minor
leaks, code formatting, and add a test comment.)
Signed-off-by: Simon McVittie <smcv@collabora.com>
These come from looking at the code coverage data. We should now have
full branch coverage of the ISO 8601 parser.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It never worked; we’ve always parsed the year with strtoul() (unsigned).
While negative years are supported by the ISO 8601 standard, they can
only be used by mutual agreement of the two parties interchanging data.
Moreover, they are not supported by GTimeVal, which is what we’re
filling with the results.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The code was previously doing a few bits of arithmetic without checking
whether they would overflow, and hence not validating the date/time it
was parsing very strictly.
The parser is now not 100% strict, but should avoid any arithmetic
overflows which would cause an invalid result to be returned even though
g_time_val_from_iso8601() had returned TRUE.
oss-fuzz#9673
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This repurposes the existing skip-all test as "combining", since it
is no longer entirely about runs where every test-case was skipped.
Signed-off-by: Simon McVittie <smcv@collabora.com>
If a test is marked with g_test_incomplete(), then it is expected to
fail, so when it fails the test executable should still exit 0
(or possibly 77, if all tests are either skipped or incomplete).
Signed-off-by: Simon McVittie <smcv@collabora.com>
In the test for the unit testing framework, we might as well have
exemplary behaviour. Leave behind a single call to g_assert (TRUE)
just to prove that it still works.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The TAP specification says that failing tests that are currently
expected to fail (like Automake's XFAIL) are to be reported as
"not ok", with that failure ignored as a result of the TODO
directive, with this example:
not ok 3 - infinite loop # TODO halting problem unsolved
A test reported as "ok # TODO" indicates that something that is
expected to fail has unexpectedly succeeded, similar to Automake's
XPASS.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Assigning the gpointer return value from g_atomic_pointer_get() to a
gsize variable was not making -Wbad-function-cast happy. Assign to an
intermediate gpointer variable and then cast that instead.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1475
g_test_skip() is appropriate for tests that can't run due to missing
functionality on the host system, whereas g_test_incomplete() is
for expected-to-fail tests for unimplemented functionality in the
code under test.
See also https://bugzilla.gnome.org/show_bug.cgi?id=793635 and
commit 5459b345.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Testing that an interned string is released once its last reference is
dropped is not possible without a hook into the interning machinery;
just checking that the returned pointer for the same string is going to
be different after the last release() is not guaranteed to work, as the
systema allocator is perfectly within its rights to recycle pointers, as
long as they are unique while valid.
Closes#1467
When checking that the timezone code falls back to UTC if a zone is
unknown, don’t use ‘PST’, because that can actually exist on some
systems.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1433
See previous commit; same reasoning behind the commit, except that these
sources weren’t (yet) causing `make distcheck` to fail.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Instead of messing around with EXTRA_*_SOURCES and manually handling .lo
files, why not just add gwin32.c to the GLib sources conditionally?
This will hopefully fix `make distcheck` failing due to gwin32.Plo not
being generated in the sub-builddir≠srcdir stage, due to depcomp
inexplicably not generating it. (Note that it is correctly generated in
non-distcheck builds.)
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The parser state machine for bookmark files did not handle unexpected
nesting of elements, such as a <bookmark> element inside a <title>
element — it would print a critical warning rather than returning a
GError.
Fix that, and add various unit tests for it. The set of tests includes
various other general markup tests as provided by Jussi Judin.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1035
That should format these character classes correctly in the
documentation, and prevent them being interpreted by gtk-doc as (broken)
Markdown hyperlinks.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This fixes a gtk-doc complaint about the argument name not matching
what’s used in the gtk-doc comment.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It is a bug if we distribute files which are generated at build time —
they should be built on the machine which is compiling GLib, not be
shipped in the tarball.
This brings the autotools-generated tarball in line with the
ninja-generated one, with the exception of man pages and gtk-doc HTML
output.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If something which looks like a closing tag is left unfinished, but
isn’t paired to an opening tag in the document, the error handling code
would do a null pointer dereference. Avoid that, at the cost of
introducing a new translatable error message.
Includes a test case, courtesy of pdknsk.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1461
When formatting the error messages for markup parsing errors, the parser
was unconditionally reading a UTF-8 character from the input buffer —
but the buffer might end with a partial code sequence, resulting in
reading off the end of the buffer by up to three bytes.
Fix this and add a test case, courtesy of pdknsk.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1462
We should bail when we detect that adding a number of items to an array
would cause it to overflow. Since we can't change to using gsize for ABI
reasons we should protect the integrity of the process even if that means
crashing.
These tests will work if the glibc translations are up to date, or if
the GLib translations are installed and up to date; but not if neither
are in place.
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
https://gitlab.gnome.org/GNOME/glib/issues/1447