When targeting mingw on architectures other than x86, the earlier cases
don't apply, and the final fallback, raise(SIGTRAP) isn't usable there.
GCC and Clang both support __builtin_trap(), so in case we have no
other alternatives, and are on windows (where raise() isn't available),
we can resort to this.
When timeout grater than 0 in g_poll function, the WaitForMultipleObjects
call will wait for all the threads to return, but when only one thread
got an event the others will sleep until the timeout elapses, and causes
a stall. Triggering the stop event in g_poll in this case is useless as
it is triggered when all the threads where already signaled or timed-out.
Closes: https://gitlab.gnome.org/GNOME/glib/issues/2107
The g_once() function exists to call a callback function exactly once,
and to block multiple contending threads on its completion, then to
return its return value to all of them (so they all see the same value).
The full implementation of g_once() (in g_once_impl()) uses a mutex and
condition variable to achieve this, and is needed in the contended case,
where multiple threads need to be blocked on completion of the callback.
However, most of the times that g_once() is called, the callback will
already have been called, and it just needs to establish that it has
been called and to return the stored return value.
Previously, a fast path was used if we knew that memory barriers were
not needed on the current architecture to safely access two dependent
global variables in the presence of multi-threaded access. This is true
of all sequentially consistent architectures.
Checking whether we could use this fast path (if
`G_ATOMIC_OP_MEMORY_BARRIER_NEEDED` was *not* defined) was a bit of a
pain, though, as it required GLib to know the memory consistency model
of every architecture. This kind of knowledge is traditionally a
compiler’s domain.
So, simplify the fast path by using the compiler-provided atomic
intrinsics, and acquire-release memory consistency semantics, if they
are available. If they’re not available, fall back to always locking as
before.
We definitely need to use `__ATOMIC_ACQUIRE` in the macro implementation
of g_once(). We don’t actually need to make the `__ATOMIC_RELEASE`
changes in `gthread.c` though, since locking and unlocking a mutex
guarantees to insert a full compiler and hardware memory barrier
(enforcing sequential consistency). So the `__ATOMIC_RELEASE` changes
are only in there to make it obvious what stores are logically meant to
match up with the `__ATOMIC_ACQUIRE` loads in `gthread.h`.
Notably, only the second store (and the first load) has to be atomic.
i.e. When storing `once->retval` and `once->status`, the first store is
normal and the second is atomic. This is because the writes have a
happens-before relationship, and all (atomic or non-atomic) writes
which happen-before an atomic store/release are visible in the thread
doing an atomic load/acquire on the same atomic variable, once that load
is complete.
References:
* https://preshing.com/20120913/acquire-and-release-semantics/
* https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/_005f_005fatomic-Builtins.html
* https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
* https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1323
There were multi-threaded tests for g_once_init_{enter,leave}(), but not
for g_once(). Add one which tests multi-threaded contention for entering
and retrieving the value of the `GOnce`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1323
It’s not expected that bindings will use `GThread` over their own
threading APIs (in fact that would generally be a bad idea, since
threads benefit from being integrated into language control flow
structures), but it can’t hurt to have the annotations right for
documentation purposes if nothing else.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #602
Unify the creation of GPtrArray.
Maybe we will add yet another constructor for creating %NULL terminated
arrays. Unify the constructors by adding an internal helper method.
The alternative instead of adding a ptr_array_new() helper, would be to
let everybody call g_ptr_array_full(). For no strong reasons, choose
this approach because the compiler is more eager to inline the static
helper as it would inlining g_ptr_array_full().
This reverts commit c0146be3a4.
The revert was originally added because the original change broke
gnome-build-meta. Now that the problem has been diagnosed, the original
commit can be fixed — see the commit which follows this one.
See: !1487
The public functions exposed as static inlines currently don't have
annotations to describe when they were introduced. This means that
compiling this file:
#include <glib.h>
void foo (void)
{
g_rec_mutex_locker_new (NULL);
}
with:
gcc -c test.c \
-I/tmp/glib/include/glib-2.0 \
-I/tmp/glib/lib/x86_64-linux-gnu/glib-2.0/include \
-Werror \
-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_28 \
-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_28
will not produce any error message, despite using
`g_rec_mutex_locker_new`, a function that was introduced after 2.28.
This patch adds some annotations to all the publicly exposed static
inline functions I could find.
I could not use the existing G_AVAILABLE* macros, because they may
expand to `extern`. This would then clash with the `static` keyword and
produce:
../glib/gthread.h:397:1: error: multiple storage classes in declaration specifiers
397 | static inline GRecMutexLocker *
| ^~~~~~
So I opted for adding a new set of macros,
GLIB_AVAILABLE_STATIC_INLINE_IN_2_XY.
With this patch applied, the example from above produces the expected
warning:
test.c: In function ‘foo’:
test.c:5:3: error: ‘g_rec_mutex_locker_new’ is deprecated: Not available before 2.60 [-Werror=deprecated-declarations]
5 | g_rec_mutex_locker_new (NULL);
| ^~~~~~~~~~~~~~~~~~~~~~
In file included from /tmp/glib/include/glib-2.0/glib/gasyncqueue.h:32,
from /tmp/glib/include/glib-2.0/glib.h:32,
from test.c:1:
/tmp/glib/include/glib-2.0/glib/gthread.h:398:1: note: declared here
398 | g_rec_mutex_locker_new (GRecMutex *rec_mutex)
| ^~~~~~~~~~~~~~~~~~~~~~
This seems to have existed since the code was written and I can’t see
a need for it.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2106
g_ptr_array_extend_and_steal() leaves the GPtrArray in an invalid state,
so if you would try to append another pointer, it leads to a crash.
Also adjust the test case so that it would result in the crash (without
the fix).
Fixes: 0675703af0 ('Adding g_ptr_array_extend_and_steal() function to glib/garray.c')
With a trivial file that just includes glib.h:
#include <glib.h>
Compiled with:
gcc -c test.c \
-I /tmp/glib/include/glib-2.0/ \
-I /tmp/glib/lib/x86_64-linux-gnu/glib-2.0/include \
-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_28 \
-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_28 \
-fmax-errors=1 \
-Werror
We get:
In file included from /tmp/glib/include/glib-2.0/glib/gasyncqueue.h:32,
from /tmp/glib/include/glib-2.0/glib.h:32,
from test.c:1:
/tmp/glib/include/glib-2.0/glib/gthread.h: In function ‘g_rec_mutex_locker_new’:
/tmp/glib/include/glib-2.0/glib/gthread.h:396:3: error: ‘g_rec_mutex_lock’ is deprecated: Not available before 2.32 [-Werror=deprecated-declarations]
396 | g_rec_mutex_lock (rec_mutex);
| ^~~~~~~~~~~~~~~~
/tmp/glib/include/glib-2.0/glib/gthread.h:196:17: note: declared here
196 | void g_rec_mutex_lock (GRecMutex *rec_mutex);
| ^~~~~~~~~~~~~~~~
compilation terminated due to -fmax-errors=1.
The problem is that the code in the static inline functions uses
g_rec_mutex_lock, introduced after 2.28. This code is compiled
regardless of if it's actually used or not.
Suppress the warning by using G_GNUC_BEGIN_IGNORE_DEPRECATIONS /
G_GNUC_END_IGNORE_DEPRECATIONS. There are precedents for doing that,
for example g_main_context_pusher_new in gmain.h.
Tested by building with all variations of GLIB_VERSION_MIN_REQUIRED /
GLIB_VERSION_MAX_ALLOWED:
for i in $(seq 26 2 64); do
gcc -c test.c \
-I/tmp/glib/include/glib-2.0 \
-I/tmp/glib/lib/x86_64-linux-gnu/glib-2.0/include \
-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_$i \
-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_$i \
-fmax-errors=1 \
-Werror
done
Fixes: #2094
Otherwise the code ends up calling `gettext ("")`, which returns the
current translation’s header. The caller should really have provided a
NULL, parameter string, but the empty string is clear enough.
See
https://gitlab.freedesktop.org/accountsservice/accountsservice/-/merge_requests/56.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When g_variant_get_child() is called on a variant which has not been
serialized, it serializes it which includes a call to
g_variant_release_children() and therefore means that any children
previously retrieved from the variant are no longer valid (unless
another reference is held on them) and consequently values borrowed from
those children are no longer safe to access. Add a note to the
g_variant_get_child_value() documentation to explain this.
Alternatively, we could say that after the child is freed, values
borrowed from it are no longer valid. But we already have an
implementation which hasn't changed in years which lets them stay valid
if the variant was serialized before the first
g_variant_get_child_value() call.
Here's a demonstration of the memory error:
static const char *get_first_child (GVariant *v) {
g_autoptr(GVariant) child_v = g_variant_get_child_value (v, 0);
return g_variant_get_string (child_v, NULL);
}
int main(int argc, char **argv) {
g_autoptr(GVariant) v = g_variant_new("(@ss)", g_variant_new_string ("hello"), "world");
const char *child1 = get_first_child (v);
const char *child2;
g_variant_get_child (v, 1, "&s", &child2);
printf ("%s\n", child1); // this is a memory error
return 0;
}
The local change from af0e0cb995 in glib ended upstreamed
as 7359c5fd9f312cddd62146896558d8c9bd2bd4cf in valgrind, with
a few minor adjustments requested from there.
Sync this local modification to what ended up upstreamed, to avoid
any doubt regarding it for future syncs of the whole header.
The gnulib math code uses __builtin_isnanf and __builtin_isnanl
within the __GNUC__ >= 4 ifdef, and clang doesn't provide those
builtins, only the one without a suffix. Make the meson check
match the code it controls, using the exactly right builtins.
Set REPLACE_ISNAN to 1 if either of the have_isnan* functions failed,
this matches how gnulib's m4 routines does it (in gnulib/m4/isnan.m4).
This fixes the isnan functions in the gnulib math header replacement
work on Clang.
Many locales have no concept of AM/PM notation, and it’s confusing to
them. It’s an Anglo-centric concept which doesn’t belong in the API at
this level — instead, programs should use more generic format specifiers
which leave the details of how to format a date/time to the locale.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2082
Meson 0.54.0 added a new method meson.override_dependency() that must be
used to ensure dependency consistency. This patch ensures a project that
depends on glib will never link to a mix of system and subproject
libraries. It would happen in such cases:
The system has glib 2.40 installed, and a project does:
dependency('glib-2.0', version: '>=2.60',
fallback: ['glib', 'glib_dep'])
dependency('gobject-2.0')
The first call will configure glib subproject because the system libglib
is too old, but the 2nd call will return system libgobject.
By overriding 'gobject-2.0' dependency while configuring glib subproject
during the first call, meson knows that on the 2nd call it must return
the subproject dependency instead of system dependency.
This also has the nice side effect that with Meson >0.54.0 an
application depending on glib can declare the fallback without knowing
the dependency variable name: dependency('glib-2.0', fallback: 'glib').
"\t" is not escaped by g_markup_escape_text(), as per its documentation:
"Note that this function doesn't protect whitespace and line endings
from being processed according to the XML rules for normalization of
line endings and attribute values."
The relevant portion of the XML specification
https://www.w3.org/TR/xml/#AVNormalize
"For a character reference, append the referenced character to the
normalized value."
"For a white space character (#x20, #xD, #xA, #x9), append a space
character (#x20) to the normalized value."
So the unescape code in GMarkup does the right thing as can be verified
by the added valid-17.* data files for the markup-parse unit test.
(Note that the valid-13.* data files already tested a plain tab
character in an attribute value, among other white space characters).
Note that the libxml2's xmlSetProp() function escapes "\t" into the
character reference "	".
See https://gitlab.gnome.org/GNOME/glib/-/issues/2080
Update our copy of valgrind.h from the Valgrind 3.15 release tarball,
and then re-apply our downstream change af0e0cb995. No other
changes made.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
malloc() was given too small value (size of pointer,
rather than struct it points to), and subsequent call
getpwnam_r() wrote past the end of allocated block - easily
seen with valgrind.
Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
Don't assume that __MINGW32__ implies x86; Windows runs on ARM/ARM64
as well, and there are mingw toolchains that target those architectures.
This mirrors how the MSVC part of the same expressions are written,
as (defined(_WIN32) && defined(_M_IX86)) and
(defined(_WIN64) && defined(_M_X64)) - not relying on _WIN32/_WIN64
or __MINGW32__/__MINGW64__ alone to indicate architecture.
The __declspec(dllexport) attribute in itself doesn't imply
'extern' - thus any intended variable declaration with
GLIB_VAR/GOBJECT_VAR would actually be a variable definition. With
C compilers defaulting to -fcommon, this isn't an issue, but
upcoming compilers (GCC 10 and Clang 11) will default to -fno-common,
ending up with duplicate definitions of these variables.
Using commands:
```
glib/gen-unicode-tables.pl -both 13.0.0 path/to/UCD
tests/gen-casefold-txt.py 13.0.0 path/to/UCD/CaseFolding.txt \
> tests/casefold.txt
tests/gen-casemap-txt.py 13.0.0 path/to/UCD/UnicodeData.txt \
path/to/UCD/SpecialCasing.txt > tests/casemap.txt
```
Using UCD release https://www.unicode.org/Public/zipped/13.0.0/UCD.zip
With some manual additions to `GUnicodeScript` for the 4 new scripts
added in 13.0, using the first assigned character in each block in
`glib/tests/unicode.c`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The test checks `g_str_match_string()` function, which performs matches
based on user's locale. For this reason, some tests may fail, e.g., see
issue #868.
Now we explicitly set locale for each test, with C locale as a fallback
when the locale is not available.
clang complains about this in the form of
<source>:6:9: warning: result of comparison against a string literal is
unspecified (use an explicit string comparison function instead)
if (f == (void *)"a") {
^ ~~~~~~~~~~~
Use variables for the strings instead, which should have the same
address.
It seems a bit unhelpful to list every single `g_assert_*()` macro, to
rephrase the documentation to use globs instead.
Add a missing word below.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This is for use in testing POSIX-style functions like `rmdir()`, which
return an integer < 0 on failure, and return their error information in
`errno`.
The new macro prints `errno` and `g_strerror (errno)` on failure.
Includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
`mem-overflow` test disables GCC warning `alloc-size-larger-than` via
diagnostic pragma, but it's still emitted in the linkage stage when
LTO is enabled.
This changes explicitly set `link_args` for the test to disable the
warning.
Some compilers have __GNUC__ defined as a value less than 6, but do
support implicit-fallthrough via __attribute__((fallthrough)). Define
G_GNUC_FALLTHROUGH for those that support __has_attribute.
Spotted by Mohammed Sadiq. `g_array_copy()` was doing a `memcpy()` of
the data from the old array to the new one, based on the reserved
elements in the old array (`array->alloc`). However, the new array was
allocated based on the *assigned* elements in the old array
(`array->len`).
So if the old array had fewer assigned elements than allocated elements,
`memcpy()` would fall off the end of the newly allocated data block.
This was particularly obvious when the old array had no assigned
elements, as the new array’s data pointer would be `NULL`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2049
Most of these scripts can probably just be deleted (see issue #2045),
but for now it was easier to just mechanically fix the shellcheck
warnings in them, rather than think about whether we actually needed the
script.
Fixes done using shellcheck 0.7.0 with default options. I haven’t tested
any of the changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Move the separate function inline using g_once_init_{enter,leave}(),
rather than g_once().
This marginally improves performance, taking 0.39s to create 10000000
UTC timezones, rather than 0.43s previously. (Who cares?)
Follow-up to !1105.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It’s quite surprising that this wasn’t documented already. Hash tables
are unordered, and any recognisable iteration ordering is not guaranteed
and might change in future releases.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Instead only do a g_critical(). This is something that has to be fixed
one way or another, but a g_critical() is less disruptive and makes sure
that code that worked in previous GLib versions still works as bad as
before.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/2039
Some CI platforms invoke these tests with euid != 0 but with
capabilities. Detect whether we have Linux CAP_DAC_OVERRIDE or other
OSs' equivalents, and skip tests that rely on DAC permissions being
denied if we do have that privilege.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2027
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2028
Some CI platforms invoke tests as euid != 0, but with capabilities that
include CAP_SYS_RESOURCE and/or CAP_SYS_ADMIN. If we detect this,
we can't test what happens if our RLIMIT_NPROC is too low to create a
thread, because RLIMIT_NPROC is bypassed in these cases.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/2029
This does not have any behaviour changes but is cleaner. The mutex is
only unlocked now after all operations on the context are done and right
before freeing the mutex and the context itself.
Instead of destroying sources directly while freeing the context, and
potentially freeing them if this was the last reference to them, collect
new references of all sources in a separate list before and at the same
time invalidate their context so that they can't access it anymore. Only
once all sources have their context invalidated, destroy them while
still keeping a reference to them. Once all sources are destroyed we get
rid of the additional references and free them if nothing else keeps a
reference to them anymore.
This fixes a regression introduced by 26056558be in 2012.
The previous code that invalidated the context of each source and then
destroyed it before going to the next source without keeping an
additional reference caused memory leaks or memory corruption depending
on the order of the sources in the sources lists.
If a source was destroyed it might happen that this was the last
reference to this source, and it would then be freed. This would cause
the finalize function to be called, which might destroy and unref
another source and potentially free it. This other source would then
either
- go through the normal free logic and change the intern linked list
between the sources, while other sources that are unreffed as part of
the main context freeing would not. As such the list would be in an
inconsistent state and we might dereference freed memory.
- go through the normal destroy and free logic but because the context
pointer was already invalidated it would simply mark the source as
destroyed without actually removing it from the context. This would
then cause a memory leak because the reference owned by the context is
not freed.
Fixes https://github.com/gtk-rs/glib/issues/583 while still keeping
https://bugzilla.gnome.org/show_bug.cgi?id=661767 fixes.
We first have to ref the next source and then unref the previous one.
This might be the last reference to the previous source, and freeing the
previous source might unref and free the next one which would then leave
use with a dangling pointer here.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/2031
It was used for running tests when we built with autotools, but is no
longer used in the Meson build system. If we need something similar in
future, it should be done by adding internal API to override the
directory on a per-call basis, rather than loading a path from a shared
global table every time.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1919
There were a couple of custom paths which could end up being relative,
rather than absolute, due to not properly prefixing them with
`get_option('prefix')`.
The use of `join_paths()` here correctly drops all path components
before the final absolute path in the list of arguments. So if someone
configures GLib with an absolute path for `gio_module_dir`, that will be
used unprefixed; but if someone configures with a relative path, it will
be prefixed by `get_option('prefix)`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1919
Even if the key already exists in the table, `g_hash_table_add()` will
call the hash table’s key free func on the old key and will then replace
the old key with the newly-passed-in key. So `key` is always `(transfer
full)`.
In particular, `key` should never need to be freed by the caller if
`g_hash_table_add()` returns `FALSE`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Since we (optionally) require nanosecond precision for this
(utimes() is used on *nix), use SetFileTime(), which nominally
has 100ns granularity (actual filesystem might be coarser), instead of
g_utime (), which only has 1-second granularity.
Expand our private statbuf structure with st_mtim, st_atim and st_ctim
fields, which are structs that contain tv_sec and tv_nsec fields,
representing a timestamp with 1-second precision (same value as st_mtime, st_atime
and st_ctime) and a fraction of a second (in nanoseconds) that adds nanosecond
precision to the timestamp.
Because FILEETIME only has 100ns precision, this won't be very precise,
but it's better than nothing.
The private _g_win32_filetime_to_unix_time() function is modified
to also return the nanoseconds-remainder along with the seconds timestamp.
The timestamp struct that we're using is named gtimespec to ensure that
it doesn't clash with any existing timespec structs (MinGW-w64 has one,
MSVC doesn't).
794c1a30bc "macro wrappers for
g_once_init_enter/leave" added this line (whose intent is unclear to me).
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r4.html>
"Deprecating volatile" (scheduled for inclusion in C++20) will make the
assignment expression
*(location) = (result)
deprecated when the LHS is of (non-class) volatile type, which is the case when
g_once_init_leave is expanded as part of e.g. G_DEFINE_TYPE_WITH_CODE (in
gobject/gtype.h), where location is a pointer to some
static volatile gsize g_define_type_id__volatile = 0;
Recent Clang trunk emits -Wdeprecated-volatile for it under -std=c++2a since
<https://github.com/llvm/llvm-project/commit/
4a6861a7e5b59be24a09b8b9782255d028e7aade> "[c++20] P1152R4: warn on any
simple-assignment to a volatile lvalue".
The fix is to make the assignment expression a discared-value expression by
casting it to void (which in turn requires casting the second branch of the
surrounding conditional expression to void, too; not sure what the top-level
cast to void was intended for, and whether it would still be needed under
certain circumstances).
Previously we would only ever run the initialization code once, but part
of it only if a non-exclusive pool was created. This caused the shared
state to be inconsistent if the first pool to be created was exclusive
and the second non-exclusive.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/2012
g_setenv() and g_unsetenv() can never be thread-safe, so emit a message if
they are used after any threads have been spawned.
This can’t catch interactions between setenv() and g_thread_new(), or
between g_setenv() and pthread_create(), but it’ll catch most
misbehaviour in GLib-centric code.
Currently, the message is a `g_debug()` call. Eventually, I’d like to
upgrade it to a `g_warning()`, but there are a number of GLib tests
which call g_setenv() after threads have been created, and they need to
be fixed first. Emitting a `g_debug()` message gives people an
opportunity to start fixing their code.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #715
This will be used in a following commit to warn if setenv() is used
after another thread has been created.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #715
It’s now used unconditionally for `shared_thread_scheduler_settings` in
`gthreadpool.c`, so it actually needs to have a storage definition.
Fixes a build failure on FreeBSD.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
On Linux the sched_getattr syscall might be available at compile-time
but not actually work at runtime (e.g. because an older kernel is
running or valgrind is used). Instead of killing the process, return
FALSE and handle this gracefully at runtime with some fallback code.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/2007
By default (on POSIX) we would be inheriting thread priorities from the
thread that pushed a new task on non-exclusive thread pools and causes a
new thread to be created. This can cause any non-exclusive thread pool
to accidentally contain threads of different priorities, or e.g. threads
with real-time priority.
To prevent this, custom handling for setting the scheduler settings for
Linux and Windows is added and as a fallback for other platforms a new
thread is added that is responsible for spawning threads for
non-exclusive thread pools.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/1834
This means that GLib will generate appropriate deprecation warnings if
`GLIB_VERSION_MAX_ALLOWED` has been set to target a GLib version older
than 2.58.
The timezone(3) man page on Fedora 31 describes the start/end
field in the POSIX TZ format as follows:
[quote]
The start field specifies when daylight saving time goes
into effect and the end field specifies when the change is
made back to standard time. These fields may have the fol‐
lowing formats:
Jn This specifies the Julian day with n between 1 and
365. Leap days are not counted. In this format,
February 29 can't be represented; February 28 is day
59, and March 1 is always day 60.
n This specifies the zero-based Julian day with n
between 0 and 365. February 29 is counted in leap
years.
Mm.w.d This specifies day d (0 <= d <= 6) of week w (1 <= w
<= 5) of month m (1 <= m <= 12). Week 1 is the
first week in which day d occurs and week 5 is the
last week in which day d occurs. Day 0 is a Sunday.
[/quote]
The GTimeZone code does not correctly parse the 'n' syntax,
treating it as having the range 1-365, the same as the 'Jn'
syntax. This is semantically broken as it makes it impossible
to represent the 366th day, which is the purpose of the 'n'
syntax.
There is a code comment saying this was done because the Linux
semantics are different from zOS and BSD. This is not correct,
as GLibC does indeed use the same 0-365 range as other operating
systems. It is believed that the original author was mislead by
a bug in old versions of the Linux libc timezone(3) man pages
which was fixed in
commit 5a554f8e525faa98354c1b95bfe4aca7125a3657
Author: Peter Schiffer <pschiffe@redhat.com>
Date: Sat Mar 24 16:08:10 2012 +1300
tzset.3: Correct description for Julian 'n' date format
The Julian 'n' date format counts atrting from 0, not 1.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
Fixes: #1999
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
The callers of parse_tz_boundary inverted the value passed
for the ignore_leap parameter. Fortunately the method impl
also had an inverted test cancelling out the first bug.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
The implementation has always wrapped at 76 characters, rather than 72,
ever since it was introduced in commit 5cf8f1d4a8 in 2006. At this
stage, it’s probably best to fix the documentation rather than the
implementation.
The likely bug in the implementation is the comparison
```
(++already) >= 19
```
19 × 4 = 76, so it seems like an off-by-one error in the comparison.
What was actually wanted was 18 × 4 = 72.
Thanks to Simon McVittie for the investigation and diagnosis.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1997
Similar to 3837b83f, glibc memcpy is declared with the first two
arguments annotated as non-null via an attribute, which results in the
undefined behaviour sanitizer considering it to be UB to pass a null
pointer there (even if we are copying no bytes, and hence not actually
dereferencing the pointer).
Signed-off-by: Simon McVittie <smcv@collabora.com>
g_atomic_pointer_compare_and_exchange() should work with const pointers.
Add a test for that.
It seems clang 9.0.0-2.fc32 does not like this:
../glib/tests/atomic.c:93:9: warning: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const char **' [-Wincompatible-pointer-types]
res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
../glib/tests/atomic.c:96:9: warning: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const char **' [-Wincompatible-pointer-types]
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
Note that this clang version already issues various compiler warnings for
this test. This merely adds another case to check.
Eventually g_atomic_pointer_compare_and_exchange() should be fixed to
avoid compiler warnings.
Actually there is a problem. When you try to use g_atomic_pointer_compare_and_exchange()
with const pointers, it is also not working, because the implementation
as a function expects "void *" arguments. As the test also shows. As such,
it's probably not portable to use g_atomic_pointer_compare_and_exchange()
with const pointers at all. However, the macro implementation is (with the right
compiler) fine with that, so it's an easy "mistake" to make.
Even if g_variant_get_va(), which we eventually call, checks on the
validity of the value argument, check it early to avoid surprises, such
as this intermittent FreeBSD test failure:
(/var/tmp/gitlab_runner/builds/3fe11159/0/GNOME/glib/_build/gio/tests/gdbus-connection:65788): GLib-CRITICAL **: 15:13:25.670: g_variant_get_va: assertion 'value != NULL' failed
Especially check for a valid reference count. This is possible now in
all cases because of the addition of the dispose function and makes
usage of already finalized/finalizing GSources more obvious than the
use-after-free that would otherwise happen.
This allows GSource implementors to safely clear any other references to
the GSource while the GSource is still valid, unlike when doing the same
from the finalize function.
After the dispose function has run, it is valid for the reference count
of the GSource to be > 0 again to allow the case where another thread in
the mean-time got access to the GSource reference before the dispose
function was called.
This allows fixing a thread-safety issue in the GCancellable, GstBus and
various other GSource implementations.
When compiling a program using glib with -Wzero-as-null-pointer-constant
warnings enabled, the compiler warns about this type check in the
g_once_init_enter macro. Fix by replacing "0" with "NULL".
This is a convenience wrapper around getpwnam_r() which handles all the
memory allocation faff.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1687
Although not quite as often-occurring, this should help with constructs
like this:
if (list)
{
g_list_free_full (list, foo);
list = NULL;
}
Closes https://gitlab.gnome.org/GNOME/glib/issues/1943
In C, the proper type for a heap allocate structure is size_t/gsize.
That means, no valid (heap allocated) pointer will ever contain more
bytes than size_t can represent.
Hence, this integer type should also be used when operating on
data like a strv array. Adjust some internal uses to use gsize
instead of gint/guint.
Note that g_strv_length() returns a value of type guint. So this
API cannot be used on string arrays longer of arbitrary size. But
that is not fixable.
This reverts commit fd3ed5e31b.
C11-style atomics have been fixed (on FreeBSD and other platforms) in
the previous commit, “gatomic: Check argument width in
g_atomic_pointer_compare_and_exchange()”.
See !1229 and #1940.
Check that the new value is actually pointer-width, rather than (for
example) `sizeof (int)` which could happen if someone used `0` rather
than `NULL`.
Changes suggested by Simon McVittie.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1940
Don’t pass integers; it’s not type-safe. The macro version of
`g_atomic_pointer_compare_and_exchange()` used to erroneously accept
integers, but they would have the wrong width on some platforms.
Changes originally investigated and suggested by Ting-Wei Lan.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1940
They’re causing the CI to fail. While someone familiar with FreeBSD
investigates the failure, it’s easiest to disable all C11-style atomics
than add more preprocessor checks to only disable the atomics added in
!1123.
If nobody can fix the new C11-style atomics before the 2.64.0 release,
this commit should be reverted and a more comprehensive set of preprocessor
checks put in place to essentially revert !1123 for BSD only.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1940
In glib/gutf8.c there was an UB in function g_utf8_find_prev_char when
p == str. In this case we substract one from p and now p points to a
location outside of the boundary of str. It's a UB by the standard.
Since this function are meant to be fast, we don't check the boundary
conditions.
Fix glib/tests/utf8-pointer test. It failed due to the UB described
above and aggressive optimisation when -O2 and LTO are enabled. Some
compilers (e.g. GCC with major version >= 8) create an optimised version
of g_utf8_find_prev_char with the first argument fixed and stored
somewhere else (with a different pointer). It can be solved with either
marking str as volatile or creating a copy of str in memory. We choose
the second approach since it's more explicit solution.
Add additional checks to glib/tests/utf8-pointer test.
Closes#1917
Commit 7678b107 seems to have left the GHashTable pretty printer with an
off-by-one error, skipping the first key it encounters and printing an
extra garbage key/value pair instead. This fixes that by moving an
increment to the end of a loop rather than the beginning.
This ensures that when running many instances of the test in parallel,
they don’t collide in the same current directory, and hence spuriously
fail. This can happen when writing `out.xbel`, for example.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1930
In general, we should aim to always check a `GError` before checking a
boolean, since the error message from the `GError` gives us a lot more
information about failure, which helps with debugging.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The time handling was assuming that the test would complete in the same
second as it started, which was not always true.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1930
`g_assert_*()` gives more useful messages on failure, and isn’t compiled
out by `G_DISABLE_ASSERT`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Similar to 3837b83f, glibc memcmp is declared with the first two
arguments annotated as non-null via an attribute, which results in the
undefined behaviour sanitizer considering it to be UB to pass a null
pointer there (even if we are comparing 0 bytes, and hence not actually
dereferencing the pointer).
This shows up in /gvariant/serialiser/children when run with the
undefined behaviour sanitizer.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Similar to 3837b83f, glibc memcmp is declared with the first two
arguments annotated as non-null via an attribute, which results in the
undefined behaviour sanitizer considering it to be UB to pass a null
pointer there (even if we are comparing 0 bytes, and hence not actually
dereferencing the pointer).
This shows up in /gvariant/serialiser/children when run with the
undefined behaviour sanitizer.
Signed-off-by: Simon McVittie <smcv@collabora.com>
kdeinit5 overwrites argv, which in turn results in /proc/self/cmdline
being overwritten. It seems that this is done in a way that does not
necessarily guarantee that /proc/self/cmdline will end up NUL-terminated.
However, g_file_get_contents() is documented to fill a buffer of size
len + 1, where buffer[len] == '\0', even if the file's actual contents
(from buffer[0] to buffer[len-1] inclusive) did not include a NUL;
so we can safely relax this assertion slightly.
Resolves: https://gitlab.gnome.org/GNOME/glib/issues/1923
Signed-off-by: Simon McVittie <smcv@collabora.com>
Change a condition from one to an equivalent one to shut up a
`scan-build` warning about potentially dereferencing a `NULL` value.
This introduces no functional changes, as it’s not actually possible to
dereference a `NULL` value here (but `scan-build` can’t link the
nullability of `error` to the nullability of `result`).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The compiler can’t work out from the combination of other conditions
that it’s not possible for (m2 == NULL) to hold true when memcmp() is
called, so add an explicit condition.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1897
Previously, these GTimeZone objects were being cached in the `time_zones` cache, but dropped from it when their final ref was dropped (which was frequently). That meant additional reads of `/etc/localtime` next time they were created, which was noticeable on profiles. Keep a permanent ref to the UTC and local timezones.
This removes the limitation of select() that only FDs with values lower
than FD_SETSIZE can be used. Previously, if the out/err pipe FDs had
high values (which could happen if a large process, like Firefox, was
spawning subprocesses while having a lot of FDs open), GLib would abort
due to an assertion failure in libc.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #954
glibc declares memcpy() with the first two arguments (the pointers)
annotated as non-null via an attribute, which results in the undefined
behaviour sanitizer considering it to be UB to pass a null pointer
in the second argument, even if we are copying 0 bytes (and hence not
actually dereferencing the pointer).
This shows up in array-test when run with the undefined behaviour
sanitizer.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Note that I deliberately haven't used g_autoptr here, because while we
encourage GLib users to use g_autoptr in their own code, GLib itself
still supports being compiled in environments like MSVC that can't
support g_autoptr.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The user_data for g_ptr_array_sort_with_data is passed directly, not
with an extra layer of pointer like the data pointers.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fixes: 52c130f8
Let's not encourage library users to sprinkle casts through their code
when they don't need to.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Fixes: 52c130f8
This is like `GMutexLocker`, in that if you are able to use
`g_autoptr()`, it makes popping a `GMainContext` off the thread-default
main context stack easier when exiting a function.
A few uses of `G_GNUC_{BEGIN,END}_IGNORE_DEPRECATIONS` are needed to
avoid warnings when building apps against GLib with
`GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_64`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
We may need to declare autocleanups for new types, which will be marked
as ‘deprecated’ if the code which includes GLib doesn’t declare a high
enough `GLIB_VERSION_MAX_ALLOWED`. Despite that, we still need to
declare the autocleanups.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The token parsing done by g_variant_parse() uses recursive function
calls, so at some point it will hit the stack limit. As with previous
changes to `GVariantType` parsing (commit 7c4e6e9fbe), limit the level
of nesting of containers parsed by g_variant_parse() to something
reasonable. We guarantee 64 levels of nesting, which should be enough
for anyone, and is the same as what we guarantee for types.
oss-fuzz#10286
Signed-off-by: Philip Withnall <withnall@endlessm.com>
On closer reading of `man 3 timezone`, it’s actually permissible for
`TZ` to contain an absolute path which points to a tzfile file outside
the system time zone database. This is indeed what happens when building
GLib under Fedora’s toolbox, so relax that check in the tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
There are a lot of Unix-like systems which have not implemented the
os-release spec. On such system, we can use POSIX uname function as a
fallback to get basic information of the system.
/etc/os-release is a spec designed for Linux. While other OSes can
implement it, it doesn't make sense to use Linux as the default value
on systems which don't use Linux.
Most of the info returned is static, the only thing that changes
is the OS version.
This code relies on g_win32_check_windows_version() providing
accurate information (hopefully, MS won't nix RtlGetVersion() on
which we use for that) and supplements it with information from the
registry for Windows >= 8.1.
In many places the pattern
static gboolean warned_once = FALSE;
if (!warned_once)
{
g_warning ("This and that");
warned_once = TRUE;
}
is used to not spam the same warning message over and over again. Add a
helper in glib for this, allowing the above statement to be changed to
g_warning_once ("This and that");
os-release(5) is widely implemented on Linux, but not necessarily
ubiquitous: unusual or minimal Linux distributions might not have it.
It could in principle be implemented by any other Unix OS, but in
practice this has not yet happened.
Closes: https://gitlab.gnome.org/GNOME/glib/issues/1906
Fixes: 349318e8 "gutils: Add g_get_os_info()"
Signed-off-by: Simon McVittie <smcv@collabora.com>
As an unsigned integer, this variable is always greater than or equal to
zero. Fixes a compiler warning on Android.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
There were tests for the situation where it does the exchange and
returns true, but no tests for the situation where it returns false.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Document that g_vasprintf and g_strdup_printf are guaranteed to return a
non-NULL string, unless the format string contains the locale sensitive
conversions %lc or %ls.
Further annotate that the output parameter for g_vasprintf and the
format string for all functions must be non-NULL.
Fixes#1622
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
The g_vasprintf method is called by g_strdup_vprintf, g_strdup_printf,
g_string_append_vprintf and more. It has three different implementations
depending on what the build target platform supports:
1. The gnulib impl appears to use the system malloc, but a
'#define malloc g_malloc' causes it to use GLib's wrapper
and thus abort on OOM. This mostly gets used on Windows
platforms or UNIX platforms with broken printf formatting.
2. The main impl mostly used on modern Linux/UNIX calls the
system vasprintf which uses the system malloc and does not
abort on OOM.
3. The final impl used on remaining platforms calls system
vsprintf on a buffer allocated by g_new, and thus always
aborts on OOM.
Of note is that impl 2 (using vasprintf) historically could abort on
OOM, if the application had installed a non-system malloc impl with
GLib. This was because the code would g_strndup the result from
vasprintf() in that scenario. This was removed in:
commit a366053253
Author: Dan Winship <danw@gnome.org>
Date: Fri Aug 7 09:46:49 2015 -0400
glib: remove deprecated g_mem_is_system_malloc() check in gprintf.c
Having inconsistent OOM behaviour for the three impls is undesirable and
aborting on OOM is normal pratice for GLib APIs. Thus we must thus ensure
this happens in all impls of g_vasprintf.
Fixes#1622
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
These were introducing strict aliasing warnings. Remove them (in line
with other uses of `g_once_init_leave()`).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Casting pointer types around is a bit fiddly when you also end up
dereferencing them. Take advantage of the fact that the
`__atomic_load()` and `__atomic_store()` built-ins are polymorphic, and
use `__typeof__()` to ensure that the atomic pointer macros use the
caller-provided types internally, and hence any type mismatches are
entirely the caller’s fault rather than ours.
This also means that the `__atomic_{load,store}()` built-ins have the
right alignment and width data from the caller-provided types, in case
that’s needed.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Various places that used atomic functions were using the wrong return
type. Fix that. This introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If we're cross-compiling, the installed-tests are useful even if we
can't run them on the build machine: we can copy them to the host
machine (possibly via a distro package like Debian's libglib2.0-tests)
and run them there.
While I'm changing the build-tests condition anyway, deduplicate it.
Based on a patch by Helmut Grohne.
Bug-Debian: https://bugs.debian.org/941509
Signed-off-by: Simon McVittie <smcv@collabora.com>
`man dup2` says that on Linux, dup2() can return `EBUSY` if the
operation needs to be retried (in addition to returning `EINTR` in other
cases where it needs to be retried).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
All uses of fdwalk in gspawn are between fork and exec, which means only
async-signal safe functions can be called if the parent process has
multiple threads. Since fdwalk is not a standard API, we should not
assume it is safe to use unless the manual of the system explicitly says
it is async-signal safe.
Fixes: #1638
See the mailing list thread <https://lists.fedoraproject.org/archives/list/
devel@lists.fedoraproject.org/thread/SZ676IHHSLOQD6UN2I5J5VKXJ5P5SOVO/>
"glib-2.0 G_CONST_RETURN causing GCC 'warning: const' on F31", where the GCC
diagnostic
> test.c:2:13: warning: const
> 2 | G_CONST_RETURN char * f();
> | ^~~~~~~
had confused me, and "Deprecated pre-processor symbol, repace with const" is
probably a better warning message than just "const".
(That recent GCC only prints "Deprecated pre-processor symbol, repace with "
appears to be a bug in GCC that GLIB_UNAVAILABLE_MACRO already suffers from,
too. Recent Clang correctly prints "Deprecated pre-processor symbol, repace
with const".)
Previously we used the old `__sync_fetch_*()` intrinsics for some of the
atomic operations, such as `g_atomic_int_compare_and_exchange()`. When
available, use the new `__atomic_*()` intrinsics for those instead.
As with the rest of our use of `__atomic_*()` intrinsics, we use the
`__ATOMIC_SEQ_CST` memory model. If people want to use a less
restrictive memory model to get better performance in certain
situations, they can use the compiler intrinsics directly themselves.
`g_atomic_*()` aim to be as fast as possible while remaining general
purpose.
Tested using:
```
meson test --repeat 1000 atomic atomic-test
```
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1750
Android is emitting `-Wtautological-constant-out-of-range-compare`
warnings when compiling the validation functions for the enum types for
`GDate`. Fix that by comparing as integers.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It was possible to pass in (for example) an invalid year to
g_date_time_new_week(), which would be passed on to g_date_time_new(),
which would (correctly) return `NULL` — but then
g_date_time_get_week_number() would try to dereference that.
Includes a test case.
oss-fuzz#17648
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If the compiler doesn’t provide modern (C++11) atomic builtins (which is
now quite unlikely), we implement our own using the `__sync_synchronize()`
memory barrier. As Behdad and others have pointed out, though, the
implementation didn’t follow the same semantics as we use with the C++11
builtins — `__ATOMIC_SEQ_CST`.
Fix the use of memory barriers to provide `__ATOMIC_SEQ_CST` semantics.
In particular, this fixes the following common pattern:
```
GObject *obj = my_object_new ();
g_atomic_pointer_set (&shared_ptr, obj);
```
Previously this would have expanded to:
```
GObject *obj = my_object_new ();
*shared_ptr = obj;
__sync_synchronize ();
```
While the compiler would not have reordered the stores to `obj` and
`shared_ptr` within the code on one thread (due to the dependency
between them), the memory system might have made the write to
`shared_ptr` visible to other threads before the write to `obj` — if
they then dereferenced `shared_ptr` before seeing the write to `obj`,
that would be a bug.
Instead, the expansion is now:
```
GObject *obj = my_object_new ();
__sync_synchronize ();
*shared_ptr = obj;
```
This ensures that the write to `obj` is visible to all threads before
any write to `shared_ptr` is visible to any threads. For completeness,
`__sync_synchronize()` is augmented with a compiler barrier to ensure
that no loads/stores can be reordered locally before or after it.
Tested by disabling the C++11 atomic implementation and running:
```
meson test --repeat 1000 atomic atomic-test
```
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1449
`g_assert_*()` provide more useful failure messages, and aren’t compiled
out when building with `G_DISABLE_ASSERT`, unlike `g_assert()`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When compiling GLib with `-Wsign-conversion`, we get various warnings
about the atomic calls. A lot of these were fixed by
3ad375a629, but some remain. Fix them by
adding appropriate casts at the call sites.
Note that `g_atomic_int_{and,or,xor}()` actually all operate on `guint`s
rather than `gint`s (which is what the rest of the `g_atomic_int_*()`
functions operate on). I can’t find any written reasoning for this, but
assume that it’s because signedness is irrelevant when you’re using an
integer as a bit field. It’s unfortunate that they’re named a
`g_atomic_int_*()` rather than `g_atomic_uint_*()` functions.
Tested by compiling GLib as:
```
CFLAGS=-Wsign-conversion jhbuild make -ac |& grep atomic
```
I’m not going to add `-Wsign-conversion` to the set of default warnings
for building GLib, because it mostly produces false positives throughout
the rest of GLib.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1565
Instead of calling close or fcntl on all possible file descriptors,
which is slow on systems with very high limit or even no limit on open
file descriptors, we can use closefrom or fcntl with F_CLOSEM to close
all unwanted file descriptors with a single system call.
This change only improves the performance when GSpawnChildSetupFunc is
NULL because there are applications known to abuse GSpawnChildSetupFunc
to unset FD_CLOEXEC on file descriptors. Since the change mentioned
above requires closing file descriptors directly, it cannot be used when
the caller may want to keep some of them open.
This patch was written by Sebastian Schwarz <seschwar@gmail.com> and
uploaded to https://gitlab.gnome.org/GNOME/glib/merge_requests/574.
It was later modified by Ting-Wei Lan <lantw@src.gnome.org> to address
code review issues.
Fixes: https://gitlab.gnome.org/GNOME/glib/issues/1638
While the introspection scanner can glean the transfer rule for the
return values by looking at their constness, adding an explicit
annotation has the advantage of gtk-doc writing out the transfer rule as
an additional bit of documentation, making the life of the documentation
reader easier.
While the XML specification doesn’t prescribe a limit, no reasonable bit
of XML is going to have more than 1000 attributes in a single XML
element.
Adding a limit reduces the changes of a runaway allocation loop caused
by dodgy input.
oss-fuzz#12960
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It was possible to pass in (for example) an invalid hour to
g_date_time_new_ordinal(), which would be passed on to
g_date_time_new(), which would (correctly) return `NULL` — but then
g_date_time_new_ordinal() would try to dereference that.
Includes some test cases.
oss-fuzz#16103
oss-fuzz#17183
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Support for custom allocators was dropped in
commit 3be6ed60aa
Author: Alexander Larsson <alexl@redhat.com>
Date: Sat Jun 27 18:38:42 2015 +0200
Deprecate and drop support for memory vtables
The introductory doc text for the gmem APIs still warns against mixing
malloc/free with g_malloc/g_free. Clarify upfront in the docs that these
two sets of APIs are now guaranteed to use the same memory allocator &
can thus their usage can be freely mixed.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
g_utf8_get_char_validated() was not exactly matching its
documentation. The function was not checking if the sequence of
unicode characters was free of null bytes before performing a more
in-depth validation.
Fix issue #1052
The static analyser can’t yet work out how `g_autofree` works, so
disable those tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
The macros for the probes confuse the static analyser, and are often
called with arguments which the analyser things shouldn’t be used any
more (for example, the address of a block of memory which has just been
freed).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
These squash various warnings from `scan-build`. None of them are
legitimate bugs, but some of them do improve code readability a bit.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1767
It’s confusing and often doesn’t help the user. Match the error code and
come up with a more UI-appropriate error message.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If the user has `CAP_DAC_OVERRIDE` or similar (for example, if running
the tests as root), the `mkdir-with-parents-permission` test is skipped.
The check for `CAP_DAC_OVERRIDE` was by creating a subdirectory of the
test directory. That subdirectory, however, was never removed, which
caused a ‘directory not empty’ error when trying to delete the test
directory.
Fix that by correctly deleting the subdirectory if skipping the test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
clang will warn with -Wunused-function if the g_autoptr macros are
ever used inside a .c file. This would break a lot of -Werror builds
with clang.
Mark such functions as explicitly unsed so clang will not warn about
them.
However, it's fine to call it when building for the debug target
(which uses the debug CRT and hence sets -D_DEBUG), so let's keep that
around.
The Windows App Certification Kit only runs on apps built in release
mode.
These macros wrap functions which were only introduced in certain
versions of GLib. The functions are correctly marked as introduced in
those versions, but the macros aren’t, which can result in not getting
appropriate deprecation warnings if you’re using those APIs when you
have said you’re targeting older GLib versions using
`GLIB_VERSION_MAX_ALLOWED`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #1860
We require a newer SDK version now, so this is not needed.
Specifically, we set _WIN32_WINNT to 0x0601, which sets our SDK
requirement to Windows 7+, and this code is only needed for MSVC 5.0,
which is ancient.
It’s confusing and often doesn’t help the user. Match the error code and
come up with a more UI-appropriate error message.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If the dup(stderr) returns '-1' (an error occured), then the program
shouldn't call a 'close(stderr); dup(old_err);' after the exec() failed.
Fix issue #1880
A static analysis run noted that we weren't freeing the cmdline in the
error path here. We can just make this an assertion instead; I just
checked the kernel code, and it just usees a seq_printf() here which
will NUL terminate.
This fixes the following warning, by making the compiler checks for the
`pop` match those for the `push`:
```
[221/1124] Compiling C object 'glib/tests/d796b50@@mem-overflow@exe/mem-overflow.c.o'.
../glib/tests/mem-overflow.c:204:24: warning: pragma diagnostic pop could not pop, no matching push [-Wunknown-pragmas]
#pragma GCC diagnostic pop
```
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When g_variant_get_child_value() is called for a child whose
serialisation is an empty byte string (which is possible), `bytes_data`
will be non-`NULL`, but `data` may be `NULL`. This results in a negative
offset being passed to `g_bytes_new_from_bytes()`, and a critical
warning.
So if `data` is `NULL`, set it to point to `bytes_data` so the offset is
calculated as zero. The actual value of the offset doesn’t matter, since
in this situation the size is always zero. An offset of zero is never
going to cause problems.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1865
These are copies of the existing tests for `g_time_val_from_iso8601()`,
with the test strings which fail for `GDateTime` commented out. This is
OK, as it’s documented as only accepting a subset of ISO 8601 (and for
some of the test vectors, it’s debatable whether they’re actually valid
ISO 8601, depending on how you interpret the valid bounds of timezone
offsets — some interpretations of the available documentation would say
that timezone offsets should never be ≥24 hours or ≥60 minutes).
There is one test string which is not accepted by
`g_time_val_from_iso8601()` but which is accepted by `GDateTime`, as
`g_date_time_new_from_iso8601()` actually accepts RFC 3339, which is a
little more liberal than ISO 8601. Fun times. See
https://tools.ietf.org/html/rfc3339#section-5.6.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Some malformed ISO 8601 date/time strings were causing an assertion
failure when passed to `g_date_time_new_from_iso8601()`, due to a
mismatch between the bounds checking of timezone offsets in `GDateTime`
and `GTimeZone`. Fix that and add a unit test for it.
oss-fuzz#16101
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Since we transitioned from Bugzilla to GitLab, we have two forms of bug
references in the GLib source code: old (but still relevant) Bugzilla
links, and newer GitLab links. We can’t use a single base for the two,
so have to either build incorrect URIs, or provide the full URI in
g_test_bug().
It’s always seemed a bit of an over-optimisation to provide the bug base
separately from the bug ID, so relax the assertions and documentation
around g_test_bug_base() so that g_test_bug() can be used on its own.
The old usage patterns are still supported unchanged.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
On x86 (and apparently most other Linux architectures), the union
with the signal handler is the first member, but on MIPS Linux,
the first struct member is sa_flags (possibly done to be compatible
with IRIX). Zero out the struct and fill in the field we want by name.
Signed-off-by: Simon McVittie <smcv@collabora.com>
When using the mingw printf shims for C99 compat the msvc format specifiers don't work
and the build fails.
Ideally we would use glib functions which abstract this away, but in the error handler context
we shouldn't call back into glib. And for scanf we don't have a glib wrapper.
Instead call the "secure" versions provided by the win32 API (_snprintf_s/fprintf_s/sscanf_s)
which mingw doesn't replace.
We currently check in multiple places if vsnprintf/snprintf/printf are
good and if not use gnulib. This case was not checking for printf which
made the build fail with recent mingw-w64 where snprintf was improved to
pass all glib checks but printf still doesn't.
Commit 6f55306e04 unintendedly broke error handling for other
error conditions than ENOENT along the path, like EPERM. It wanted
to ignore ENOENT on all elements except the last in the path, but
in doing that it ignored any other error that might happen on the
last element.
https://gitlab.gnome.org/GNOME/glib/issues/1852
You may expect funny effects from passing invalid UTF-8, but not
that funny. The assert will probably be a better and more immediate
confirmation of an error than invalid writes under the address of the
string copy.
https://gitlab.gnome.org/GNOME/glib/issues/1863
This comment was correct until commit adf1f98f62, when the `GTimeVal`
which the result was put into (introducing the Y2038-unsafety) was
dropped.
The adjustment and scaling of the `FILETIME` should not make it
Y2038-unsafe: the maximum `FILETIME` is 2^64-1. Subtracting the epoch
adjustment and dividing by 10 gives the timestamp 1833029933770955161,
which is in June 58086408216 (at just after 3am UTC). I think that’s
enough time to be going on with.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
This requires some reworking of the internal g_date_time_new_from_unix()
function, since it previously operated in seconds, which wasn’t high
enough resolution — the g_get_current_time() code path used to operate
in microseconds.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
The former is now deprecated, so it makes sense to base its
implementation on the latter, rather than the other way around.
This introduces no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
GTimeVal is subject to the year 2038 problem, since its `tv_sec` field
is a `glong`, which is 32 bits on 32-bit platforms.
Use `guint64` to represent microsecond-precision time since the Unix
epoch; or use `GDateTime` for full date/time representation.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1438
It’s not Y2038-safe, as it’s 32-bit. While it was previously deprecated
in the documentation, now add the deprecation annotation for the
compiler.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
This is a simple wrapper around g_date_time_format_iso8601() which
always produces ISO 8601 dates, without people having to remember the
format string for them (and with the convenience of terminating UTC
dates with ‘Z’ rather than ‘+00’).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
Only redefine g_message() and friends to use structured logging if the
compiling code is OK with depending on GLib functionality from ≥2.56.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1847
Try to create the complete path right away and fall back
to creating all path elements one by one.
This also helps to avoid TOCTTOU problems and avoids walking
the path all the time, providing a nice performance gain, by
avoiding syscalls.
Ignore ENOENT errors up until the last element while trying to create each
of the path elements in case a restricted file-system is being used where
path elements can be hidden or non-accessible.
__atomic_load_8 and friends do not exist under clang. Use the generic
__atomic_load variant instead that are documented here:
https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
These have the additional benefit that the exact size of gint (4 bytes)
or gpointer (4 or 8 bytes) no longer have to be checked.
I initially tried `__typeof__(*(atomic)) val;`, but that caused warnings
in Clang (-Wincompatible-pointer-types-discards-qualifiers) when
"atomic" points to a volatile variable. Aside from that, it is
apparently not supported everywhere, see the g_has_typeof macro.
Another reason not to use it are new warnings under Clang, including:
glib/deprecated/gthread-deprecated.c:683:11: warning: incompatible pointer types initializing 'typeof (*(&mutex->mutex.mutex))' (aka 'union _GMutex *') with an expression of type 'GRecMutex *' (aka 'struct _GRecMutex *') [-Wincompatible-pointer-types]
g_atomic_pointer_set (&mutex->mutex.mutex, result);
Hence, cast the atomic variable to gint/gpointer pointers, the size was
already statically asserted so the cast should be safe.
The macros use a (hopefully) rare "gaps_temp" name instead of something
like "val" to avoid an issue with GCC builds:
glib/tests/once.c:123:test_once4: assertion failed (val == "foo"): (NULL == "foo")
Closes#1843
We're using the `install` argument for configure_file() all over the
place.
The support for an `install` argument for configure_file() was added in
Meson 0.50, but we haven't bumped the minimum version of Meson we
require, yet; which means we're getting compatibility warnings when
using recent versions of Meson, and undefined behaviour when using older
versions.
The configure_file() object defaults to `install: false`, unless an
install directory is used. This means that all instances of an `install`
argument with an explicit `true` or `false` value can be removed,
whereas all instances of `install` with a value determined from a
configuration option must be turned into an explicit conditional.
If searching for an element which is smaller than every element in the
array (i.e. the element being searched for is not in the array), the
previous g_array_binary_search() implementation would underflow in the
calculation `right = middle - 1`, and end up trying to dereference an
element way off the right of the array.
Fix that by checking the additions/subtractions before doing them, and
bailing if the bounds are hit. We don’t need to check `middle <
G_MAXUINT`, as `middle` is bounded above by `right`, which is always `<=
_array->len - 1`, and `_array->len <= G_MAXUINT`.
Add some tests for that, and for not-present elements in the middle of
the array. Previously, the tests only checked for not-present elements
which were bigger than every element in the array.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If `right` and `left` are both near `G_MAXUINT`, it’s possible for the
addition to overflow, even if the eventual result would fit in a
`guint`. Avoid that by operating on the difference instead.
The difference is guaranteed to be positive due to the prior `left <=
right` check.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The allocation size was set correctly before, but not the array length,
so the copied array appeared to have zero elements.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
We need to enable building the dirent and gnulib sources for clang-cl,
as we are still using the Microsoft-style headers and lib's and CRT.
We need to also do this for the following, for similar reasoning:
-Symbol export (via __declspec(dllexport))
-Dependency discovery without pkg-config files
-long long and ssize_t detection
We do, however, enable the autoptr tests for clang-cl builds. Note that
at this point real MSVC builds are still better supported than clang-cl
builds, and it will likely remain so for at least the near future,
alhtough real MSVC builds of the GTK stack are consumable and are usable
by clang-cl.
Use the GCC-style definition for the deprecation warning macros so that
builds using those won't break due to how they are placed as clang-cl
seems to not support __declspec(deprecated) very well. Also make sure
that we do indeed support the temparary disabling of deprecation
warnings on clang-cl, as the MSVC ones don't really work on clang-cl.
clang-cl does support __attribute__((cleanup)), which is what is used
for the g_auto* macros, but neither it, nor clang.exe defines __GNUC__
when they are used in a MSVC cmd.exe environment. It does, however,
define __clang__.
So, check for the presence of the __clang__ macro to enable g_autoptr as
well, so that we can build things with MSVC builds that make use
of g_autoptr via pretending to be MSVC by using clang-cl.
Windows does not recognize the "America/Recife" as a valid timezone
identifier, so setting the TZ envvar to that will result in "UTC" to
be returned on Windows.
Instead, set TZ to be the Windows equivilant "SA Eastern Standard
Time", and see whether that is indeed our identifier when we create the
GTimeZone using that.
On Windows, we may be using the US DST boundaries by using the default
"Pacific Standard Time" for rules_from_windows_time_zone() in
rules_from_identifier(). This has the unfortunate side-effect of
hardcoding the out_identifier to "Pacific Standard Time", which is
likely not what we want.
Instead, upon retrieving the items successfully using
rules_from_windows_time_zone ("Pacific Standard Time", ...), we just
set the out_identifier to whatever identifier that was passed into
rules_from_identifier().
Update the gdatetime test program to make use of the updates that was
done in gtimezone.c in the previous commit, so that we don't have to
worry what language version of Windows the tests are being run in, but
instead be assured that we produce and check for the English-language
time zone name strings.
Also, instead of testing for "Pacific Standard Time" in
test_GDAteTime_printf(), use GetDynamicTimeZoneInformation() to get the
actual time zone string (where the system running the test program is)
we want to check for, because on Windows the actual result will be
dependent on which timezone the system running the test program is in.
https://bugzilla.gnome.org/show_bug.cgi?id=719344
The existing method of using RegQueryValueExW() to query the Std/Dlt
strings can only retrive the localized versions of those strings, so
that means they will vary by the language version of Windows. Instead,
use RegQueryValueExW() only as a fallback when RegLoadMUIStringW() fails,
as RegLoadMUIStringW() can query for the Std and Dlt strings in
whatever language we need by setting the locale stuff programatically on
the fly.
We are going to use RegLoadMUIStringW() in the next commit, since there
is no real RegLoadMUIStringA() function (it exists as a stub only).
This is done so that we are consistent along the way
Also fix rule_from_windows_time_zone_info() as we can't just do a strncpy()
of tzi->StandardName and tzi->DaylightName directly, as they are wchar_t/
gunichar2 strings, where we must convert to UTF-8 first.
https://bugzilla.gnome.org/show_bug.cgi?id=719344
We said the type must support being cleaned up and will be cleaned up in
an appropriate way, but in order to figure out how to do that, you had
to jump forward in the documentation to the other macros. Just say them.
This is a follow-up to a0c7f85437.
In addition LC_MESSAGES, we should remove LC_ALL from the environment
as well. Otherwise, LC_ALL overrides LC_MESSAGES, causing the test to
fail on FreeBSD when LC_ALL is set to a non-English locale.
This (dubious) testcase fails before the previous commit due to errno
being clobbered by the interrupted wait on the contended mutex. The
previous commit fixes that.
The testcase is dubious because, in theory (as per POSIX),
g_cond_wait_until() is permitted to return TRUE at any time for any
reason, due to so-called "spurious wakeups". Having a testcase that
asserts that the return value should be FALSE is therefore fundamentally
broken. We do it anyway, though.
We're only really trying to test a bug in our homemade Linux/futex
implementation here, and it takes a fair amount of effort to actually
convince the old code to fail (including some system stuff which
probably isn't available on Windows). There's also the spurious wakeup
situation mentioned above to worry about on other systems. For all of
those reasons, this test is only enabled on Linux.
The return value from `g_cond_wait_until()` is calculated, based on the
value of `errno` after reacquiring the mutex. This is a problem because
`errno` can be overwritten in the case the mutex is contended (in which
case the slow-path code will re-enter the kernel).
Perform the calculation before reacquiring the mutex.
See merge request GNOME/glib!958
Visual Studio 2010 and later support static_assert on both C and C++,
but we can only enable it for plain-C code on Visual Studio 2013 and
later, as apparently the static_assert macro implementation will carry
out something after defining certain variables.
For C++ code, we use static_assert on Visual Studio 2010 and later.
The return value for g_utf8_normalize may be null, but the return type
is not annotated as such. This is important for language bindings for
langs that are about nullability, such as Vala and Haskell.
g_test_trap_fork() is deprecated, but it’s still tested in the GLib
tests. If we don’t set the coredump rlimit to 0 to prevent coredumps,
the test for it creates a coredump (which is expected). On systems with
systemd-coredump, that causes systemd-coredump to spawn and process the
coredump for a while. That slows down the tests, and results in spurious
coredump lists in the system logs.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #436
The static assert message is much nicer to read, and is less likely to
be misinterpreted as a false positive.
glib is built with `-std=gnu89`, but this macro will be available to
projects that use glib with c11 or gnu11.
It is unclear that why the size of the buffer was chosen to be 100
because the commit introduced the code didn't mention the reason.
POSIX defines _POSIX_HOST_NAME_MAX to be 255 and provides a way to
determine the suitable value with sysconf, so we should use it instead
of hard-coding a small value.
The g_creat() call was done in *nix style in regards to the mode parameter,
which the Windows CRT isn't going to understand (nor like, on newer CRTs).
Update the program such that it will pass, by using Windows-style
permission mode parameters for g_creat(), on Windows.
On Windows, everything is assumed as UTF-8 in g_get_filename_charsets(),
so setting G_FILENAME_ENCODING envvar has no effect, so we can just skip
the test on g_get_filename_charsets() where we try to influence it by
setting the G_FILENAME_ENCODING envvar.
On Windows, in particular the CRTs on and after Visual Studio 2012, it
is not enough just to do setlocale (LC_ALL, "") to set the default
system locale, which results in the tools that use the translated
messages to show unreadable messages when running the commmand line
tools.
This adds an entry in glib-private.h.in which denotes the appropriate
string to use for setlocale() to set the default system locale by
setting it to ".ACP" if we are building on Windows and "" for
other systems (as we are doing now).
The tools in gio/ will be updated in the next commit to make use of this
entry so that the translated messages can be shown correctly.
From grefcount.h, in order to disable warnings when G_DISABLE_CHECKS is
defined, we need to make use of the GCC-isque-only __extension__ for it
to work. This means that in the saturation tests, we can only expect no
warnings to show if we are building on GCC-isque compilers with
G_DISABLE_CHECKS defined.
This will fix the refcount-macro test on Visual Studio builds at least.
The variable types for the PID (bp) and event (be) are accidentally
reversed in the test program. Correct their types so that tests do not
fail on Visual Studio x64 builds.
Fixes issue #1797
In !863 I assumed that a 4 byte wchar_t would be equal to gunichar on all platforms,
but this is not the case for FreeBSD. It previously was using the non wchar_t based API
because it doesn't define __STDC_ISO_10646__.
Add back the __STDC_ISO_10646__ check again and introduce a more meaningful macro for guarding
the code paths that are mixing gunichar and wchar_t.
Fixes#1798
It’s already documented elsewhere, but not particularly obviously.
Clarify argument encodings in the GOptionArg documentation.
As reported on StackOverflow:
https://stackoverflow.com/q/56416098/2931197.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The documentation erroneously said that a thread calling
g_rw_lock_reader_lock() would always block if another thread was waiting
for the write lock. That’s not true: if no thread holds the lock, it is
implementation defined which of a waiting reader and writer gets the
lock.
See
http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_rwlock_rdlock.html.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #590
These have all been documented as deprecated for a long time, but we’ve
never had a way to programmatically mark them as deprecated. Do that
now.
This is based on the list of deprecations from the reverted commit
80fcb1bc2.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #638
This code uses, or tests, deprecated functions, types or macros; so
needs to be compiled with deprecation warnings disabled.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Use the new `GLIB_DEPRECATED_{TYPE,ENUMERATOR}*` macros to annotate types
and enumerators as deprecated, rather than using `G_DISABLE_DEPRECATED`.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The definitions weren’t templated in glibconfig.h.in at all, so didn’t
vary between configurations of GLib — so they should be in a normal
header.
Move them to gutils.h and fix the deprecation annotations.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This allows the symbols there to be used conditionally, depending on the
user’s stated `GLIB_VERSION_MIN_REQUIRED` and `GLIB_VERSION_MAX_ALLOWED`
preferences.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
When defining deprecated macros, annotate them with
`GLIB_DEPRECATED_MACRO_IN_*()` and `GLIB_DEPRECATED_MACRO_IN_*_FOR()` to
conditionally emit warnings if people use them, depending on their
declared minimum and maximum GLib version requirements (see
`GLIB_VERSION_MIN_REQUIRED` and `GLIB_VERSION_MAX_ALLOWED`).
The old way of doing this was for users to define `G_DISABLE_DEPRECATED`
if they didn’t want to use deprecated APIs, but it reported errors via
missing symbols, and wasn’t version-dependent. It’s being phased out.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
These will be used to annotate deprecated macros, types and enumerators.
`GLIB_DEPRECATED_MACRO{,_FOR}` are based very heavily on the
corresponding macros from Clutter, written by Emmanuele Bassi.
The other deprecation annotators use the standard annotations supported
by Clang and GCC. They need to be separated as they are supported in
different versions of the compilers.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1060
This makes it easier to maintain the documentation and code at the same
time. The documentation comments haven’t been modified.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Queries the charset used by the associated console, which does not
necessarily match the charset of the current locale as returned by
g_get_charset.
Fixes https://gitlab.gnome.org/GNOME/glib/issues/1270
As we discovered in GNOME/gtk#1280, GCC considers the pragmas to control
the deprecation warnings as statements. This means we cannot just use
the GLib wrappers as markers around the call site, but we must be aware
of their side effects.
Let's document this, to avoid falling into the trap.
The code in gunicollate uses __STDC_ISO_10646__ to check that wchar.h is avilable,
that it includes the wide character related functions and that sizeof(wchar_t) == 4.
cygwin defines __STDC_ISO_10646__ and has sizeof(wchar_t) == 2 and the C standard text isn't
that clear on whether wchar_t should always be 4 bytes in this case, so we better not use if for
assuming the size here.
Instead of relying on __STDC_ISO_10646__ add HAVE_WCHAR_H and SIZEOF_WCHAR_T macros.
With HAVE_WCHAR_H defined we assume wchar_t exists and wchar.h exists. With SIZEOF_WCHAR_T we
guard the parts where the size of wchar_t is assumed to be 4 (currently all of them).
Note that this doesn't make the collate tests pass under cygwin, they fail before and after this patch for me.
See !755 for related discussions.
This is a new function along the same lines as g_test_bug(): to allow
developers to annotate unit tests with information about the test (what
it tests, how it tests it) for future developers to read and learn from.
It will also output this summary as a comment in the test’s TAP output,
which might clarify test results.
Includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1450
Factor out the code for setting up the hash table size, mask and mod,
detecting valgrind and allocating the arrays for hashes, keys, and
values.
Make use of this new function from g_hash_table_remove_all_nodes().
The handling of have_big_keys and have_big_values was never correct in
this function because it reallocated the array without changing the
flags in the struct. Any calls in to the hashtable from destroy
notifies would find the table in an inconsistent state.
Many thanks to Thomas Haller who is essentially responsible for all the
real work in this patch: both discovering and identifying the original
problem, as well as finding the solution to it.
Make it clear that there is a reference transfer going on here, rather
than relying on the fields being overwritten on each branch of the
conditional below.
We were calling g_hash_table_set_shift() to reinitialise the hash table
even in the case of destroying it. Only do that for the non-destruction
case, and fill the relevant fields with zeros for the destruction case.
This has a nice side effect of causing more certain crashes in case of
invalid reuse of the table after (or during) destruction.
The changes introduced by 18745ff674 made
the comment at the top of g_hash_table_remove_all_nodes() no longer
correct. Fix that inaccuracy and add more documentation all-around.
g_hash_table_new_full() had an invocation of
g_hash_table_realloc_key_or_value_array() with the @is_big argument
incorrectly hardcoded to FALSE, even though later in the function the
values of have_big_keys and have_big_values would be set conditionally.
This never caused problems before because on 64bit platforms, this would
result in the allocation of a guint-sized array (which would be fine, as
have_big_keys and have_big_values would always start out as false) and
on 32bit platforms, this function ignored the value and always allocated
a gpointer-sized array.
Since merge request GNOME/glib!845 we have the possibility for
have_big_keys and have_big_values to start out as TRUE on 64bit
platforms. We need to make sure we pass the argument through correctly.
For some reasons, the buffer used in the Format struct was not long
enough on Windows-x64 and the final null ('\0') character was omitted
leading to a limited memory disclosure.
Valgrind can't find 64bit pointers when we pack them into an array of
32bit values. Disable this optimisation if we detect that we are
running under valgrind.
Fixes#1749
Only disable TAP output if the `--GTestLogFD` argument is passed to the
test, which is passed in by the (deprecated) gtester harness, and
shouldn’t ever have been passed in by anything else.
Also disable it when running a subprocess, using `--GTestSubprocess`,
since users commonly strictly check the stdout and stderr of test
subprocesses.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1619
Add warnings about their deprecation everywhere. The tools will continue
to work until we break API, but will be less well maintained. You should
use TAP for communicating test results to the test harness provided by
your build system or CI system instead.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1441
Update the abbreviated month name in the test to match the actual
translation. Otherwise the test fails with false positive.
Vocabulary:
July (nominative) - Greek: Ιούλιος (abbreviated: Ιούλ)
Of July (genitive) - Greek: Ιουλίου (abbreviated: Ιουλ)
This is similar to commit 4d215e006e
and commit 7fe793e125.
Closes#1776
This clarifies the meaning a bit. Don’t change the logic associated with
it. Add a few comments to clarify things further.
Based on work done by Emmanuel Fleury.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #77
It gives clearer failure messages, and won’t get compiled out when
building with G_DISABLE_ASSERT.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
The documentation has marked it as deprecated for a long time, but not
in a structured way. Use the gtk-doc ‘Deprecated’ tag to mark it as
deprecated.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Helps: #1438
queue->tail->next cannot be non-NULL, as pushing onto the end of the
queue is handled by the call to g_queue_push_tail_link() above.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This makes it a bit clearer that we expect the queue to be empty as a
result of calling g_queue_clear_full(), rather than as a result of any
of the later cleanup.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This makes the g_list_insert_before() follow more closely the guidelines
for GLib, which is to avoid implicit pointer boolean value and to prefer
for over while to improve readability.
This adds two new helpers that allow for inserting pre-allocated GList
elements to the queue similar to existing helpers. This may be advantagous
in some situations such as statically allocated GList elements.
The GHashTable code ignores the duplicated-branches GCC warning, but we
need to do a compiler and version check, as either non-GCC compatible
compilers, or older versions of GCC will warn about the unknown pragma
or diagnostic.
If we don't do this while turning warnings into error, we're going to
fail the build unnecessarily.
Apparently, the documentation of g_strcanon() was not really cristal
clear, so this new code sample try to make it clear the fact that we
are working on the given string and not a copy. Moreover, it provides
a way to keep the original string at once.
Fix#29
Using --GTestSkipCount 0 is the same as omitting it. A skip count
greater than the number of tests is the same as equalling the number
of tests: they are all skipped.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The -p option is documented, and can be used to select and repeat
test-cases. This is particularly useful when debugging a single
failure among a large number of test-cases, or when debugging a
test-case that you suspect influences another test-case by leaking
global state.
Until now, -p was only supported with GLib's default (GLib-specific)
textual output format, and not with the standardized TAP format that
we are now encouraging. If we are considering making TAP the new default
(see glib#1619) it should get feature-equivalence with the current
default.
Because -p allows test-cases to be re-ordered and repeated, and an entry
in the test_paths list can match any number of test-cases (including
zero), we don't know ahead of time how many test-cases we are going to
run. TAP allows the "plan" to be deferred to the end, exactly to support
situations like this.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The undocumented --GTestSkipCount option is internal to the deprecated
gtester tool and rather obscure, but it's straightforward to support
by making G_TEST_LOG_SKIP_CASE produce TAP output similar to what already
happened when we emitted G_TEST_LOG_STOP_CASE with result
G_TEST_RUN_SKIPPED. I might as well do that while I'm looking at the
interaction between the --tap, -p and -s options.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Using commands:
glib/gen-unicode-tables.pl -both 12.0.0 path/to/UCD
tests/gen-casefold-txt.py 12.0.0 path/to/UCD/CaseFolding.txt \
> tests/casefold.txt
tests/gen-casemap-txt.py 12.0.0 path/to/UCD/UnicodeData.txt \
path/to/UCD/SpecialCasing.txt > tests/casemap.txt
plus some manual additions of the new G_UNICODE_SCRIPT_* symbols to
gunicode.h, guniprop.c and glib/tests/unicode.c.
Using UCD release https://www.unicode.org/Public/zipped/12.0.0/UCD.zip.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1713
This reverts commit 9f75cc9edf.
It breaks usage of G_STRFUNC when compiling applications with
`-Wpedantic` — `__func__` is not `#define`d, so G_STRFUNC was falling
through to using `__FUNCTION__`, which raises a warning with
`-Wpedantic`.
Fun times.
Fixes: #1755
Since out-of-source-tree builds are now used after switching to meson,
we don't need .gitignore files in the source directories to ignore
build artifacts.
This fixes build errors when doing a meson build after an autotools
build, because generated files such as gio/xdp-dbus.c won't show up in
a `git status`, or be removed by a `git clean -f`, and so it won't be
obvious that such files need to be removed for the meson build to
succeed.
Currently, there is no way to prevent tests from building using meson.
When cross-compiling, building the tests isn't necessary.
Instead, only build the tests on the following conditions:
1) If not cross-compiling.
2) If cross-compiling, and there is an exe wrapper.
Commit 398008da added a W32-only code (from commit 7e0e251a)
to g_get_prgname() that makes this function never return NULL. This
is inconsistent with the other platforms. Revert the change, and add an
implementation for platform_get_argv0(), which is used by GOption when
g_get_prgname() == NULL.
The W32 platform_get_argv0() code is different from the one that was in
g_get_prgname(), because it should be getting argv0, not the name
of the executable that is being run (although most of the time they are
one and the same).
Adjust thest option-argv0 test to expect it to pass on W32.
There are now C99 functions that the printf items want to use that may
not be necessarily supported by the math.h that is shipped by the
compiler, such as signbit(), isinf(), isnan() and isfinite() and their
double, long and float counterparts.
This checks for whether these functions are provided by the math.h
shipped by the compiler, and builds the gnulib implementations of them
if they cannot be found. Currently no attempt is made to check whether
these, if available from the compiler's math.h, are compliant with the
specs.
The test programs for those in the Meson build files will not work for
Visual Studio prior to 2013 (whereas the rest of the code does).
Improve the tests for these by:
-Adding a test to see whether we can re-define a prototype for these
functions, using cc.compiles(). If so, set HAVE_DECL_xxxx to be 0,
otherwise set HAVE_DECL_xxxx to be 1.
Also, for glib/gnulib/frexpl.c, don't undefine frexpl on Visual Studio,
otherwise we will not be able to compile/link it on Visual Studio
compilers.
To avoid potential regression in feature check that configures
`HAVE_PROC_SELF_CMDLINE` treat test failures on Linux as fatal.
This restores behaviour from before 4c038a27ff.
Instead of hardcoding /proc/self/cmdline use for __linux__ only,
do a configure-time test for it.
Specifically, this enables /proc/self/cmdline use on Cygwin.
The configure-time test is very primitive (just tests that the
file exists and that it's possible to read more than one byte from it),
relying on the testsuite for more extensive checks.
The test in the testsuite is modified to always run, even on platforms
where it isn't supposed to pass. If it fails there, the testing framework
skips it. If the test unexpectedly passes, that is reported too.
It can return NULL if no program name has been set yet (i.e.
g_set_prgname() has not been called from somewhere).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
In file included from glib/glibconfig.h:9,
from glib/gslice.c:20:
glib/gslice.c: In function ‘magazine_cache_trim’:
glib/gmacros.h:354:25: error: comparison of unsigned expression < 0 is always false [-Werror=type-limits]
#define ABS(a) (((a) < 0) ? -(a) : (a))
^
glib/gslice.c:643:10: note: in expansion of macro ‘ABS’
while (ABS (stamp - magazine_chain_uint_stamp (current)) >= allocator->config.working_set_msecs)
^~~
glib/gvariant-parser.c: In function ‘number_get_value’:
glib/gvariant-parser.c:1924:46: error: operand of ?: changes signedness from ‘int’ to ‘guint64’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
return g_variant_new_int16 (negative ? -((gint16) abs_val) : abs_val);
^~~~~~~~~~~~~~~~~~~
glib/gvariant-parser.c:1934:46: error: operand of ?: changes signedness from ‘int’ to ‘guint64’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
return g_variant_new_int32 (negative ? -((gint32) abs_val) : abs_val);
^~~~~~~~~~~~~~~~~~~
glib/gvariant-parser.c:1944:46: error: operand of ?: changes signedness from ‘long int’ to ‘guint64’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
return g_variant_new_int64 (negative ? -((gint64) abs_val) : abs_val);
^~~~~~~~~~~~~~~~~~~
glib/gvariant-parser.c:1954:47: error: operand of ?: changes signedness from ‘int’ to ‘guint64’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
return g_variant_new_handle (negative ? -((gint32) abs_val) : abs_val);
^~~~~~~~~~~~~~~~~~~
glib/gvariant-parser.c: In function ‘g_variant_parse_error_print_context’:
glib/gvariant-parser.c:2785:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘size_t’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (point >= strlen (source_str))
^~
glib/gvariant.c: In function ‘g_variant_new_strv’:
glib/gvariant.c:1563:17: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘long int’} [-Werror=sign-compare]
for (i = 0; i < length; i++)
^
glib/gvariant.c: In function ‘g_variant_new_objv’:
glib/gvariant.c:1699:17: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘long int’} [-Werror=sign-compare]
for (i = 0; i < length; i++)
^
glib/gvariant.c: In function ‘g_variant_new_bytestring_array’:
glib/gvariant.c:1939:17: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘long int’} [-Werror=sign-compare]
for (i = 0; i < length; i++)
^
glib/gvariant-core.c: In function ‘g_variant_ensure_size’:
glib/gvariant-core.c:339:19: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘long int’ [-Werror=sign-compare]
if (value->size == (gssize) -1)
^~
^~~
glib/giounix.c:111:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/gprintf.h:21,
from glib/gstdio.h:22,
from glib/giounix.c:43:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gatomic.h:27,
from glib/gthread.h:32,
from glib/gthread-posix.c:42:
glib/gthread-posix.c: In function ‘g_system_thread_new’:
glib/gmacros.h:348:26: error: comparison of integer expressions of different signedness: ‘long int’ and ‘gulong’ {aka ‘long unsigned int’} [-Werror=sign-compare]
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
^
glib/gthread-posix.c:1169:22: note: in expansion of macro ‘MAX’
stack_size = MAX (min_stack_size, stack_size);
^~~
glib/gmacros.h:348:35: error: operand of ?: changes signedness from ‘long int’ to ‘gulong’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
^~~
glib/gthread-posix.c:1169:22: note: in expansion of macro ‘MAX’
stack_size = MAX (min_stack_size, stack_size);
^~~
glib/gtester.c: In function ‘main’:
glib/gtester.c:705:19: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’ [-Werror=sign-compare]
for (ui = 1; ui < argc; ui++)
^
glib/glib-unix.c:314:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/glib-unix.h:33,
from glib/glib-unix.c:29:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function ‘g_string_insert_len’:
glib/gstring.c:441:31: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:441:5: note: in expansion of macro ‘g_return_val_if_fail’
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:458:15: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (pos < string->len)
^
glib/gstring.c:462:18: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘long int’} [-Werror=sign-compare]
if (offset < pos)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gmacros.h:351:26: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘long unsigned int’ [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^
glib/gstring.c:464:22: note: in expansion of macro ‘MIN’
precount = MIN (len, pos - offset);
^~~
glib/gmacros.h:351:35: error: operand of ?: changes signedness from ‘gssize’ {aka ‘long int’} to ‘long unsigned int’ due to unsignedness of other operand [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^~~
glib/gstring.c:464:22: note: in expansion of macro ‘MIN’
precount = MIN (len, pos - offset);
^~~
glib/gstring.c:469:15: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (len > precount)
^
glib/gstring.c:481:15: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function ‘g_string_insert_c’:
glib/gstring.c:782:31: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:782:5: note: in expansion of macro ‘g_return_val_if_fail’
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:785:11: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function ‘g_string_insert_unichar’:
glib/gstring.c:857:31: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:857:5: note: in expansion of macro ‘g_return_val_if_fail’
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:860:11: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (pos < string->len)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gstring.h:32,
from glib/gstring.c:37:
glib/gstring.c: In function ‘g_string_erase’:
glib/gstring.c:969:29: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_return_val_if_fail (pos <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:969:3: note: in expansion of macro ‘g_return_val_if_fail’
g_return_val_if_fail (pos <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:975:39: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_return_val_if_fail (pos + len <= string->len, string);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gstring.c:975:7: note: in expansion of macro ‘g_return_val_if_fail’
g_return_val_if_fail (pos + len <= string->len, string);
^~~~~~~~~~~~~~~~~~~~
glib/gstring.c:977:21: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (pos + len < string->len)
^
glib/gtimezone.c: In function ‘g_time_zone_unref’:
glib/gtimezone.c:241:29: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (idx = 0; idx < tz->t_info->len; idx++)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gtimezone.h:27,
from glib/gtimezone.c:24:
glib/gtimezone.c: In function ‘init_zone_from_iana_info’:
glib/gtimezone.c:578:34: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
g_assert (trans.info_index < gtz->t_info->len);
^
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gtimezone.c:578:7: note: in expansion of macro ‘g_assert’
g_assert (trans.info_index < gtz->t_info->len);
^~~~~~~~
glib/gtimezone.c: In function ‘find_relative_date’:
glib/gtimezone.c:859:22: error: comparison of integer expressions of different signedness: ‘GDateWeekday’ {aka ‘enum <anonymous>’} and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
if (first_wday > wday)
^
glib/gtimezone.c: In function ‘init_zone_from_rules’:
glib/gtimezone.c:938:19: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’ [-Werror=sign-compare]
for (ri = 0; ri < rules_num - 1; ri++)
^
glib/gtimezone.c:958:19: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’ [-Werror=sign-compare]
for (ri = 0; ri < rules_num - 1; ri++)
^
glib/gtimezone.c: In function ‘g_time_zone_adjust_time’:
glib/gtimezone.c:1792:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (i = 0; i <= intervals; i++)
^~
glib/gtimezone.c:1825:39: error: comparison of integer expressions of different signedness: ‘gboolean’ {aka ‘int’} and ‘GTimeType’ {aka ‘enum <anonymous>’} [-Werror=sign-compare]
else if (interval_isdst (tz, i) != type)
^~
glib/gtimezone.c:1832:22: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
else if (i < intervals &&
^
glib/gtimezone.c: In function ‘g_time_zone_find_interval’:
glib/gtimezone.c:1881:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (i = 0; i <= intervals; i++)
^~
glib/gtimezone.c:1900:35: error: comparison of integer expressions of different signedness: ‘gboolean’ {aka ‘int’} and ‘GTimeType’ {aka ‘enum <anonymous>’} [-Werror=sign-compare]
else if (interval_isdst (tz, i) != type)
^~
glib/gtimezone.c:1905:18: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
else if (i < intervals && time_ >= interval_local_start (tz, i + 1))
^
glib/gtestutils.c: In function ‘g_test_build_filename_va’:
glib/gtestutils.c:3865:49: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’ [-Werror=sign-compare]
for (num_path_segments = 2; num_path_segments < G_N_ELEMENTS (pathv); num_path_segments++)
^
glib/gthreadpool.c: In function ‘g_thread_pool_wait_for_new_pool’:
glib/gthreadpool.c:157:46: error: comparison of integer expressions of different signedness: ‘int’ and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
if (g_atomic_int_get (&unused_threads) >= local_max_unused_threads)
^~
glib/gthreadpool.c: In function ‘g_thread_pool_wakeup_and_stop_all’:
glib/gthreadpool.c:836:17: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
for (i = 0; i < pool->num_threads; i++)
^
This reverts commit 80fcb1bc26.
G_DISABLE_DEPRECATED should never be used by anybody, least of all by
GLib. We have deprecation annotations for the compiler, these days, and
they are much better suited than a macro that makes symbols appear and
disappear. The fact that gtk-doc doesn't understand the deprecation
annotations is a limitation of gtk-doc, and it's gtk-doc that ought to be
fixed.
Commit 80fcb1bc broke GStreamer, which disables old API that was
deprecated before the introduction of the deprecation annotations, but
still uses newly deprecated one, and relies on the deprecation
annotations to do their thing. It also broke libsoup, as it uses
GValueArray in its own API.
glib/gstrfuncs.c: In function ‘g_strstr_len’:
glib/gstrfuncs.c:2709:24: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (haystack_len < needle_len)
^
glib/gmain.c:480:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/glib-unix.h:33,
from glib/gmain.c:50:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
glib/gmain.c:491:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/glib-unix.h:33,
from glib/gmain.c:50:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
glib/gmain.c:499:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/glib-unix.h:33,
from glib/gmain.c:50:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
glib/gmain.c:507:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’} [-Werror=missing-field-initializers]
};
^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/glib-unix.h:33,
from glib/gmain.c:50:
glib/gmain.h:262:19: note: ‘closure_callback’ declared here
GSourceFunc closure_callback;
^~~~~~~~~~~~~~~~
glib/gmain.c: In function ‘g_source_set_callback_indirect’:
glib/gmain.c:1615:68: error: suggest braces around empty body in an ‘if’ statement [-Werror=empty-body]
callback_funcs->get));
^
glib/gscanner.c:344:1: error: missing initializer for field ‘padding_dummy’ of ‘GScannerConfig’ {aka ‘const struct _GScannerConfig’} [-Werror=missing-field-initializers]
};
^
In file included from glib/gscanner.c:40:
glib/gscanner.h:166:10: note: ‘padding_dummy’ declared here
guint padding_dummy;
^~~~~~~~~~~~~
glib/goption.c: In function ‘context_has_h_entry’:
glib/goption.c:785:21: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
for (i = 0; i < context->main_group->n_entries; i++)
^
glib/goption.c:797:21: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
for (i = 0; i < group->n_entries; i++)
^
In file included from glib/glibconfig.h:9,
from ../glib.git/glib/gtypes.h:32,
from ../glib.git/glib/gquark.h:32,
from ../glib.git/glib/gerror.h:28,
from ../glib.git/glib/gmarkup.h:28,
from ../glib.git/glib/gmarkup.c:28:
../glib.git/glib/gmarkup.c: In function ‘unescape_gstring_inplace’:
../glib.git/glib/gmarkup.c:789:30: error: comparison of integer expressions of different signedness: ‘long int’ and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_assert (to - string->str <= string->len);
^~
../glib.git/glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
../glib.git/glib/gmarkup.c:789:3: note: in expansion of macro ‘g_assert’
g_assert (to - string->str <= string->len);
^~~~~~~~
../glib.git/glib/gmarkup.c:790:24: error: comparison of integer expressions of different signedness: ‘long int’ and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (to - string->str != string->len)
^~
../glib.git/glib/gmarkup.c: In function ‘g_markup_parse_boolean’:
../glib.git/glib/gmarkup.c:2634:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Werror=sign-compare]
for (i = 0; i < G_N_ELEMENTS (falses); i++)
^
../glib.git/glib/gmarkup.c:2645:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Werror=sign-compare]
for (i = 0; i < G_N_ELEMENTS (trues); i++)
^
glib/gquark.c: In function ‘g_quark_to_string’:
glib/gquark.c:268:13: error: comparison of integer expressions of different signedness: ‘GQuark’ {aka ‘unsigned int’} and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
if (quark < seq_id)
^
glib/gprimes.c: In function ‘g_spaced_primes_closest’:
glib/gprimes.c:91:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’ [-Werror=sign-compare]
for (i = 0; i < G_N_ELEMENTS (g_primes); i++)
^
glib/gmappedfile.c: In function ‘mapped_file_new_from_fd’:
glib/gmappedfile.c:153:18: error: comparison of integer expressions of different signedness: ‘__off_t’ {aka ‘long int’} and ‘long unsigned int’ [-Werror=sign-compare]
if (st.st_size > G_MAXSIZE)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gquark.h:32,
from glib/gerror.h:28,
from glib/gconvert.h:32,
from glib/giochannel.h:32,
from glib/giochannel.c:37:
glib/giochannel.c: In function ‘g_io_channel_write_chars’:
glib/gmacros.h:351:26: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘long int’} [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^
glib/giochannel.c:2285:31: note: in expansion of macro ‘MIN’
gssize write_this = MIN (space_in_buf, count - wrote_bytes);
^~~
glib/gmacros.h:351:41: error: operand of ?: changes signedness from ‘gssize’ {aka ‘long int’} to ‘gsize’ {aka ‘long unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^~~
glib/giochannel.c:2285:31: note: in expansion of macro ‘MIN’
gssize write_this = MIN (space_in_buf, count - wrote_bytes);
^~~
glib/giochannel.c:2415:41: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘long int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
g_assert (count == from_buf_len - from_buf_old_len);
^~
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/giochannel.c:2415:25: note: in expansion of macro ‘g_assert’
g_assert (count == from_buf_len - from_buf_old_len);
^~~~~~~~
It would be nice if docs.c eventually went away — it’s more maintainable
for documentation comments to be next to the definition of the symbols
they document.
Move a few from docs.c, based on what I’ve been modifying recently.
The documentation comments are unchanged apart from fixing an argument
name for G_ALIGNOF.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
As pointed out by gtk-doc, these are all symbols which have been marked
as deprecated, but which aren’t protected by a deprecation guard. We
can’t use G_DEPRECATED_IN_* for them, as they are all non-function
symbols. Instead, wrap them in #ifndef G_DISABLE_DEPRECATED.
In some cases, we also need to wrap one or two functions which use the
deprecated types in G_DISABLE_DEPRECATED too.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It isn't always obvious how and where to use these. Where possible I've
chosen real examples from GLib, preferring simple examples that
developers considering using these macros have hopefully already seen.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Both GCC and Clang treat this as a hint that the code won’t be reached,
which helps in the cases where they might not have automatically
detected it already.
It doesn’t change any behaviour of the compiled code, other than
allowing the compiler to go off into undefined behaviour.
See
https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005funreachable.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
g_assert_*() give more informative failure messages, and aren’t compiled
out when building with G_DISABLE_ASSERT.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
g_assert_*() give more informative failure messages, and aren’t compiled
out when building with G_DISABLE_ASSERT.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
g_assert_*() give more informative failure messages, and aren’t compiled
out when building with G_DISABLE_ASSERT.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
g_assert_*() give more informative failure messages, and aren’t compiled
out when building with G_DISABLE_ASSERT.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
In order to allow GLib itself to be built with G_DISABLE_ASSERT defined,
we need to explicitly undefine it when building the tests, otherwise
g_test_init() turns into an abort.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1708
Move them next to their definitions, so they’re more likely to be kept
up to date.
This doesn’t modify any of the documentation comments at all.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Any function which requires g_quark_init() to have been called first
cannot be called before the library constructors have finished running.
In particular, this means that g_quark_from_static_string() or
g_intern_static_string() can’t be used to initialize C++ globals.
Do this, rather than adding a conditional call to g_quark_init() to all
these functions, because such a call was previously removed from the
functions to improve performance (quarks are used a lot in the
implementation of GObject for properties and signals). That’s the reason
why g_quark_init() was originally moved out to a library constructor.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1177
One test is for _g_win32_subst_pid_and_event().
Two tests for crashing with different exceptions (access violation
and illegal instruction).
And one test for running a debugger.
Install a Vectored Exception Handler[0]. Its sole purpose is to catch
some exceptions (access violations, stack overflows, illegal
instructions and debug breaks - by default, but it can be made to catch
any exception for which a code is known) and run a debugger in response.
This allows W32 glib applications to be run without a debugger,
but at the same time allows a debugger to be attached in case
something happens.
The debugger is run with a new console, unless an environment variable
is set to allow it to inherit the console of the crashing process.
The short list of handleable exceptions is there to ensure that
this handler won't run a debugger to "handle" utility exceptions,
such as the one that is used to communicate thread names to a debugger.
The handler is installed to be called last, and shouldn't interfere
with any user-installed handlers.
There's nothing fancy about the way it runs a debugger (it doesn't even
support unicode in paths), and it deliberately avoids using glib code.
The handler will also print a bit of information about the exception
that it caught, and even more information for well-known exceptions,
such as access violation.
The whole scheme is similar to AeDebug[1] and, in fact, the signal-event
gdb command was originally implemented for this very purpose.
[0]: https://docs.microsoft.com/en-us/windows/desktop/debug/vectored-exception-handling
[1]: https://docs.microsoft.com/en-us/windows/desktop/debug/configuring-automatic-debugging
At that point in the code, len can only be 0, 1 or 2. The code below is
a no-op if (len == 0), so the condition is pointless.
Remove it, and we should be able to achieve full branch coverage of
gbase64.c.
This should introduce no functional changes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
While I’m here, we might as well check that we output what the RFC says
we should output.
https://tools.ietf.org/html/rfc4648#section-10
(We do.)
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Relax a precondition in g_base64_encode_step() to allow this. It’s valid
to base64 encode an empty string, as per RFC 4648.
Similarly for g_base64_decode(), although calling it with a NULL string
has never been allowed. Instead, clarify the case of calling it with an
empty string.
This includes a unit test.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1698
The caller needs to check this themselves in any case, so we might as
well at least follow convention in defining the precondition.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Previously pattern_coalesce incorrectly concluded that maybe type is not
present when one pattern starts with `M` and other pattern with anything
else than `M` or `m`. This is false when the other pattern is `*`, since
it includes the maybe type.
It's necessary sometimes for installed tests to be able to run with a
custom environment. For example, the gsocketclient-slow test requires an
LD_PRELOADed library to provide a slow connect() (this is to be added in
a followup commit).
Introduce a variable `@env@` into the installed test template, which we
can override as necessary when generating `.test` files, to run tests
prefixed with `/usr/bin/env <LIST OF VARIABLES>`.
As the only test that requires this currently lives in `gio/tests/`, we
are only hooking this up for that directory right now. If other tests in
future require this treatment, then the support can be extended at that
point.
The g_string_insert_len method accepts '-1' for its len parameter,
as a shorthand for strlen(val). Likewise the various convenience
wrappers around it also accept -1. This was not documented, leaving
developers to wonder why len is a gssize, instead of gsize.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
When parsing GVariant text format strings, we do a limited form of type
inference. The algorithm for type inference for nested array child types
is not complete, however (and making it complete, at least with a naive
implementation, would make it O(N^2), which is not worth it) and so some
text format arrays were triggering an assertion failure in the error
handling code.
Fix that by making the error handling code a little more relaxed, in the
knowledge that our type inference algorithm is not complete. See the
comment added to the code.
This includes a test case, provided by oss-fuzz.
oss-fuzz#11578
Signed-off-by: Philip Withnall <withnall@endlessm.com>
And add tests.
There wasn’t actually a bug on x86_64 before, but it was making use of
undefined behaviour, and hence triggering ubsan warnings. Make the code
more explicit, and avoid undefined behaviour.
oss-fuzz#12686
Signed-off-by: Philip Withnall <withnall@endlessm.com>
__func__ is part of the C99 standard.
__FUNCTION__ is another name for __func__. Older versions of GCC
recognize only this name. However, it is not standardized.
For maximum portability, Its recommended to use __func__.
__PRETTY_FUNCTION__ is yet another name for __func__. However, in C++,
__PRETTY_FUNCTION__ contains the type signature of the function as
well as its bare name
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.htmlhttps://gitlab.gnome.org/GNOME/glib/issues/535
This uses newer methods that support more folders such as Downloads. The
Objective-C code is in a separate file, gosxutils.m.
Based on !85 by Patrick Griffis.
They were changed in 6a2cfde2 to reuse the G_MAXINT values but
parsing nexted macros is currently broken in g-i and results in wrong
values.
Add value annotations for g-i to override the values.
This also moves the annotations to the macro definitions to have
everything g-i uses in one place.
This code was a persistent source of `-fsanitize=thread` errors
when I was trying to use it on OSTree.
The problem is that while I think this code is functionally correct,
we hold a mutex during the writes, but not the reads, and TSAN (IMO
correctly) flags that.
Reading this, I don't see a reason we need a mutex at all. At the
cost of some small code duplication between posix/win32, we can just
pass the data we need down into each implementation. This ends up
being notably cleaner I think than the awkward "lock/unlock to
serialize" dance.
(Minor review changes made by Philip Withnall <withnall@endlessm.com>.)
https://gitlab.gnome.org/GNOME/glib/issues/1224
glib/deprecated/gthread-deprecated.c: In function ‘g_static_rec_mutex_init’:
glib/deprecated/gthread-deprecated.c:657:3: error: missing initializer for field ‘depth’ of ‘GStaticRecMutex’ {aka ‘const struct _GStaticRecMutex’} [-Werror=missing-field-initializers]
static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
^~~~~~
In file included from glib/deprecated/gthread-deprecated.c:30:
glib/deprecated/gthread.h:161:9: note: ‘depth’ declared here
guint depth;
^~~~~
glib/garray.c: In function ‘g_ptr_array_insert’:
glib/garray.c:1522:14: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’} [-Werror=sign-compare]
if (index_ < rarray->len)
^
glib/gdatetime.c: In function ‘get_iso8601_int’:
glib/gdatetime.c:1142:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
for (i = 0; i < length; i++)
^
glib/gdatetime.c: In function ‘get_iso8601_seconds’:
glib/gdatetime.c:1175:9: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
if (i == length)
^~
glib/gdatetime.c:1178:12: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
for (; i < length; i++)
^
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/gtimezone.h:27,
from glib/gdatetime.h:31,
from glib/gdatetime.c:62:
glib/gdatetime.c: In function ‘initialize_alt_digits’:
glib/gdatetime.c:2806:27: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘long int’ [-Werror=sign-compare]
g_assert (digit_len < buffer + sizeof (buffer) - buffer_end);
^
glib/gmacros.h:455:25: note: in definition of macro ‘G_LIKELY’
#define G_LIKELY(expr) (expr)
^~~~
glib/gdatetime.c:2806:7: note: in expansion of macro ‘g_assert’
g_assert (digit_len < buffer + sizeof (buffer) - buffer_end);
^~~~~~~~
glib/gchecksum.c: In function ‘digest_to_string’:
glib/gchecksum.c:186:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘gsize’ {aka ‘long unsigned int’} [-Werror=sign-compare]
for (i = 0; i < digest_len; i++)
^
glib/gdataset.c: In function ‘g_datalist_clear_i’:
glib/gdataset.c:233:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint32’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (i = 0; i < data->len; i++)
^
glib/gdataset.c: In function ‘g_datalist_clear’:
glib/gdataset.c:270:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint32’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (i = 0; i < data->len; i++)
^
glib/gdataset.c: In function ‘g_datalist_foreach’:
glib/gdataset.c:1147:21: error: comparison of integer expressions of different signedness: ‘int’ and ‘guint32’ {aka ‘unsigned int’} [-Werror=sign-compare]
for (j = 0; j < d->len; j++)
^
../glib.git/glib/garray.c: In function ‘g_ptr_array_maybe_expand’:
../glib.git/glib/garray.c:1172:43: error: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘gint’ {aka ‘int’} [-Werror=sign-compare]
if G_UNLIKELY ((G_MAXUINT - array->len) < len)
../glib.git/glib/gtester.c: In function ‘sindent’:
../glib.git/glib/gmacros.h:351:26: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘int’ [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^
../glib.git/glib/gtester.c:73:7: note: in expansion of macro ‘MIN’
n = MIN (n, l);
^~~
../glib.git/glib/gmacros.h:351:41: error: operand of ?: changes signedness from ‘int’ to ‘guint’ {aka ‘unsigned int’} due to unsignedness of other operand [-Werror=sign-compare]
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
^~~
../glib.git/glib/gtester.c:73:7: note: in expansion of macro ‘MIN’
n = MIN (n, l);
^~~
We must use the platform specific method to create an IO channel
out of an fd. The test still does not work on Windows but
this is a step forward in the direction to make it work.
Rather than prefixing unsigned numbers with unary minus operators and
expecting the implicit cast to carry the correct value through, add an
explicit cast to a signed type before the unary minus is applied.
In all four cases, an overflow check has already been done.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1655
The subprocess needs to access the test_log_fd. If the file descriptors
are not left open, functions such as g_test_message may stomp on file
descriptors open by the subprocess and cause bad behavior of the test.
(Tweaked by Philip Withnall <bugzilla@tecnocode.co.uk> to fix review
comments.)
In C++ we can use nullptr to ensure g_assert_[non]null() is only called
with pointers. This will introduce build failures in tests that would
have previously compiled, but only in C++, and only for code that
misused these macros. Code using the macros properly will be fine.
This change caught a couple bugs in WebKit's API tests, where I had
accidentally used these functions improperly. E.g. this is now a build
failure in C++:
g_assert_null(webkit_context_menu_get_n_items(menu)); /* Oops! */
Either I wanted to use cmpuint there, or I wanted to use
webkit_context_menu_get_items() to receive a GList* instead.
Another example that will no longer build in C++:
g_assert_null(0); /* Contrived, but 0 is not a pointer! */
So long, and thanks for everything. We’re a Meson-only shop now.
glib-2-58 will remain the last stable GLib release series which is
buildable using autotools.
We continue to install autoconf macros for autotools-using projects
which depend on GLib; they are stable API.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
We’re about to drop autotools support. Rather than keep the .mk files
around in master indefinitely, link to the versions in the glib-2-58
branch (the last stable release of GLib which supports building with
autotools) in readiness for dropping the .mk files from master.
Any future fixes to these files can happen on the glib-2-58 branch. The
links should work forever (as long as we use GitLab).
Signed-off-by: Philip Withnall <withnall@endlessm.com>
We don’t actually build this; the Makefile was just there to allow
ad-hoc regeneration of the glib-mirroring-tab output files.
Port it to Meson just so there are no remnants of GNU make left in GLib.
Don’t hook it up to the rest of the build.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
But it can't be used as a drop-in implementation of G_GNUC_NORETURN
because it can only be placed at the start of the function prototype.
Document this in a comment so that the next person doesn't spend
20 min figuring it out.
This is a wrapper around g_private_set() which allocates the desired
amount of memory for the caller and calls g_private_set() on it.
This is intended to make it easier to suppress Valgrind warnings about
leaked memory, since g_private_set() is typically used to make one-time
per-thread allocations. We can now just add a blanket suppression rule
for any allocations inside g_private_set_alloc0().
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This is a new polling method allowing to poll more than 64 handles
based on the glib one.
When we reach the limit of 64 we create a thread and we poll
on that thread for a batch of handles this way we overcome the limit.
https://gitlab.gnome.org/GNOME/glib/issues/1071
According to msdn documentation last backslash(es) of quoted argument
in a win32 cmdline need to be escaped, since they are
directly preceding quote in the resulting string:
https://docs.microsoft.com/en-us/cpp/c-language/parsing-c-command-line-arguments
Glib <=2.58.0 passed children arguments like C:\Program Files\
without escaping last backslash(es).
So it had been passed as "C:\Program Files\"
windows command line parsing treated this as escaped quote,
and later text was treated as argument continuation instead of separate
arguments.
Existing implementation wasn't easily adoptable to fix this problem,
so escaping logic was rewritten.
Since the resulting length need to be increased due to extra escaping
it was rewritten too. Now the calculated length assumes that all
escapable chars would be escaped in a resulting string,
so the length may be a bit bigger than actually needed,
since backslashes not preceding quotes are not escaped.
This fixes the glib/tests/spawn-singlethread.c test
(which introduced testing for special chars to make this problem
testable).
The problem itself was found during investigations about fixing
related https://gitlab.gnome.org/GNOME/glib/issues/1566
The logic is duplicated in protect_argv_string() and protect_wargv() funcs.
However there is no single obvious way to get rid of duplication -
https://gitlab.gnome.org/GNOME/glib/merge_requests/419#note_371483
So by now adding a note referencing protect_wargv from protect_argv_string,
the other direction is already referenced.
This fixes test that were added in previous commit:
checking for empty stderr failed with coverage enabled, since
coverage warnings printed from gspawn-win32-helper process were treated
as child output. This is fixed by removing redirection after child
finishes execution.
The dup_noninherited renamed to reopen_noninherited,
since it actually always closes passed file descriptor.
Problem was just a typo - wrong variable was checked before enabling
stderr redirection.
This fixes error-only redirection spawn-test added in previous commit.
Behavior while redirecting only stdout should be unaffected,
since old code tried to redirect stderr to -1 in such case,
which silently failed I think.
The existing singlethread g_spawn_sync test is modified and now tests
that special characters in arguments are correctly passed to child.
The test is added before spawn escaping fixing on win32
and covers the case currently broken on win32:
'trailing \ in argument containing space'.
It has different semantics from _Alignof and our G_STRUCT_OFFSET
fallback. See the comments in the diff for details.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1055
We need stronger alignment guarantees for the memory allocations done
through g_rc_box_alloc_full(): while the passed block size may be
aligned, we're not aligning the private data size; this means the
overall allocation may become unaligned, and this could raise issues
when we use the private data size as an offset to access the reference
count.
Fixes: #1581
It’s not possible for g_build_home_dir() to return NULL. The fallback
code here seems to originate from commit 1607e3f1 in 2005 (bug 169348),
where it was added with the explanation “Guard against g_home_dir being
NULL”.
The XDG Base Directory specification doesn’t have anything to say about
what to do when $HOME is unset:
https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
It’s all a bit moot, though, becaause since commit 9cbfb560
(bug 773435), g_{get,build}_home_dir() cannot return NULL. So just drop
the fallback.
See discussion on
https://gitlab.gnome.org/GNOME/glib/merge_requests/505#note_386109.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Otherwise we can have problems calling g_get_home_dir() from within a
g_build_*_dir() function elsewhere in gutils.c:
• There will be a deadlock due to trying to recursively acquire the
g_utils_global lock.
• A stale g_home_dir value may be used if a test harness has called
g_set_user_dirs() in the interim.
Fix that by splitting the code to find/construct the home path out of
g_get_home_dir() into g_build_home_dir(), the same way it’s split for
the other g_get_*() functions. Call g_build_home_dir() from any call
site where the g_utils_global lock is held.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Add a new G_TEST_OPTIONS_ISOLATE_XDG_DIRS option for g_test_init() which
automatically creates a temporary set of XDG directories, and a
temporary home directory, and overrides the g_get_user_data_dir() (etc.)
functions for the duration of the unit test with the temporary values.
This is intended to better isolate unit tests from the user’s actual
data and home directory. It works with g_test_subprocess(), but does not
work with subprocesses spawned manually by the test — each unit test’s
code will need to be amended to correctly set the XDG_* environment
variables in the environment of any spawned subprocess.
“Why not solve that by setting the XDG environment variables for the
whole unit test process tree?” I hear you say. Setting environment
variables is not thread safe and they would need to be re-set for each
unit test, once worker threads have potentially been spawned.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
Add a new internal function, g_set_user_dirs(), which will safely
override the values returned by g_get_user_data_dir() and friends, and
the value returned by g_get_home_dir().
This is intended to be used by unit tests, and will be hooked up to them
in a following commit.
This can be called as many times as needed by the current process. It’s
thread-safe. It does not modify the environment, so none of the changes
are propagated to any subsequently spawned subprocesses.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
While it is currently OK to read the global variables backing functions
like g_get_user_data_dir() without the g_utils_global lock held (since
such a read is always preceeded by a critical section where the variable
is set to its final value), upcoming changes will allow those variables
to be changed. If they are changed from one thread while another thread
is calling (for example) g_get_user_data_dir(), the final read from the
second thread could race with the first thread.
Avoid that by only reading the global variables with the lock held.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
While this might seem like a regression, it means that the home
directory can be overridden by GLib internal code, which will be done in
an upcoming commit. This brings g_get_home_dir() inline with functions
like g_get_user_data_dir().
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
In order to make some guarantees in an upcoming commit that test path
components won’t clash with file system names used by GLib, add a
restriction that test path components cannot start with a dot.
This is an API break, but one which anyone is unlikely to have hit. If
it is an issue, we can relax the restriction to be a warning.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
Seems a bit odd to have the documentation comment miles from what it’s
actually documenting.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
Split out the code which calculates each XDG variable value from the
code which caches it, so that GLib can internally recalculate the
variables if needed, without necessarily trashing the user-visible
cache.
This will be useful in a following commit to add support for explicitly
reloading the variables.
This commit necessarily reworks how g_get_user_runtime_dir() is
structured, since it was inexplicably structured differently from (but
equivalently to) the other XDG variable functions.
Future refactoring could easily share a lot more code between these
g_build_*() functions.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/538
This is a utility function which I find myself writing in a number of
places. Mostly in unit tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
On non-systemd Gentoo systems the chosen timezone is expressed in
/etc/timezone and /etc/localtime may be a copy of the timezone
file instead of symlink. Add this path to the fallback test to
not regress dates into UTC.
This is along the same lines as g_assert_cmpstr(), but for variants.
Based on a patch by Guillaume Desmottes.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://gitlab.gnome.org/GNOME/glib/issues/1191
Use macro name that doesn't conflict with string literal encoding prefix `U`.
```
../glib/tests/fileutils.c(282): warning C4133: 'function': incompatible types - from 'unsigned int [2]' to 'const gchar *'
../glib/tests/fileutils.c(284): warning C4133: 'function': incompatible types - from 'unsigned int [2]' to 'const gchar *'
../glib/tests/fileutils.c(285): warning C4133: 'function': incompatible types - from 'unsigned int [2]' to 'const gchar *'
../glib/tests/fileutils.c(286): warning C4133: 'function': incompatible types - from 'unsigned int [2]' to 'const gchar *'
../glib/tests/fileutils.c(287): warning C4133: 'function': incompatible types - from 'unsigned int [3]' to 'const gchar *'
...
```
When parsing an escaped Unicode character in a text format GVariant
string, such as '\U0001F415', the code uses g_ascii_strtoull(). This,
unexpectedly, accepts minus signs, which can cause an assertion failure
when input like '\u-FF4' is presented for parsing.
Validate that there are no leading sign characters when parsing.
This shouldn’t be considered a security bug, because the GVariant text
format parser should not be used on untrusted input.
oss-fuzz#11576
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Unlike g_ascii_strtoull(), g_ascii_string_to_unsigned() does not permit
leading signs (`+` or `-`). Document that.
It’s already in the unit tests.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
It’s perverse, but explicitly documented that strtoull() accepts numbers
with a leading minus sign (`-`) and explicitly casts them to signed
output.
g_ascii_strtoull() is documented to do what strtoull() does (but locale
independently), and its behaviour is correct. However, the documentation
could be a lot clearer about this unexpected behaviour.
Add a unit test for it too.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
In date time formatting routine, instead of converting from UTF-8 to
locale charset and then from locale charset to UTF-8, store all
intermediate result in UTF-8.
This solves the issue where user provided UTF-8 format string might be
unrepresentable in the current locale charset.
Fixes issue #1605.
In glibc, LANGUAGE is used as highest priority guess for category value.
Unset it to avoid interference with tests using setlocale and translation.
Issue #1357.
g_environ_getenv(env, "PATH") and g_environ_setenv(env, "PATH", newpath)
did not have the intended effect on Windows due to the environment block
containing "Path=". Make these functions case-insensitive for Windows.
g_main_context_prepare() needs to calculate the timeout to pass to
poll(), expressed in milliseconds as a gint. But since the ready time
for a GSource is represented by gint64 microseconds, it's possible that
it could be more than G_MAXINT * 1000 microseconds in the future, and so
can't be represented as a gint. This conversion to a narrower signed
type is implementation-defined, but there are two possible outcomes:
* the result is >= 0, in which case poll() will time out earlier than we
might hope (with no adverse consequences besides an unwanted wakeup)
* the result is < 0, in which case, if there are no other sources,
poll() will block forever
This is extremely unlikely to happen in practice, but can be avoided by
clamping the gint64 value, which we know to be positive, to G_MAXINT.
Thanks to Tomasz Miąsko for pointing this out on !496.
This is essentially a C version of the reproducer on #1600. It is based
on the existing test_seconds(), which relates to a similar but distinct
overflow.
I've only actually run this on a system with 32-bit ints, it should work
regardless of the width of an int, since the remainder after wrapping
will by construction be less than 1 second.
Previously, the `guint interval` parameter, measured in seconds, was
multiplied by 1000 and stored in another `guint` field. For intervals
greater than (G_MAXUINT / 1000) seconds, this would overflow; the
timeout would fire much sooner than intended.
Since GTimeoutSource already keeps track of whether it was created at
millisecond or second resolution, always store the passed interval
directly. We later convert the interval to microseconds, stored in a
gint64, so can move the `* 1000` to there.
The eagle-eyed reader might notice that there is no obvious guarantee
that the source's expiration time in microseconds won't overflow the
gint64, but I don't think this is a new problem. Previously, the
monotonic time would have to reach (2 ** 63 - 2 ** 32) microseconds for
this overflow to occur; now it would have to reach approximately (2 **
63 - 2 ** 42) microseconds. Both of these are 292.47 millennia to 5
significant figures.
Fixes#1600.
opendir and closedir are not async-signal-safe, these may call malloc
under the hood and cause a deadlock in a multi-threaded program.
This only affected Linux when /proc is mounted, other systems use a
slower path that iterates through all potential file descriptors.
Fixes a long-standing problem (since GLib 2.14.2).
Closes#945 and #1014