9274 Commits

Author SHA1 Message Date
Philip Withnall
d0cb0fc016 Merge branch 'fix-string-replace-heap-buffer-overflow' into 'main'
gstring: Fix a heap buffer overflow in the new g_string_replace() code

See merge request GNOME/glib!4332
2024-10-15 09:32:14 +00:00
Alan Coopersmith
b6004c70cc tests: add casts to avoid -Wformat errors on 32-bit Solaris builds
For historical reasons, pid_t & mode_t are defined as long instead
of int for 32-bit processes in the Solaris headers, and even though
they are the same size, gcc issues -Wformat headers if you try to
print them with "%d" and "%u" instead of "%ld" & "%lu".

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2024-10-14 18:29:29 -07:00
Alan Coopersmith
5ff0429147 glib-unix: Fix build of safe_fdwalk() on Solaris
The refactoring done by commit 168fd4f2b3dbaa100ace1264462ccc6fc33ea39c
lost the definition of the open_max variable used in the Solaris ifdefs.

Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2024-10-13 16:26:26 -07:00
Philip Withnall
450fa0a501
gdate: Fix minor typo in documentation comment
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-10 16:48:54 +01:00
Philip Withnall
0175b5ff12
gvarianttypeinfo: Mark one-off leaks as ignored
These two data structures are allocated once and live for the lifetime
of the process, and are leaked on exit. That’s fine, and intentional.
Add `g_ignore_leak()` to them to make that a bit clearer, and
communicate the intent to asan.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3472
2024-10-10 13:21:32 +01:00
Christian Hergert
67532b4555 gvarianttype: Garbage Collect GVariantTypeInfo
The goal of this change is to avoid re-parsing `GVariantTypeInfo` on
every creation or parsing of a `GVariant` byte-buffer. Parsing presents
a non-trivial amount of overhead which can typically be elided.

It was discovered that many applications and tooling are re-generating
this information upon receiving a D-Bus message as they tend to process
messages serially, thus dropping the last reference count.

Previously, when the last reference count for a `GVariantTypeInfo` was
dropped we would finalize the parsed type information.

This change keeps `GVariantTypeInfo` alive in a Garbage Collected array.
The array is collected upon reaching a 32 entries. The number 32 was
chosen because it is larger than what I've seen active on various D-Bus
based applications-or-daemons.

Take a simple test case of using `GVariantBuilder` in a loop with a
debugoptimized build of GLib. A reduction in wallclock time can be
observed in the 35% to more than 70% based on the complexity of the
GVariant being created.

For cases like ibus-daemon, it was previously parsing `GVariantTypeInfo`
up to dozens of times per key-press/release cycle.

Closes: #3472
2024-10-10 13:17:47 +01:00
Christian Hergert
ad572e7780 glib/gutf8: use ifunc to check for valgrind
This attempts to use GCC __attribute__((ifunc("resolver_func"))) to check
for valgrind early in the process startup so that the proper function is
dispatched instead of runtime checks within the function.

This should make #3493 less annoying when run under Valgrind.
2024-10-09 16:26:05 -07:00
Christian Hergert
f88dc81a1b glib/gmacros: no_sanitize_address and ifunc fallbacks
Allow these to be checked for so that we can avoid compiler checks in
various places.
2024-10-09 15:27:22 -07:00
Philip Withnall
26d8553af5 Merge branch 'win32-cleanup' into 'main'
Win32 cleanup: do not define STRICT

See merge request GNOME/glib!4339
2024-10-09 16:01:57 +00:00
Luca Bacci
13f20f1546 Win32: Do not define STRICT
It's defined automatically by system headers (both Windows SDK and mingw-w64)
2024-10-09 11:26:20 +02:00
Philip Withnall
c9e48947e1
gstring: Fix a heap buffer overflow in the new g_string_replace() code
This affects the new `g_string_replace()` code which landed on `main` a
few days ago. It does not affect the old implementation of
`g_string_replace()`.

The code for the `f_len == 0` (needle is an empty string) case was
modifying `string` in the loop, without updating any of the string
pointers into it. If the replacement was long enough (or inserted enough
times), this would trigger a realloc of `string->str` and cause all the
string pointers to be dangling.

Fix this by pulling the `f_len == 0` code out into a separate branch and
loop, rather than trying to integrate it into the main loop. This
simplifies the main loop significantly, and makes both easier to verify.

An alternative approach, which doesn’t involve splitting the
`f_len == 0` case out, might have been to track the positions using
indexes rather than string pointers. I think the approach in this commit
is better, though, as it removes the possibility of `f_len == 0`
entirely from the loop, which makes it much easier to verify termination
of the loop.

Add more tests to validate this, including the test from oss-fuzz which
triggered the realloc and found the heap buffer overflow.

The new tests have also been run against the _old_ implementation of
`g_string_replace()` to ensure its behaviour (particularly around `f_len
== 0 && limit > 0`) has not changed.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

oss-fuzz#371043019
2024-10-03 18:18:19 +01:00
Philip Withnall
fb4f2e5578 Merge branch 'wip/chergert/c-utf8' into 'main'
glib/utf8: Use SIMD for UTF-8 validation

Closes #3481

See merge request GNOME/glib!4319
2024-10-03 15:07:17 +00:00
Philip Withnall
72384894b8
gutf8: Remove dead branch condition
This arm of the condition is always true, because 0x00 has been checked
in the previous branch.

This is not going to improve performance, but does mean we now have full
branch coverage of the code via our unit tests, which gives some
assurance that it’s all good.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3481
2024-10-03 15:46:01 +01:00
Philip Withnall
36e4bb9872
tests: Add some more UTF-8 validation corner cases
The move to c-utf8 for validation has exposed a few new branches where
our existing (fairly comprehensive) UTF-8 validation test suite didn’t
check things.

Add unit tests for those branches, so we keep code coverage.

I’ve validated (with an independent UTF-8 decoder) that the test vectors
are correctly marked as valid/invalid in the test data (so the tests
aren’t just blindly coded to match the behaviour of the new validator
code).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3481
2024-10-03 15:43:35 +01:00
Philip Withnall
e570263483
tests: Add basic unit tests for g_str_is_ascii()
It turns out it’s not actually been explicitly tested before, even
though it has full code coverage through being called by other code
which is tested.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-03 14:31:02 +01:00
Christian Hergert
b72650542c glib/utf8: Use SIMD for g_str_is_ascii()
This moves g_str_is_ascii() from gstrfuncs.c to gutf8.c so that we can
reuse the same SIMD code for ASCII validation.

On Apple Silicon:

 Before:  3297 MB/s
  After: 26146 MB/s
2024-10-01 15:30:32 -07:00
Christian Hergert
1d3d7336ed glib/utf8: Use SIMD for UTF-8 validation
This is based on the https://github.com/c-util/c-utf8 project and has
been adapted for portability and integration into GLib. c-utf8 is dual
licensed Apache-2.0 and LGPLv2.1+, the latter matching GLib.

Notably, `case 0x01 ... 0x7F:` style switch/case labels have been
converted to if/else which is more portable to non-GCC/Clang platforms
while generating the same assembly, at least on x86_64 with GCC.

Additionally, `__attribute__((aligned(n)))` is used in favor of
`__builtin_assume_aligned(n)` because it is more portable to MSVC's
`__declspec(align(n))` and also generates the same assembly as GCC's
`__builtin_assume_aligned(n)`.

For GCC x86_64 Linux on a Xeon 4214 this improved the throughput of
g_utf8_validate() for ASCII from 750MB/s to around 10,000MB/s (13x).

On GCC aarch64 Linux with an Apple Silicon M2 Pro we go from about
2,200 MB/s to 26,700 MB/s (12x).

Closes: #3481
2024-10-01 12:44:36 -07:00
Philip Withnall
c6340430db
gvarianttype: Convert docs to gi-docgen linking syntax
And improve formatting in a few places while I’m there:
 * Add quotes around ‘maybe’ types to make it clearer that ‘maybe’ is
   being used as a proper noun
 * Add linebreaks so that all doc comments start with a single-sentence
   summary of the method
 * Improve formatting of constants
 * Add a few links to external specifications

See https://developer.gnome.org/documentation/guidelines/devel-docs.html

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3250
2024-10-01 19:55:28 +01:00
Philip Withnall
fecf2b2e7b
gvarianttype: Add two missing (nullable) annotations
Spotted while working on the docs (see the following commit).

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 19:54:40 +01:00
Philip Withnall
e14a393d27 Merge branch '3483-mainloop-test' into 'main'
tests: Rework a mainloop test to use an explicit termination condition

Closes #3483

See merge request GNOME/glib!4324
2024-10-01 15:00:03 +00:00
Philip Withnall
9e73d9a15a Merge branch 'utf8-docs' into 'main'
gutf8: Convert docs to gi-docgen linking syntax

See merge request GNOME/glib!4304
2024-10-01 14:53:53 +00:00
Philip Withnall
23d6db4ea9
gbytes: Convert docs to gi-docgen linking syntax
Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3250
2024-10-01 15:51:29 +01:00
Philip Withnall
f8ba505dc1
gutf8: Clarify position of end returned from g_utf8_validate()
It wasn’t previously clear (to me) whether `end` was returned pointing
to the nul terminator, or to the byte immediately preceding it. Try and
clarify that.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 15:44:43 +01:00
Philip Withnall
7302c04e32
gutf8: Convert docs to gi-docgen linking syntax
Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3250
2024-10-01 15:44:36 +01:00
Philip Withnall
766f3414eb Merge branch 'steal-handle-id' into 'main'
utils: Add g_steal_handle_id() to complement g_clear_handle_id()

See merge request GNOME/glib!4308
2024-10-01 14:25:58 +00:00
Michael Catanzaro
04543594d4 Merge branch 'gbytes-double-free' into 'main'
gbytes: Add an assertion to placate static analysis

See merge request GNOME/glib!4323
2024-10-01 14:04:13 +00:00
Michael Catanzaro
637ec98f2e Merge branch 'disable-assert-fix' into 'main'
gvariant: Fix unused variables when G_DISABLE_ASSERT is defined

See merge request GNOME/glib!4322
2024-10-01 13:57:04 +00:00
Philip Withnall
dfb0ea737b
gstdio: Move doc comment for g_clear_fd() to be next to the code
Nobody’s going to keep it up to date if it’s floating about in an
unrelated place, not next to the code.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 14:29:31 +01:00
Philip Withnall
f9d1f614a9
gmain: Move doc comment for g_steal_fd() to be next to the code
Nobody’s going to keep it up to date if it’s floating about in an
unrelated place, not next to the code.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 14:29:25 +01:00
Philip Withnall
a960725b5d
glib: Add declarations for public static inline methods
This is needed in order to expose them in the GIR, and hence for their
documentation to work.

See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4308#note_2236525

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 14:29:18 +01:00
Philip Withnall
431e75fa36
utils: Add g_steal_handle_id() to complement g_clear_handle_id()
Just like we have `g_steal_pointer()` and `g_clear_pointer()`, it would
be useful to have a ‘steal’ version of `g_clear_handle_id()`.

Particularly in situations where a clear function can’t be represented
as a `GClearHandleFunc`, such as
`g_dbus_connection_signal_unsubscribe()` (there’s no way of passing the
`GDBusConnection` to it) — or in situations where a handle ID isn’t
being released, but is being passed from one struct to another or from a
local scope to a struct or vice-versa.

Includes unit tests.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 14:29:05 +01:00
Philip Withnall
a40a33dfe0
tests: Rework a mainloop test to use an explicit termination condition
And to not assume that every main context iteration will provide
progress on the sources that the test is interested in. It’s possible
that other sources may be attached to the `GMainContext` which get
dispatched instead of the pipe sources on an iteration.

I don’t know if this will fix #3483, but it will certainly make this
test a little tidier. It doesn’t affect test run time.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Fixes: #3483
2024-10-01 13:32:29 +01:00
Philip Withnall
df8592268a
gbytes: Add an assertion to placate static analysis
Otherwise `scan-build` thinks it’s possible for the `GBytes` to be
double-freed, which would indeed happen if `try_steal_and_unref()` were
to return `NULL` on this branch.

It’s not actually possible for it to return `NULL` here though, as if
`bytes->data` were `NULL`, the function would have already returned
higher up.

Fixes this `scan-build` failure:
https://gitlab.gnome.org/GNOME/glib/-/jobs/4359929

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 13:15:15 +01:00
Philip Withnall
c920d2257b
gvariant: Fix unused variables when G_DISABLE_ASSERT is defined
This fixes commit 9eb9df2396, which I really should have noticed at the
time would cause a load of unused variables to be declared if compiled
with `G_DISABLE_ASSERT`. That’s what the original `#ifdef`s were to
protect against.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-10-01 12:24:30 +01:00
Christian Hergert
4db378a739 gvariant: Add portable alignment fix for GVariant suffix
We want to keep the suffix aligned to 8 bytes on 32-bit too. This makes
sure we do that in a way that is portable across our supported compilers.

Fixes: #3486
2024-10-01 12:19:26 +01:00
Chun-wei Fan
1b9d3964f5 gvariant-core.c: Fix suffix alignment on 32-bit MSVC builds
With a similar rationale to commit d50102f2, this avoids the static
assert from failing on 32-bit Visual Studio builds.
2024-10-01 17:25:37 +08:00
Philip Withnall
d50102f2d8
gvariant: Fix suffix alignment on 32-bit machines
This fixes commit 0b083e3d8c. The static assertion added in that commit
fails on 32-bit machines.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-29 13:12:31 +01:00
Philip Withnall
d3e0d4fbde
gpoll: Remove unused variable
Fixes commit 3baf1f1a73952277abd05ac82b0b356c6f5ab725.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-09-29 12:30:53 +01:00
James Tirta
e8517e7776 remove quadratic behavior in g_string_replace
Current implementation replaces find in string with replace
one-at-a-time and replacement is done in O(n^2) time. The new
implementation is O(n). Memory allocation is done once instead of
incrementally.

In the old implementation, every replacement will move the whole
rest of the string from the current position to make space for
the replace string and then insert the replace string.

In the new implementation, when the replace string is shorter or equal
to the find string, it will move the characters in-place and requires no
additional memory. When the replace string is longer, find the required
size needed for the new string and preallocate a new string to copy the
original string to with its replacements. When the replace string is an
empty string use the old implementation to handle the special case.
2024-09-28 21:09:53 +00:00
Philip Withnall
019de2cbbc Merge branch 'wip/chergert/gvariant-inline-suffix-data' into 'main'
glib/gvariant: Inline small gvariant data using C99 flexible arrays

See merge request GNOME/glib!4301
2024-09-27 12:35:05 +00:00
Christian Hergert
0b083e3d8c glib/gvariant: Avoid many GBytes allocation
Previously, all GVariants would allocate a GBytes for the buffered
contents. This presents a challenge for small GVariant type created
during the building process of GVariantBuilder as that results in an
allocation for the GVariant, GBytes, and the byte buffer.

Recent changes for GBytes may reduce those 3 allocations to 2, but even
that is quite substantial overhead for a 32-bit integer.

This changeset switches GVariant to use g_new/g_free allocators instead
of g_slice_new/free. When benchmarked alone, this presented no
measurable difference in overhead with the standard glibc allocator.

With that change in place, allocations may then become variable in size
to contain small allocations at the end of the GVariant reducing things
to a single allocation (plus the GVariantTypeInfo reference).

The size of GVariant is already 1 cacheline @ 64-bytes on x86_64. This
uses that to guarantee our alignment of data maintains the 8-bytes
guarantee of GVariant, and also extends it to match malloc().

On 32-bit systems, we are similarly aligned but reduce the amount we
will inline to 32 bytes so we have a total of 1 cacheline.

This is all asserted at compile-time to enforce the guarantee.

In the end, this changeset reduces the wallclock time of building many
GVariant in a loop using GVariantBuilder by 10% beyond the 10% already
gained through GBytes doing the same thing.
2024-09-26 14:28:41 -07:00
Philip Withnall
c2a5bd2c65 Merge branch 'wip/chergert/no-copy-gvarianttype-stack-builder' into 'main'
glib/gvariant: avoid GVariantType copy for stack builders

See merge request GNOME/glib!4286
2024-09-26 11:57:26 +00:00
Philip Withnall
80e8bc7c0b Merge branch 'wip/chergert/reduce-copies-for-gvarianttype-cache' into 'main'
gvarianttypeinfo: reduce caching overhead

See merge request GNOME/glib!4293
2024-09-26 11:11:52 +00:00
Yash Trivedi
3baf1f1a73 gpoll windows: use a threadpool when polling large number of fds 2024-09-26 10:27:19 +00:00
Christian Hergert
c50e44a6e0 glib/gvariant: add g_variant_builder_init_static()
This adds another form of stack building which allows avoiding the rather
expensive GVariantType malloc/memcpy/free. In a tight loop this reduced
wallclock time by about 4-5% for cases where you do not need to further
open using g_variant_builder_open() which still require a copy at this
time.

New API is provided instead of modifying g_variant_type_init() because
previously it was possible (though misguided) to use g_variant_type_init()
which a dynamically allocated GVariantType which could be freed before
g_variant_builder_end() or g_variant_builder_clear() was called.

# Conflicts:
#	glib/gvariant.c
2024-09-25 11:13:58 -07:00
Christian Hergert
2deb5dcfc0 glib/gvariant: add test for g_variant_type_hash() 2024-09-25 10:05:36 -07:00
Christian Hergert
1850b5c1ab gvarianttypeinfo: avoid string copy for cache lookup
When trying to locate a GVariantTypeInfo from the cache we were copying
the string so that we can use g_str_hash, as that requires a \0 terminated
string.

However, we have hash and equal functions which can be used without the
extra copy. Additionally, these were moved to headers in previous commits
so they can be used without having to re-check GVariantType we already
know to be valid.
2024-09-25 10:05:33 -07:00
Philip Withnall
fd9c00179f Merge branch 'wip/chergert/gvariant-use-proper-macros-conditions' into 'main'
Fix incorrect use of assert/debug/check macros

See merge request GNOME/glib!4292
2024-09-25 15:06:10 +00:00
Philip Withnall
267342420f Merge branch 'wip/chergert/fix-ganalyzer-use' into 'main'
glib/gvariant: Fix check for G_ANALYZER_ANALYZING

Closes #3480

See merge request GNOME/glib!4291
2024-09-25 13:43:02 +00:00
Philip Withnall
04e45e3cef Merge branch 'wip/chergert/gvariant-transfer-gbyte-ownership' into 'main'
glib/gvariant: Avoid extraneous GBytes ref counting

See merge request GNOME/glib!4299
2024-09-25 13:42:57 +00:00