Commit graph

288 commits

Author SHA1 Message Date
Thomas Haller
80a19958dc
code-style: fix wrong indentation for code comments 2022-05-09 19:20:18 +02:00
Thomas Haller
560feecb4c
glib-aux: avoid #if in "nm-str-buf.h"
NM_MORE_ASSERT is a compile time constant. The compiler can optimize
it away just fine.
2022-05-09 19:18:30 +02:00
Thomas Haller
532f3e34a8
glib-aux: drop nm_str_buf_init() for NM_STR_BUF_INIT()
NM_STR_BUF_INIT() and nm_str_buf_init() were pretty much redundant. Drop one of
them.

Usually our pattern is that we don't have functions that return structs.
But NM_STR_BUF_INIT() returns a struct, because it's convenient to use
with

  nm_auto_str_buf NMStrBuf strbuf = NM_STR_BUF_INIT(...);

So use that variant instead.
2022-05-09 19:18:30 +02:00
Thomas Haller
13d25f9d0b
glib-aux: add support for starting with stack-allocated buffer in NMStrBuf
Allow to initialize NMStrBuf with an externally allocated array.
Usually a stack buffer. If the NMStrBuf grows beyond the size of
that initial buffer, then it would switch using malloc.

The idea is to support the common case where the result is small enough
to fit on the stack.

I always wanted to do such optimization because the main purpose of
NMStrBuf is to put it on the stack and ad-hoc construct a string.
I just figured, it would complicate the implementation and add
a runtime overhead. But turns out, it doesn't really.
The biggest question is how NMStrBuf should behave with a pre-allocated
buffer? Turns out, most choices can be made in a rather obvious way.
The only non-obvious thing is that nm_str_buf_finalize() would malloc()
a buffer, but that too seems consistent and what a user would probably
expect. As such, this doesn't seem to add unexpected semantics to the API.
2022-05-09 19:18:23 +02:00
Thomas Haller
7fcfc5ccb3
all: hardcode HOST_NAME_MAX to 64
On glibc, HOST_NAME_MAX is defined as 64. Also, Linux'
sethostname() enforces that limit (__NEW_UTS_LEN). Also,
`man gethostname` comments that HOST_NAME_MAX on Linux is
64.

However, when building against musl, HOST_NAME_MAX is defined as 255.
That seems wrong. We use this limit to validate the hostname, and that
should not depend on the libc or on the compilation.

Hardcode the value to 64.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1197
2022-04-26 17:54:56 +02:00
Thomas Haller
b3359126ba
glib-aux/tests: fix test for nm_hostname_is_valid() for different HOST_NAME_MAX
nm_hostname_is_valid() determines the valid length based on
HOST_NAME_MAX, which is defined differently for glibc and musl.

Fixes: 9ff1f66680 ('glib-aux: add nm_hostname_is_valid() helper from systemd')
2022-04-20 19:01:54 +02:00
Thomas Haller
9ff1f66680
glib-aux: add nm_hostname_is_valid() helper from systemd 2022-04-20 12:07:04 +02:00
Thomas Haller
b5f3d88e6f
glib-aux: add path-utils from systemd
We use these functions, currently from our systemd fork. One day we want
to stop importing systemd code, so we need them ourselves.

Copy them, and adjust for NM style.
2022-04-20 12:07:03 +02:00
Thomas Haller
04fc191922
glib-aux: refactor nm_unbase64mem_full()
Make the code more nm-like.
2022-04-20 12:05:17 +02:00
Thomas Haller
3571292d97
glib-aux: treat '=' as special character in nm_unbase64char()
This will be useful.
2022-04-20 12:05:17 +02:00
Thomas Haller
e3240781b1
glib-aux: use switch in nm_unbase64char()
This seams easier to read. And as we have a unit test that covers all
possible 256 input values, it's easy to refactor and ensure the code
still works.
2022-04-20 12:05:17 +02:00
Thomas Haller
63dcc5680b
glib-aux/tests: add unbase64mem test
This is copied and adjusted from "src/core/tests/test-systemd.c",
where it currently tests the systemd implementation.
2022-04-20 12:05:16 +02:00
Thomas Haller
0aa7d59557
glib-aux: add nm_unbase64{char,mem,mem_full}() helpers
These are taken from systemd code. We want to stop using systemd code,
so we can eventually drop it.
2022-04-20 12:05:16 +02:00
Thomas Haller
de926723f0
glib-aux: add nm_utils_hash_to_array() helper
We effectively already have this function, with the name
nm_utils_named_values_from_strdict(). Which is a decent name,
if you have a strdict. But it seems odd to use for other dictionaries.

Instead, add a variant with a different name. Naming is important,
and just to have the better name, the function is effectively duplicated.
2022-04-15 09:04:28 +02:00
Thomas Haller
78aad6cf51
glib-aux: add "name_ptr" union field to NMUtilsNamedValue
NMUtilsNamedValue is a key-value tuple, usually the key is a string
(hence the name "Named").

But this struct is also useful for keys that are not strings.
Add another "name_ptr" union field to access the key that way.

The alternative would be to add another struct, which serves
a very similar purpose though.
2022-04-14 21:31:36 +02:00
Thomas Haller
c44b49db6f
glib-aux: add nm_parse_env_file() helpers for parsing systemd's env-files
We write lease files for internal DHCP client ("systemd" and "nettools")
in a systemd-specific format. We want to drop systemd code, so we need
to have our own parsing code.

Granted, nettools only writes a single "ADDRESS=" line, so parsing that
would be easy. On the other hand, systemd's parser is not complicated
either (in particular, if we can steal their implementation). Also, it's
a commonly used format in systemd, so having the parser would allow us
to parse similar formats.

Also, we could opt to choose that format, where it makes sense.
2022-04-14 14:51:02 +02:00
Thomas Haller
7df494bc9a
glib-aux: add nm_ascii_is_{whitespace,newline}() helper 2022-04-14 14:51:02 +02:00
Thomas Haller
4b9ea28cd4
tests: improve nmtst_assert_strv() helper macro 2022-04-14 14:51:01 +02:00
Thomas Haller
24dab91a66
glib-aux/trivial: add code comment to nm_str_buf_get_str_unsafe() 2022-04-13 09:25:06 +02:00
Thomas Haller
2c5bacd416
std-aux: add NM_UTILS_GET_NEXT_REALLOC_SIZE_488 define 2022-04-13 09:23:28 +02:00
Thomas Haller
9ce4a16523
glib-aux: add assertions for valid prefix length 2022-04-08 15:59:50 +02:00
Thomas Haller
0cf9db42d4
glib-aux: use uint32 type for prefix length parameter
Of course, the prefix length cannot be larger than 32 or 128.
But as C does implicit conversions, a buggy prefix length can
lead to a (wrongly) valid prefix length.

Make the type uint32, to prevent that (at least for common cases,
unless you pass a huge 64 bit integer).
2022-04-08 15:59:50 +02:00
Thomas Haller
b5a06dedd4
glib-aux: move nm_utils_ip4_address_clear_host_address() to header so it can be inlined 2022-04-08 15:59:50 +02:00
Thomas Haller
d7990b359b
glib-aux: move ip address utils in "nm-shared-utils.h" header
Some were duplicated. Drop those.

Some function were in an order where they required forward declarations.
Reorder.
2022-04-08 15:59:49 +02:00
Thomas Haller
27752bfd5b
glib-aux: assert that nm_utils_to_string_buffer_init() does not use the global buffer
For convenience, most to-string methods call nm_utils_to_string_buffer_init().
This allows to omit the string buffer and use a global (thread-local)
buffer.

That "convenience" seems error prone. Start drop it.

Start by adding a g_return_if_reached() assertion to catch the cases
that use it.
2022-04-08 15:59:49 +02:00
Thomas Haller
02a8d21e4e
all: use "NM_UTILS_TO_STRING_BUFFER_SIZE" macro 2022-04-08 15:59:49 +02:00
Thomas Haller
36e709c021
all: add "NM_UTILS_TO_STRING_BUFFER_SIZE" macro
I want to get rid of "_nm_utils_to_string_buffer" (or at least, limit
and control its use). Currently it's used all over the place only
to get the size of it. Add a define instead.
2022-04-08 15:59:48 +02:00
Thomas Haller
3f4586532f
glib-aux: add nm_utils_get_monotonic_timestamp_sec_cached() helper 2022-04-08 15:59:47 +02:00
Thomas Haller
79f676c83a
crypto: move nm_crypto_read_file() to "libnm-glib-aux"
It has no actual dependency on the crypto library. All it does, is
to be careful about not leaking secrets in memory. We have code
for that in libnm-glib-aux already. Move.

The goal is to reduce the number of places where we use libnm-crypto,
because that has a large dependency. libnm-glib-aux is a very light
dependency instead.
2022-03-29 11:56:04 +02:00
Thomas Haller
526a05d6f2
glib-aux: add _nm_utils_bin2hexstr() and use from nm_utils_bin2hexstr()
nm_utils_bin2hexstr() is part of public libnm API.
That means, if we want to use this function, we need to link with
libnm-core-impl.

This is used by "nm-crypto.c". That file is currently part of
libnm-core, but that will change.

Move the implementation to libnm-glib-aux, so that we can use this code
from all our glib-based code (because all our glib-based code is allowed
to link with libnm-glib-aux).
2022-03-29 11:56:03 +02:00
Thomas Haller
681926ad43
glib-aux: make nm_gobject_notify_together_full() macro more robust
If __VA_ARGS__ contains odd arguments, it's not clear that N_ARG() gives
the same as the array initialization. Add a static assert that the
numbers agree to catch wrong usage of the macro.

For example:

    nm_gobject_notify_together(setting, a, b, );
2022-03-28 18:27:35 +02:00
Thomas Haller
47519659ed
glib-aux: reword code comments for nm_utils_buf_utf8safe_{,un}escape() 2022-03-17 12:28:56 +01:00
Thomas Haller
45d2537116
glib-aux: restrict NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER workaround to gcc 12.0.1
This was a bug in gcc 12 (<= 12.0.1). Restrict the macro further
for when we disable the warning.

See-also: https://bugzilla.redhat.com/show_bug.cgi?id=2056613
2022-03-14 13:51:29 +01:00
Thomas Haller
9b030a3988
all: change scheduling priority for idle actions to G_PRIORITY_DEFAULT_IDLE
g_idle_add() uses G_PRIORITY_DEFAULT_IDLE priority. Most of the time we don't
care much about the priority.

But at the places that this patch changes, I think that using
G_PRIORITY_DEFAULT_IDLE (and following g_idle_add()) is more correct. The
reason for this is not very strong, except that it's probably the better
choice. And the old choice was made because I didn't realize that
g_idle_add() uses another default priority. Hence, the old choice was not
for good reasons either.
2022-03-13 11:59:42 +01:00
Thomas Haller
15e8837945
glib-aux: fix priority for nm_g_idle_add_source()
nm_g_idle_add_source() is supposed to work like g_idle_add(). Use the correct
priority.

I think this causes little actual problems, because usually we don't
carefully tune the priorities and would be mostly fine with either.

Fixes: 6b18fc252d ('shared: add nm_g_{idle,timeout}_add_source() helpers')
2022-03-13 11:59:31 +01:00
Thomas Haller
5dc9307a34
glib-aux: add nm_g_main_context_can_acquire() helper 2022-03-11 12:10:18 +01:00
Thomas Haller
5cf4d3c744
glib-aux: hide API g_alloca0() and g_newa0()
For one, this API is only available since 2.72, thus we must not use
it (unless we would add a compat implementation to nm-glib.h).

But also, g_alloca0() evaluates the size argument multiple times,
making it non-function like. That seems highly undesirable and error
prone.

Also, we should be very careful about alloca() and the potential
for stack overflow. We use alloca() at times, but usually with
macros that are named "*_a()" (to make the danger clearer) and compile
time checks for the size. These glib functions make this slightly
less safe.

Just prevent us from using this API.
2022-03-04 10:05:06 +01:00
Thomas Haller
13caff572d
glib-aux: avoid nm_crypto_md5_hash() in nm_uuid_generate_from_string()
What nm_uuid_generate_from_string() does, is pretty straight forward.
What nm_crypto_md5_hash() does, is not.

Just directly use GChecksum, it seems clearer.

Also, sometimes the compiler is adamant to warn about uninitialized variables.
The workaround from commit cb9ca67901 ('glib-aux: workaround maybe-uninitialized
warning with LTO in nm_uuid_generate_from_string_str()') does not always work.
Try to solve that this way.

Note that we have plenty of unit tests for our UUID generation. This is
covered by tests.

Also, there is now only one caller of nm_crypto_md5_hash() left. Which
is good, because that function is rather non-obvious and special purpose.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1129
2022-03-02 22:19:00 +01:00
Thomas Haller
dab2ee8ac5
all: suppress wrong gcc-12 warning "-Wdangling-pointer"
gcc-12.0.1-0.8.fc36 is annoying with false positives.
It's related to g_error() and its `for(;;) ;`.

For example:

    ../src/libnm-glib-aux/nm-shared-utils.c: In function 'nm_utils_parse_inaddr_bin_full':
    ../src/libnm-glib-aux/nm-shared-utils.c:1145:26: error: dangling pointer to 'error' may be used [-Werror=dangling-pointer=]
     1145 |                     error->message);
          |                          ^~
    /usr/include/glib-2.0/glib/gmessages.h:343:32: note: in definition of macro 'g_error'
      343 |                                __VA_ARGS__);         \
          |                                ^~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1133:31: note: 'error' declared here
     1133 |         gs_free_error GError *error = NULL;
          |                               ^~~~~
    /usr/include/glib-2.0/glib/gmessages.h:341:25: error: dangling pointer to 'addrbin' may be used [-Werror=dangling-pointer=]
      341 |                         g_log (G_LOG_DOMAIN,         \
          |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      342 |                                G_LOG_LEVEL_ERROR,    \
          |                                ~~~~~~~~~~~~~~~~~~~~~~~
      343 |                                __VA_ARGS__);         \
          |                                ~~~~~~~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1141:13: note: in expansion of macro 'g_error'
     1141 |             g_error("unexpected assertion failure: could parse \"%s\" as %s, but not accepted by "
          |             ^~~~~~~
    ../src/libnm-glib-aux/nm-shared-utils.c:1112:14: note: 'addrbin' declared here
     1112 |     NMIPAddr addrbin;
          |              ^~~~~~~

I think the warning could potentially be useful and prevent real bugs.
So don't disable it altogether, but go through the effort to suppress it
at the places where it currently happens.

Note that NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER macro only expands
to suppressing the warning with __GNUC__ equal to 12. The purpose is to
only suppress the warning where we know we want to. Hopefully other gcc
versions don't have this problem.

I guess, we could also write a NM_COMPILER_WARNING() check in
"m4/compiler_options.m4", to disable the warning if we detect it. But
that seems too cumbersome.
2022-02-21 19:50:52 +01:00
Thomas Haller
445dcd9d9b
glib-aux: add NM_PRAGMA_WARNING_DISABLE_DANGLING_POINTER macro for workaround
New gcc-12.0.1-0.8.fc36 on Fedora rawhide likes to emit false
"-Wdangling-pointer" warnings with some g_error() uses. It seems
related to g_error()'s `for(;;) ;`.

As workaround, add a macro to suppress the warning.
But only do that for gcc-12. This bug hopefully gets fixed
and we don't want to suppress useful warnings too eagerly.

https://bugzilla.redhat.com/show_bug.cgi?id=2056613
2022-02-21 19:50:52 +01:00
Thomas Haller
cc28aac0de
glib-aux: add NM_PRAGMA_DIAGNOSTICS_PUSH macro
Also, combine the different macros in the same #if/#else block.

The point of this is if you have a macro that does conditionally
NM_PRAGMA_WARNING_DISABLE(), then we need a way to balance the
push/pop.
2022-02-21 19:50:52 +01:00
Thomas Haller
61ff2b03df
libnm: add direct strv type for NMSetting and use it for "match.interface-name"
G_TYPE_STRV is the last property type in NMSetting that is implemented
by directly accessing the GObect property. Note that we have lots of
override, non-default implementations that still use GObject properties,
but I am talking here about properties that don't have a special
implementation and use a G_TYPE_STRV GObject property.

Add a "direct" implementation also for strv arrays.

The advantage is that we no longer call g_value_get() for various
operations, which requires a deep-copy of the strv array. The other
advantage is that we will get a unified approach for implementing strv
properties. In particular strv arrays need a lot of code to implement,
and most settings do it differently. By adding a general mechanism,
this code (and behavior) can be unified.

Showcase it on "match.interface-name".
2022-02-10 22:30:27 +01:00
Thomas Haller
f0c565a79f
glib-aux: add nm_strvarray_*() helpers for cmp/equal functions 2022-02-10 22:30:27 +01:00
Thomas Haller
6f277d8fa6
libnm: change NMVariantAttributeSpec.str_type to work for attributes of any type
First of all, all of NMVariantAttributeSpec is internal API. We only
expose the typedef itself as public API, but not its fields nor
their meaning. So we can change things.

Change "str_type" to "type_detail", so that it can work for any kind of
attribute, not only for strings. Usually, we want to avoid special
cases and treat all attributes the same, based on their GVariant type.
But sometimes, it is necessary to do something special with an
attribute. This is what the "type_detail" encodes, but it's not only
relevant for strings.
2022-02-09 19:13:02 +01:00
Thomas Haller
a2c4f071e4
all: drop /*<skip>*/ annotations for enums
We don't run glib-mkenums for certain sources like "core" and
"libnm-glib-aux".

These annotations have no effect. Drop them.
They also mess with the automated formatting.
2022-02-08 11:14:01 +01:00
Thomas Haller
bd84ba31a5
glib-aux/tests: add tests for nm_ref_string_equal_str() 2022-01-27 19:04:44 +01:00
Thomas Haller
6ae6edb6a8
glib-aux/trival: add code comment to nm_ref_string_equal_str() 2022-01-27 14:35:38 +01:00
Beniamino Galvani
b755539aa6 glib-aux: fix nm_ref_string_equal_str()
Fix comparison with a NULL string.

The only current caller is nm-supplicant-interface.c, and this bug
causes a missing cleanup of the CurrentBSS property on disconnect.

Fixes: ac8c3a7111 ('glib-aux: improve nm_ref_string_equals_str() to work for non-C-strings')

https://bugzilla.redhat.com/show_bug.cgi?id=1983735
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1073
2022-01-27 13:47:57 +01:00
Thomas Haller
ee3e2e0bb6
glib-aux/tests: add nmtst_test_skip_slow() helper 2022-01-21 12:08:00 +01:00
Thomas Haller
cb9ca67901
glib-aux: workaround maybe-uninitialized warning with LTO in nm_uuid_generate_from_string_str()
In function 'nm_uuid_unparse',
      inlined from 'nm_uuid_generate_from_string_str' at src/libnm-glib-aux/nm-uuid.c:393:12,
      inlined from 'nm_uuid_generate_from_strings.constprop' at src/libnm-glib-aux/nm-uuid.c:430:16:
  src/libnm-glib-aux/nm-uuid.h:37:12: error: 'uuid' may be used uninitialized [-Werror=maybe-uninitialized]
     37 |     return nm_uuid_unparse_case(uuid, out_str, FALSE);
        |            ^
  src/libnm-glib-aux/nm-uuid.c: In function 'nm_uuid_generate_from_strings.constprop':
  src/libnm-glib-aux/nm-uuid.c:20:1: note: by argument 1 of type 'const struct NMUuid *' to 'nm_uuid_unparse_case.constprop' declared here
     20 | nm_uuid_unparse_case(const NMUuid *uuid, char out_str[static 37], gboolean upper_case)
        | ^
  src/libnm-glib-aux/nm-uuid.c:390:12: note: 'uuid' declared here
    390 |     NMUuid uuid;
        |            ^
  lto1: all warnings being treated as errors

The problem are code paths with failed g_return*() assertions. Being in
a bad state already, they don't bother to ensure proper return values,
and with LTO the compiler might think there are valid code paths wrongly
handled. Work around.
2022-01-21 11:38:08 +01:00