g_strdup() is often used to duplicate static strings, in these cases the
compiler could use a faster path because it knows the length of the
string at compile time, but this cannot happen because our g_strdup()
implementation is hidden.
To improve this case, we add a simple implementation of g_strdup() when
it is used with static or NULL strings that explicitly uses strlen,
g_malloc and memcpy to give hints to the compiler how to behave better.
This has definitely some benefits in terms of performances, causing an
iteration of 1000000 string duplication to drop from 2.7002s to 1.9428s
for a static string and from ~0.6584s to ~0.4408 for a NULL one.
Since compiler can optimize these cases quite a bit, the generated code
[2] is not increasing a lot, given that it can now avoid generating some
code or do it in few simpler steps.
Update tests to cover both inlined and non inlined cases.
[1] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3209#note_1644383
[2] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3209#note_1646662
Compilers can emit optimized code for str|strn|mem)cmp(str,"literal")
at compile-time. This commit use the preprocessor to introduce this
kind of optimization for the functions g_str_has_prefix() and
g_str_has_suffix().
Original work by Ben @bdejean
Closes issue #24
In the case strerror_r returns an error (both in the char* variant and
in the int variant) we should not try to proceed converting the message
and adding to the errors maps, as that's likely causing errors.
So, let's just return a null string in case this happens
Add SPDX license (but not copyright) headers to all files which follow a
certain pattern in their existing non-machine-readable header comment.
This commit was entirely generated using the command:
```
git ls-files glib/*.[ch] | xargs perl -0777 -pi -e 's/\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/\n \*\n \* SPDX-License-Identifier: LGPL-2.1-or-later\n \*\n \* This library is free software; you can redistribute it and\/or\n \* modify it under the terms of the GNU Lesser General Public/igs'
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #1415
Make it so USE_XLOCALE is set whenever newlocale() and uselocale() are
available. This way, we can still use the _g_snprintf() path for some
functions, and also use the *_l functions when they are available.
newlocale(3) are uselocale(3) part of POSIX 2008, while the *_l
functions being used are nonstandard glibc extensions. Gating all the
locale functionality behind them meant we were using fallbacks on non
glibc platforms unnecessarily.
Further changes to this code could add fallback for the non _l suffixed
number parsing functions, but that might be unnecessary complexity.
Fixes#2553
The documentation wasn’t clear about whether it did that, or ignored nul
bytes and continued to `n` bytes regardless.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Unfortunately, `g_memdup()` accepts its size argument as a `guint`,
unlike most other functions which deal with memory sizes — they all use
`gsize`. `gsize` is 64 bits on 64-bit machines, while `guint` is only 32
bits. This can lead to a silent (with default compiler warnings)
truncation of the value provided by the caller. For large values, this
will result in the returned heap allocation being significantly smaller
than the caller expects, which will then lead to buffer overflow
reads/writes.
Any code using `g_memdup()` should immediately port to `g_memdup2()` and
check the pointer arithmetic around their call site to ensure there
aren’t other overflows.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2319
This will replace the existing `g_memdup()` function, which has an
unavoidable security flaw of taking its `byte_size` argument as a
`guint` rather than as a `gsize`. Most callers will expect it to be a
`gsize`, and may pass in large values which could silently be truncated,
resulting in an undersize allocation compared to what the caller
expects.
This could lead to a classic buffer overflow vulnerability for many
callers of `g_memdup()`.
`g_memdup2()`, in comparison, takes its `byte_size` as a `gsize`.
Spotted by Kevin Backhouse of GHSL.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: GHSL-2021-045
Helps: #2319
gboolean is secretly actually typedef gint gboolean, so the delim_table
is going to take 1KB of stack all by itself. That’s fine, but it could
be smaller.
This strnpbrk()-like block could do with a comment to make it a bit
clearer what it’s doing.
Suggested-by: Philip Withnall <philip@tecnocode.co.uk>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This was mostly machine generated with the following command:
```
codespell \
--builtin clear,rare,usage \
--skip './po/*' --skip './.git/*' --skip './NEWS*' \
--write-changes .
```
using the latest git version of `codespell` as per [these
instructions](https://github.com/codespell-project/codespell#user-content-updating).
Then I manually checked each change using `git add -p`, made a few
manual fixups and dropped a load of incorrect changes.
There are still some outdated or loaded terms used in GLib, mostly to do
with git branch terminology. They will need to be changed later as part
of a wider migration of git terminology.
If I’ve missed anything, please file an issue!
Signed-off-by: Philip Withnall <withnall@endlessm.com>
This is more efficient and also much easier since we already have the
memory allocated that we're going to return from the function. No need
to do that ourselves or reverse a list.
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.
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>
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
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
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)
^
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>
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>
g_snprintf() and g_vsnprintf() declarations were moved and
don't require gprintf.h to be included anymore but g_vasprintf()
is and requires gprintf.h to be explicitly included.
https://bugzilla.gnome.org/show_bug.cgi?id=760716
Mention that it really is a good idea to save errno before doing
literally anything else after calling a function which could set it.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://bugzilla.gnome.org/show_bug.cgi?id=785577
All glib/*.{c,h} files have been processed, as well as gtester-report.
12 of those files are not licensed under LGPL:
gbsearcharray.h
gconstructor.h
glibintl.h
gmirroringtable.h
gscripttable.h
gtranslit-data.h
gunibreak.h
gunichartables.h
gunicomp.h
gunidecomp.h
valgrind.h
win_iconv.c
Some of them are generated files, some are licensed under a BSD-style
license and win_iconv.c is in the public domain.
Sub-directories inside glib/:
deprecated/: processed in a previous commit
glib-mirroring-tab/: already LGPLv2.1+
gnulib/: not modified, the code is copied from gnulib
libcharset/: a copy
pcre/: a copy
tests/: processed in a previous commit
https://bugzilla.gnome.org/show_bug.cgi?id=776504
The tool that extracts the translatable strings to .po files does not
cope with the G_GUINTX_FORMAT macros, so we preformat the numbers to
strings and use the strings in the translatable error messages.
Very often when we want to convert a string to number, we assume that
the string contains only a number. We have g_ascii_strto* family of
functions to do the conversion but they are awkward to use - one has
to check if errno is zero, end_ptr is not NULL and *end_ptr points to
the terminating nul and then do the bounds checking. Many projects
need this kind of functionality, so it gets reimplemented all the
time.
This commit adds some replacement functions that convert a string to a
signed or unsigned number that also follows the usual way of error
reporting - returning FALSE on failure and filling an error output
parameter.
glibc string.h declares memcpy() with attribute(nonnull(1,2)), causing
calls with NULL arguments to be treated as undefined behaviour.
This is consistent with ISO C99 and C11, which state that passing 0
to string functions as an array length does not remove the requirement
that the pointer to the array is a valid pointer.
gcc -fsanitize=undefined catches this while running OSTree's test suite.
Similarly, running the GLib test suite reports similar issues for
qsort(), memmove(), memcmp().
Signed-off-by: Simon McVittie <smcv@debian.org>
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=775510
Reviewed-by: Colin Walters
If we have an input parameter (or return value) we need to use (nullable).
However, if it is an (inout) or (out) parameter, (optional) is sufficient.
It looks like (nullable) could be used for everything according to the
Annotation documentation, but (optional) is more specific.
Add various (nullable) and (optional) annotations which were missing
from a variety of functions. Also port a couple of existing (allow-none)
annotations in the same files to use (nullable) and (optional) as
appropriate instead.
Secondly, add various (not nullable) annotations as needed by the new
default in gobject-introspection of marking gpointers as (nullable). See
https://bugzilla.gnome.org/show_bug.cgi?id=729660.
This includes adding some stub documentation comments for the
assertion macro error functions, which weren’t previously documented.
The new comments are purely to allow for annotations, and hence are
marked as (skip) to prevent the symbols appearing in the GIR file.
https://bugzilla.gnome.org/show_bug.cgi?id=719966