mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-03-05 17:00:49 +01:00
libnm,json: merge branch 'th/libnm_jansson-2'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/559
This commit is contained in:
commit
341111ff31
20 changed files with 855 additions and 527 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -131,6 +131,7 @@ test-*.trs
|
|||
/examples/C/qt/monitor-nm-running
|
||||
/examples/C/qt/monitor-nm-running.moc
|
||||
|
||||
/shared/nm-glib-aux/tests/test-json-aux
|
||||
/shared/nm-glib-aux/tests/test-shared-general
|
||||
/shared/nm-version-macros.h
|
||||
|
||||
|
|
|
|||
45
Makefile.am
45
Makefile.am
|
|
@ -642,6 +642,39 @@ shared_nm_glib_aux_tests_test_shared_general_LDADD = \
|
|||
|
||||
###############################################################################
|
||||
|
||||
if WITH_JANSSON
|
||||
|
||||
check_programs += shared/nm-glib-aux/tests/test-json-aux
|
||||
|
||||
shared_nm_glib_aux_tests_test_json_aux_CPPFLAGS = \
|
||||
$(dflt_cppflags) \
|
||||
-I$(srcdir)/shared \
|
||||
-DNETWORKMANAGER_COMPILATION_TEST \
|
||||
-DNETWORKMANAGER_COMPILATION='(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)' \
|
||||
$(CODE_COVERAGE_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(JANSSON_CFLAGS) \
|
||||
$(SANITIZER_LIB_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
shared_nm_glib_aux_tests_test_json_aux_LDFLAGS = \
|
||||
$(CODE_COVERAGE_LDFLAGS) \
|
||||
$(SANITIZER_EXEC_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
shared_nm_glib_aux_tests_test_json_aux_LDADD = \
|
||||
$(JANSSON_LIBS) \
|
||||
shared/nm-glib-aux/libnm-glib-aux.la \
|
||||
shared/systemd/libnm-systemd-logging-stub.la \
|
||||
shared/nm-std-aux/libnm-std-aux.la \
|
||||
shared/libcsiphash.la \
|
||||
$(GLIB_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
|
||||
noinst_LTLIBRARIES += introspection/libnmdbus.la
|
||||
|
||||
introspection_libnmdbus_la_CPPFLAGS = $(GLIB_CFLAGS)
|
||||
|
|
@ -1031,13 +1064,6 @@ libnm_core_lib_c_real = \
|
|||
libnm-core/nm-vpn-plugin-info.c \
|
||||
$(NULL)
|
||||
|
||||
if WITH_JSON_VALIDATION
|
||||
libnm_core_lib_h_priv += \
|
||||
libnm-core/nm-json.h
|
||||
libnm_core_lib_c_real += \
|
||||
libnm-core/nm-json.c
|
||||
endif
|
||||
|
||||
libnm_core_lib_c_mkenums = \
|
||||
libnm-core/nm-core-enum-types.c
|
||||
|
||||
|
|
@ -1092,11 +1118,6 @@ libnm_core_libnm_core_la_CPPFLAGS = \
|
|||
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE \
|
||||
$(NULL)
|
||||
|
||||
if WITH_JSON_VALIDATION
|
||||
libnm_core_libnm_core_la_CPPFLAGS += $(JANSSON_CFLAGS)
|
||||
libnm_core_libnm_core_la_CPPFLAGS += -fcommon
|
||||
endif
|
||||
|
||||
libnm_core_libnm_core_la_SOURCES = \
|
||||
$(libnm_core_lib_h_pub_real) \
|
||||
$(libnm_core_lib_h_priv) \
|
||||
|
|
|
|||
|
|
@ -212,9 +212,6 @@
|
|||
/* Define if JANSSON is enabled */
|
||||
#mesondefine WITH_JANSSON
|
||||
|
||||
/* Define if JSON validation in libnm is enabled */
|
||||
#mesondefine WITH_JSON_VALIDATION
|
||||
|
||||
/* Define if you have libpsl */
|
||||
#mesondefine WITH_LIBPSL
|
||||
|
||||
|
|
|
|||
21
configure.ac
21
configure.ac
|
|
@ -583,7 +583,7 @@ PKG_CHECK_MODULES(UUID, uuid)
|
|||
|
||||
# Teamd control checks
|
||||
|
||||
PKG_CHECK_MODULES(JANSSON, [jansson >= 2.5], [have_jansson=yes], [have_jansson=no])
|
||||
PKG_CHECK_MODULES(JANSSON, [jansson >= 2.7], [have_jansson=yes], [have_jansson=no])
|
||||
if test "$have_jansson" = "yes"; then
|
||||
AC_DEFINE(WITH_JANSSON, 1, [Define if JANSSON is enabled])
|
||||
|
||||
|
|
@ -596,6 +596,8 @@ if test "$have_jansson" = "yes"; then
|
|||
fi
|
||||
AC_DEFINE_UNQUOTED(JANSSON_SONAME, "$JANSSON_SONAME", [Define to path to the Jansson shared library])
|
||||
else
|
||||
have_jansson=no
|
||||
JANSSON_SONAME=
|
||||
AC_DEFINE(WITH_JANSSON, 0, [Define if JANSSON is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_JANSSON, test "${have_jansson}" = "yes")
|
||||
|
|
@ -622,21 +624,6 @@ if test "${enable_teamdctl}" = "yes"; then
|
|||
fi
|
||||
AM_CONDITIONAL(WITH_TEAMDCTL, test "${enable_teamdctl}" = "yes")
|
||||
|
||||
# Jansson for team configuration validation
|
||||
AC_ARG_ENABLE(json-validation,
|
||||
AS_HELP_STRING([--enable-json-validation], [Enable JSON validation in libnm]),
|
||||
[enable_json_validation=${enableval}],
|
||||
[enable_json_validation=${have_jansson}])
|
||||
if test "${enable_json_validation}" = "no"; then
|
||||
AC_DEFINE(WITH_JSON_VALIDATION, 0, [Define if JSON validation in libnm is enabled])
|
||||
else
|
||||
if test "$have_jansson" = "no"; then
|
||||
AC_MSG_ERROR([jansson is needed for team configuration validation. Use --disable-json-validation to build without it.])
|
||||
fi
|
||||
AC_DEFINE(WITH_JSON_VALIDATION, 1, [Define if JSON validation in libnm is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_JSON_VALIDATION, test "${enable_json_validation}" != "no")
|
||||
|
||||
# we usually compile with polkit support. --enable-polkit=yes|no only sets the
|
||||
# default configuration for main.auth-polkit. User can always enable/disable polkit
|
||||
# authorization via config.
|
||||
|
|
@ -1366,6 +1353,7 @@ echo " nmcli: $build_nmcli"
|
|||
echo " nmtui: $build_nmtui"
|
||||
echo " nm-cloud-setup: $with_nm_cloud_setup"
|
||||
echo " iwd: $ac_with_iwd"
|
||||
echo " jansson: $have_jansson${JANSSON_SONAME:+ (soname: $JANSSON_SONAME)}"
|
||||
echo
|
||||
|
||||
echo "Configuration plugins (main.plugins=${config_plugins_default})"
|
||||
|
|
@ -1398,7 +1386,6 @@ echo " valgrind: $with_valgrind $with_valgrind_suppressions"
|
|||
echo " code coverage: $enable_code_coverage"
|
||||
echo " LTO: $enable_lto"
|
||||
echo " linker garbage collection: $enable_ld_gc"
|
||||
echo " JSON validation for libnm: $enable_json_validation"
|
||||
echo " crypto: $with_crypto (have-gnutls: $have_crypto_gnutls, have-nss: $have_crypto_nss)"
|
||||
echo " sanitizers: $sanitizers"
|
||||
echo " Mozilla Public Suffix List: $with_libpsl"
|
||||
|
|
|
|||
|
|
@ -196,12 +196,6 @@ links = [
|
|||
|
||||
libnm_core_c_args = common_c_flags
|
||||
|
||||
if enable_json_validation
|
||||
libnm_core_sources += files('nm-json.c')
|
||||
deps += jansson_dep
|
||||
libnm_core_c_args += ['-fcommon']
|
||||
endif
|
||||
|
||||
libnm_core = static_library(
|
||||
'nm-core',
|
||||
sources: libnm_core_sources + libnm_core_enum_sources + nm_meta_setting_source + [nm_version_macro_header],
|
||||
|
|
|
|||
|
|
@ -1,110 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/*
|
||||
* Copyright (C) 2017, 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#define NM_JANSSON_C
|
||||
#include "nm-json.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
void *_nm_jansson_json_object_iter_value;
|
||||
void *_nm_jansson_json_object_key_to_iter;
|
||||
void *_nm_jansson_json_integer;
|
||||
void *_nm_jansson_json_object_del;
|
||||
void *_nm_jansson_json_array_get;
|
||||
void *_nm_jansson_json_array_size;
|
||||
void *_nm_jansson_json_array_append_new;
|
||||
void *_nm_jansson_json_string;
|
||||
void *_nm_jansson_json_object_iter_next;
|
||||
void *_nm_jansson_json_loads;
|
||||
void *_nm_jansson_json_dumps;
|
||||
void *_nm_jansson_json_object_iter_key;
|
||||
void *_nm_jansson_json_object;
|
||||
void *_nm_jansson_json_object_get;
|
||||
void *_nm_jansson_json_array;
|
||||
void *_nm_jansson_json_false;
|
||||
void *_nm_jansson_json_delete;
|
||||
void *_nm_jansson_json_true;
|
||||
void *_nm_jansson_json_object_size;
|
||||
void *_nm_jansson_json_object_set_new;
|
||||
void *_nm_jansson_json_object_iter;
|
||||
void *_nm_jansson_json_integer_value;
|
||||
void *_nm_jansson_json_string_value;
|
||||
|
||||
#define TRY_BIND_SYMBOL(symbol) \
|
||||
G_STMT_START { \
|
||||
void *sym = dlsym (handle, #symbol); \
|
||||
if (_nm_jansson_ ## symbol && sym != _nm_jansson_ ## symbol) \
|
||||
return FALSE; \
|
||||
_nm_jansson_ ## symbol = sym; \
|
||||
} G_STMT_END
|
||||
|
||||
static gboolean
|
||||
bind_symbols (void *handle)
|
||||
{
|
||||
TRY_BIND_SYMBOL (json_object_iter_value);
|
||||
TRY_BIND_SYMBOL (json_object_key_to_iter);
|
||||
TRY_BIND_SYMBOL (json_integer);
|
||||
TRY_BIND_SYMBOL (json_object_del);
|
||||
TRY_BIND_SYMBOL (json_array_get);
|
||||
TRY_BIND_SYMBOL (json_array_size);
|
||||
TRY_BIND_SYMBOL (json_array_append_new);
|
||||
TRY_BIND_SYMBOL (json_string);
|
||||
TRY_BIND_SYMBOL (json_object_iter_next);
|
||||
TRY_BIND_SYMBOL (json_loads);
|
||||
TRY_BIND_SYMBOL (json_dumps);
|
||||
TRY_BIND_SYMBOL (json_object_iter_key);
|
||||
TRY_BIND_SYMBOL (json_object);
|
||||
TRY_BIND_SYMBOL (json_object_get);
|
||||
TRY_BIND_SYMBOL (json_array);
|
||||
TRY_BIND_SYMBOL (json_false);
|
||||
TRY_BIND_SYMBOL (json_delete);
|
||||
TRY_BIND_SYMBOL (json_true);
|
||||
TRY_BIND_SYMBOL (json_object_size);
|
||||
TRY_BIND_SYMBOL (json_object_set_new);
|
||||
TRY_BIND_SYMBOL (json_object_iter);
|
||||
TRY_BIND_SYMBOL (json_integer_value);
|
||||
TRY_BIND_SYMBOL (json_string_value);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_jansson_load (void)
|
||||
{
|
||||
static enum {
|
||||
UNKNOWN,
|
||||
AVAILABLE,
|
||||
MISSING,
|
||||
} state = UNKNOWN;
|
||||
void *handle;
|
||||
int mode;
|
||||
|
||||
if (G_LIKELY (state != UNKNOWN))
|
||||
goto out;
|
||||
|
||||
/* First just resolve the symbols to see if there's a conflict already. */
|
||||
if (!bind_symbols (RTLD_DEFAULT))
|
||||
goto out;
|
||||
|
||||
mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND;
|
||||
#if defined (ASAN_BUILD)
|
||||
/* Address sanitizer is incompatible with RTLD_DEEPBIND. */
|
||||
mode &= ~RTLD_DEEPBIND;
|
||||
#endif
|
||||
handle = dlopen (JANSSON_SONAME, mode);
|
||||
|
||||
if (!handle)
|
||||
goto out;
|
||||
|
||||
/* Now do the actual binding. */
|
||||
if (!bind_symbols (handle))
|
||||
goto out;
|
||||
|
||||
state = AVAILABLE;
|
||||
out:
|
||||
return state == AVAILABLE;
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/*
|
||||
* Copyright (C) 2017, 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_JSON_H__
|
||||
#define __NM_JSON_H__
|
||||
|
||||
gboolean nm_jansson_load (void);
|
||||
|
||||
#ifndef NM_JANSSON_C
|
||||
#define json_object_iter_value (*_nm_jansson_json_object_iter_value)
|
||||
#define json_object_key_to_iter (*_nm_jansson_json_object_key_to_iter)
|
||||
#define json_integer (*_nm_jansson_json_integer)
|
||||
#define json_object_del (*_nm_jansson_json_object_del)
|
||||
#define json_array_get (*_nm_jansson_json_array_get)
|
||||
#define json_array_size (*_nm_jansson_json_array_size)
|
||||
#define json_array_append_new (*_nm_jansson_json_array_append_new)
|
||||
#define json_string (*_nm_jansson_json_string)
|
||||
#define json_object_iter_next (*_nm_jansson_json_object_iter_next)
|
||||
#define json_loads (*_nm_jansson_json_loads)
|
||||
#define json_dumps (*_nm_jansson_json_dumps)
|
||||
#define json_object_iter_key (*_nm_jansson_json_object_iter_key)
|
||||
#define json_object (*_nm_jansson_json_object)
|
||||
#define json_object_get (*_nm_jansson_json_object_get)
|
||||
#define json_array (*_nm_jansson_json_array)
|
||||
#define json_false (*_nm_jansson_json_false)
|
||||
#define json_delete (*_nm_jansson_json_delete)
|
||||
#define json_true (*_nm_jansson_json_true)
|
||||
#define json_object_size (*_nm_jansson_json_object_size)
|
||||
#define json_object_set_new (*_nm_jansson_json_object_set_new)
|
||||
#define json_object_iter (*_nm_jansson_json_object_iter)
|
||||
#define json_integer_value (*_nm_jansson_json_integer_value)
|
||||
#define json_string_value (*_nm_jansson_json_string_value)
|
||||
|
||||
#include "nm-glib-aux/nm-jansson.h"
|
||||
#endif
|
||||
|
||||
#endif /* __NM_JSON_H__ */
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "nm-errors.h"
|
||||
#include "nm-utils-private.h"
|
||||
#include "nm-json.h"
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-setting-team.h"
|
||||
|
|
@ -460,9 +459,9 @@ _team_attr_data_to_json (const TeamAttrData *attr_data,
|
|||
_team_attr_data_ASSERT (attr_data);
|
||||
nm_assert (p_field);
|
||||
|
||||
nm_json_aux_gstr_append_obj_name (gstr,
|
||||
attr_data->js_keys[attr_data->js_keys_len - 1],
|
||||
'\0');
|
||||
nm_json_gstr_append_obj_name (gstr,
|
||||
attr_data->js_keys[attr_data->js_keys_len - 1],
|
||||
'\0');
|
||||
|
||||
if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC) {
|
||||
nm_value_type_to_json (attr_data->value_type, gstr, p_field);
|
||||
|
|
@ -482,7 +481,7 @@ _team_attr_data_to_json (const TeamAttrData *attr_data,
|
|||
g_string_append (gstr, "[ ");
|
||||
for (i = 0; i < v_ptrarray->len; i++) {
|
||||
if (i > 0)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
_link_watcher_to_json (v_ptrarray->pdata[i], gstr);
|
||||
}
|
||||
g_string_append (gstr, " ]");
|
||||
|
|
@ -500,8 +499,8 @@ _team_attr_data_to_json (const TeamAttrData *attr_data,
|
|||
g_string_append (gstr, "[ ");
|
||||
for (i = 0; i < v_ptrarray->len; i++) {
|
||||
if (i > 0)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_aux_gstr_append_string (gstr, v_ptrarray->pdata[i]);
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_string (gstr, v_ptrarray->pdata[i]);
|
||||
}
|
||||
g_string_append (gstr, i > 0 ? " ]" : "]");
|
||||
}
|
||||
|
|
@ -671,7 +670,7 @@ _team_setting_field_to_json (const NMTeamSetting *self,
|
|||
return FALSE;
|
||||
|
||||
if (prepend_delimiter)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
_team_attr_data_to_json (attr_data,
|
||||
self->d.is_port,
|
||||
gstr,
|
||||
|
|
@ -1108,29 +1107,29 @@ _link_watcher_to_json (const NMTeamLinkWatcher *link_watcher,
|
|||
if (is_first)
|
||||
is_first = FALSE;
|
||||
else
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_aux_gstr_append_obj_name (gstr, attr_data->js_key, '\0');
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_obj_name (gstr, attr_data->js_key, '\0');
|
||||
nm_value_type_to_json (attr_data->value_type, gstr, &p_val->val);
|
||||
}
|
||||
|
||||
g_string_append (gstr, " }");
|
||||
}
|
||||
|
||||
#if WITH_JSON_VALIDATION
|
||||
static NMTeamLinkWatcher *
|
||||
_link_watcher_from_json (const json_t *root_js_obj,
|
||||
_link_watcher_from_json (const NMJsonVt *vt,
|
||||
const nm_json_t *root_js_obj,
|
||||
gboolean *out_unrecognized_content)
|
||||
{
|
||||
NMValueTypUnioMaybe args[G_N_ELEMENTS (link_watcher_attr_datas)] = { };
|
||||
const char *j_key;
|
||||
json_t *j_val;
|
||||
nm_json_t *j_val;
|
||||
const char *v_name;
|
||||
NMTeamLinkWatcher *result = NULL;
|
||||
|
||||
if (!json_is_object (root_js_obj))
|
||||
if (!nm_json_is_object (root_js_obj))
|
||||
goto fail;
|
||||
|
||||
json_object_foreach ((json_t *) root_js_obj, j_key, j_val) {
|
||||
nm_json_object_foreach (vt, (nm_json_t *) root_js_obj, j_key, j_val) {
|
||||
const LinkWatcherAttrData *attr_data = NULL;
|
||||
NMValueTypUnioMaybe *parse_result;
|
||||
|
||||
|
|
@ -1154,7 +1153,7 @@ _link_watcher_from_json (const json_t *root_js_obj,
|
|||
if (parse_result->has)
|
||||
*out_unrecognized_content = TRUE;
|
||||
|
||||
if (!nm_value_type_from_json (attr_data->value_type, j_val, &parse_result->val))
|
||||
if (!nm_value_type_from_json (vt, attr_data->value_type, j_val, &parse_result->val))
|
||||
*out_unrecognized_content = TRUE;
|
||||
else
|
||||
parse_result->has = TRUE;
|
||||
|
|
@ -1218,7 +1217,6 @@ fail:
|
|||
*out_unrecognized_content = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -1575,15 +1573,15 @@ nm_team_setting_config_get (const NMTeamSetting *self)
|
|||
|
||||
nm_assert (list_is_empty);
|
||||
|
||||
nm_json_aux_gstr_append_obj_name (gstr, "runner", '{');
|
||||
nm_json_gstr_append_obj_name (gstr, "runner", '{');
|
||||
|
||||
if (_team_setting_fields_to_json_maybe (self, gstr, !list_is_empty2, attr_lst_runner_pt1, G_N_ELEMENTS (attr_lst_runner_pt1)))
|
||||
list_is_empty2 = FALSE;
|
||||
|
||||
if (_team_setting_has_fields_any_v (self, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2))) {
|
||||
if (!list_is_empty2)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_aux_gstr_append_obj_name (gstr, "tx_balancer", '{');
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_obj_name (gstr, "tx_balancer", '{');
|
||||
if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_runner_pt2, G_N_ELEMENTS (attr_lst_runner_pt2)))
|
||||
nm_assert_not_reached ();
|
||||
g_string_append (gstr, " }");
|
||||
|
|
@ -1600,8 +1598,8 @@ nm_team_setting_config_get (const NMTeamSetting *self)
|
|||
|
||||
if (_team_setting_has_fields_any_v (self, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers))) {
|
||||
if (!list_is_empty)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_aux_gstr_append_obj_name (gstr, "notify_peers", '{');
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_obj_name (gstr, "notify_peers", '{');
|
||||
if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_notify_peers, G_N_ELEMENTS (attr_lst_notify_peers)))
|
||||
nm_assert_not_reached ();
|
||||
g_string_append (gstr, " }");
|
||||
|
|
@ -1610,8 +1608,8 @@ nm_team_setting_config_get (const NMTeamSetting *self)
|
|||
|
||||
if (_team_setting_has_fields_any_v (self, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin))) {
|
||||
if (!list_is_empty)
|
||||
nm_json_aux_gstr_append_delimiter (gstr);
|
||||
nm_json_aux_gstr_append_obj_name (gstr, "mcast_rejoin", '{');
|
||||
nm_json_gstr_append_delimiter (gstr);
|
||||
nm_json_gstr_append_obj_name (gstr, "mcast_rejoin", '{');
|
||||
if (!_team_setting_fields_to_json_maybe (self, gstr, FALSE, attr_lst_mcast_rejoin, G_N_ELEMENTS (attr_lst_mcast_rejoin)))
|
||||
nm_assert_not_reached ();
|
||||
g_string_append (gstr, " }");
|
||||
|
|
@ -1641,7 +1639,6 @@ nm_team_setting_config_get (const NMTeamSetting *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if WITH_JSON_VALIDATION
|
||||
static gboolean
|
||||
_attr_data_match_keys (const TeamAttrData *attr_data,
|
||||
const char *const*keys,
|
||||
|
|
@ -1686,18 +1683,21 @@ _attr_data_find_by_json_key (gboolean is_port,
|
|||
}
|
||||
|
||||
static void
|
||||
_js_parse_locate_keys (NMTeamSetting *self,
|
||||
json_t *root_js_obj,
|
||||
json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
_js_parse_locate_keys (const NMJsonVt *vt,
|
||||
NMTeamSetting *self,
|
||||
nm_json_t *root_js_obj,
|
||||
nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
gboolean *out_unrecognized_content)
|
||||
{
|
||||
const char *keys[3];
|
||||
const char *cur_key1;
|
||||
const char *cur_key2;
|
||||
const char *cur_key3;
|
||||
json_t *cur_val1;
|
||||
json_t *cur_val2;
|
||||
json_t *cur_val3;
|
||||
nm_json_t *cur_val1;
|
||||
nm_json_t *cur_val2;
|
||||
nm_json_t *cur_val3;
|
||||
|
||||
nm_assert (vt);
|
||||
|
||||
#define _handle(_self, _cur_key, _cur_val, _keys, _level, _found_keys, _out_unrecognized_content) \
|
||||
({ \
|
||||
|
|
@ -1713,18 +1713,18 @@ _js_parse_locate_keys (NMTeamSetting *self,
|
|||
(_found_keys)[_attr_data->team_attr] = (_cur_val); \
|
||||
_handled = TRUE; \
|
||||
} else if ( !_attr_data \
|
||||
|| !json_is_object ((_cur_val))) { \
|
||||
|| !nm_json_is_object ((_cur_val))) { \
|
||||
*(_out_unrecognized_content) = TRUE; \
|
||||
_handled = TRUE; \
|
||||
} \
|
||||
_handled; \
|
||||
})
|
||||
|
||||
json_object_foreach (root_js_obj, cur_key1, cur_val1) {
|
||||
nm_json_object_foreach (vt, root_js_obj, cur_key1, cur_val1) {
|
||||
if (!_handle (self, cur_key1, cur_val1, keys, 1, found_keys, out_unrecognized_content)) {
|
||||
json_object_foreach (cur_val1, cur_key2, cur_val2) {
|
||||
nm_json_object_foreach (vt, cur_val1, cur_key2, cur_val2) {
|
||||
if (!_handle (self, cur_key2, cur_val2, keys, 2, found_keys, out_unrecognized_content)) {
|
||||
json_object_foreach (cur_val2, cur_key3, cur_val3) {
|
||||
nm_json_object_foreach (vt, cur_val2, cur_key3, cur_val3) {
|
||||
if (!_handle (self, cur_key3, cur_val3, keys, 3, found_keys, out_unrecognized_content))
|
||||
*out_unrecognized_content = TRUE;
|
||||
}
|
||||
|
|
@ -1737,8 +1737,9 @@ _js_parse_locate_keys (NMTeamSetting *self,
|
|||
}
|
||||
|
||||
static void
|
||||
_js_parse_unpack (gboolean is_port,
|
||||
json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
_js_parse_unpack (const NMJsonVt *vt,
|
||||
gboolean is_port,
|
||||
nm_json_t *found_keys[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
bool out_has_lst[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
NMValueTypUnion out_val_lst[static _NM_TEAM_ATTRIBUTE_NUM],
|
||||
gboolean *out_unrecognized_content,
|
||||
|
|
@ -1747,10 +1748,12 @@ _js_parse_unpack (gboolean is_port,
|
|||
{
|
||||
const TeamAttrData *attr_data;
|
||||
|
||||
nm_assert (vt);
|
||||
|
||||
for (attr_data = &team_attr_datas[TEAM_ATTR_IDX_CONFIG + 1]; attr_data < &team_attr_datas[G_N_ELEMENTS (team_attr_datas)]; attr_data++) {
|
||||
NMValueTypUnion *p_out_val;
|
||||
gboolean valid = FALSE;
|
||||
json_t *arg_js_obj;
|
||||
nm_json_t *arg_js_obj;
|
||||
|
||||
if (!_team_attr_data_is_relevant (attr_data, is_port))
|
||||
continue;
|
||||
|
|
@ -1764,25 +1767,27 @@ _js_parse_unpack (gboolean is_port,
|
|||
p_out_val = &out_val_lst[attr_data->team_attr];
|
||||
|
||||
if (attr_data->value_type != NM_VALUE_TYPE_UNSPEC)
|
||||
valid = nm_value_type_from_json (attr_data->value_type, arg_js_obj, p_out_val);
|
||||
valid = nm_value_type_from_json (vt, attr_data->value_type, arg_js_obj, p_out_val);
|
||||
else if (attr_data->team_attr == NM_TEAM_ATTRIBUTE_LINK_WATCHERS) {
|
||||
GPtrArray *link_watchers = NULL;
|
||||
NMTeamLinkWatcher *link_watcher;
|
||||
|
||||
nm_assert (out_ptr_array_link_watchers_free && !*out_ptr_array_link_watchers_free);
|
||||
if (json_is_array (arg_js_obj)) {
|
||||
if (nm_json_is_array (arg_js_obj)) {
|
||||
gsize i, len;
|
||||
|
||||
len = json_array_size (arg_js_obj);
|
||||
len = vt->nm_json_array_size (arg_js_obj);
|
||||
link_watchers = g_ptr_array_new_full (len, (GDestroyNotify) nm_team_link_watcher_unref);
|
||||
for (i = 0; i < len; i++) {
|
||||
link_watcher = _link_watcher_from_json (json_array_get (arg_js_obj, i),
|
||||
link_watcher = _link_watcher_from_json (vt,
|
||||
vt->nm_json_array_get (arg_js_obj, i),
|
||||
out_unrecognized_content);
|
||||
if (link_watcher)
|
||||
g_ptr_array_add (link_watchers, link_watcher);
|
||||
}
|
||||
} else {
|
||||
link_watcher = _link_watcher_from_json (arg_js_obj,
|
||||
link_watcher = _link_watcher_from_json (vt,
|
||||
arg_js_obj,
|
||||
out_unrecognized_content);
|
||||
if (link_watcher) {
|
||||
link_watchers = g_ptr_array_new_full (1, (GDestroyNotify) nm_team_link_watcher_unref);
|
||||
|
|
@ -1799,16 +1804,17 @@ _js_parse_unpack (gboolean is_port,
|
|||
GPtrArray *strv = NULL;
|
||||
|
||||
nm_assert (out_ptr_array_master_runner_tx_hash_free && !*out_ptr_array_master_runner_tx_hash_free);
|
||||
if (json_is_array (arg_js_obj)) {
|
||||
if (nm_json_is_array (arg_js_obj)) {
|
||||
gsize i, len;
|
||||
|
||||
len = json_array_size (arg_js_obj);
|
||||
len = vt->nm_json_array_size (arg_js_obj);
|
||||
if (len > 0) {
|
||||
strv = g_ptr_array_sized_new (len);
|
||||
for (i = 0; i < len; i++) {
|
||||
const char *v_string;
|
||||
|
||||
if ( nm_jansson_json_as_string (json_array_get (arg_js_obj, i),
|
||||
if ( nm_jansson_json_as_string (vt,
|
||||
vt->nm_json_array_get (arg_js_obj, i),
|
||||
&v_string) <= 0
|
||||
|| !v_string
|
||||
|| v_string[0] == '\0') {
|
||||
|
|
@ -1832,11 +1838,11 @@ _js_parse_unpack (gboolean is_port,
|
|||
*out_unrecognized_content = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
guint32
|
||||
nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
|
||||
{
|
||||
const NMJsonVt *vt;
|
||||
guint32 changed_flags = 0;
|
||||
gboolean do_set_default = TRUE;
|
||||
gboolean new_js_str_invalid = FALSE;
|
||||
|
|
@ -1866,30 +1872,29 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
|
|||
} else
|
||||
changed_flags |= nm_team_attribute_to_flags (NM_TEAM_ATTRIBUTE_CONFIG);
|
||||
|
||||
#if WITH_JSON_VALIDATION
|
||||
{
|
||||
nm_auto_decref_json json_t *root_js_obj = NULL;
|
||||
|
||||
if (nm_jansson_load ())
|
||||
root_js_obj = json_loads (js_str, 0, NULL);
|
||||
if ((vt = nm_json_vt ())) {
|
||||
nm_auto_decref_json nm_json_t *root_js_obj = NULL;
|
||||
|
||||
root_js_obj = vt->nm_json_loads (js_str, 0, NULL);
|
||||
if ( !root_js_obj
|
||||
|| !json_is_object (root_js_obj))
|
||||
|| !nm_json_is_object (root_js_obj))
|
||||
new_js_str_invalid = TRUE;
|
||||
else {
|
||||
gboolean unrecognized_content = FALSE;
|
||||
bool has_lst[_NM_TEAM_ATTRIBUTE_NUM] = { FALSE, };
|
||||
NMValueTypUnion val_lst[_NM_TEAM_ATTRIBUTE_NUM];
|
||||
json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
|
||||
nm_json_t *found_keys[_NM_TEAM_ATTRIBUTE_NUM] = { NULL, };
|
||||
gs_unref_ptrarray GPtrArray *ptr_array_master_runner_tx_hash_free = NULL;
|
||||
gs_unref_ptrarray GPtrArray *ptr_array_link_watchers_free = NULL;
|
||||
|
||||
_js_parse_locate_keys (self,
|
||||
_js_parse_locate_keys (vt,
|
||||
self,
|
||||
root_js_obj,
|
||||
found_keys,
|
||||
&unrecognized_content);
|
||||
|
||||
_js_parse_unpack (self->d.is_port,
|
||||
_js_parse_unpack (vt,
|
||||
self->d.is_port,
|
||||
found_keys,
|
||||
has_lst,
|
||||
val_lst,
|
||||
|
|
@ -1906,8 +1911,6 @@ nm_team_setting_config_set (NMTeamSetting *self, const char *js_str)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (do_set_default)
|
||||
changed_flags |= _team_setting_set_default (self);
|
||||
|
||||
|
|
@ -2222,6 +2225,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
|
|||
GVariantIter iter;
|
||||
const char *v_key;
|
||||
GVariant *v_val;
|
||||
const NMJsonVt *vt;
|
||||
|
||||
*out_changed = 0;
|
||||
|
||||
|
|
@ -2271,10 +2275,12 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
|
|||
variants[attr_data->team_attr] = g_steal_pointer (&v_val_free);
|
||||
}
|
||||
|
||||
vt = nm_json_vt ();
|
||||
|
||||
if (variants[NM_TEAM_ATTRIBUTE_LINK_WATCHERS]) {
|
||||
|
||||
if ( variants[NM_TEAM_ATTRIBUTE_CONFIG]
|
||||
&& WITH_JSON_VALIDATION
|
||||
&& vt
|
||||
&& !NM_FLAGS_HAS (parse_flags, NM_SETTING_PARSE_FLAGS_STRICT)) {
|
||||
/* we don't require the content of the "link-watchers" and we also
|
||||
* don't perform strict validation. No need to parse it. */
|
||||
|
|
@ -2282,7 +2288,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
|
|||
gs_free_error GError *local = NULL;
|
||||
|
||||
/* We might need the parsed v_link_watchers array below (because there is no JSON
|
||||
* "config" present or because we don't build WITH_JSON_VALIDATION).
|
||||
* "config" present or because we don't have json support).
|
||||
*
|
||||
* Or we might run with NM_SETTING_PARSE_FLAGS_STRICT. In that mode, we may not necessarily
|
||||
* require that the entire setting as a whole validates (if a JSON config is present and
|
||||
|
|
@ -2310,7 +2316,7 @@ nm_team_setting_reset_from_dbus (NMTeamSetting *self,
|
|||
? g_variant_get_string (variants[NM_TEAM_ATTRIBUTE_CONFIG], NULL)
|
||||
: NULL);
|
||||
|
||||
if ( WITH_JSON_VALIDATION
|
||||
if ( vt
|
||||
&& variants[NM_TEAM_ATTRIBUTE_CONFIG]) {
|
||||
/* for team settings, the JSON must be able to express all possible options. That means,
|
||||
* if the GVariant contains both the JSON "config" and other options, then the other options
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
#if WITH_JSON_VALIDATION
|
||||
#include "nm-json.h"
|
||||
#endif
|
||||
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "nm-glib-aux/nm-str-buf.h"
|
||||
#include "nm-glib-aux/nm-enum-utils.h"
|
||||
#include "nm-glib-aux/nm-time-utils.h"
|
||||
|
|
@ -5493,9 +5490,9 @@ _nm_utils_is_json_object_no_validation (const char *str, GError **error)
|
|||
gboolean
|
||||
nm_utils_is_json_object (const char *str, GError **error)
|
||||
{
|
||||
#if WITH_JSON_VALIDATION
|
||||
nm_auto_decref_json json_t *json = NULL;
|
||||
json_error_t jerror;
|
||||
nm_auto_decref_json nm_json_t *json = NULL;
|
||||
const NMJsonVt *vt;
|
||||
nm_json_error_t jerror;
|
||||
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
|
|
@ -5507,10 +5504,10 @@ nm_utils_is_json_object (const char *str, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_jansson_load ())
|
||||
if (!(vt = nm_json_vt ()))
|
||||
return _nm_utils_is_json_object_no_validation (str, error);
|
||||
|
||||
json = json_loads (str, JSON_REJECT_DUPLICATES, &jerror);
|
||||
json = vt->nm_json_loads (str, NM_JSON_REJECT_DUPLICATES, &jerror);
|
||||
if (!json) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
@ -5523,7 +5520,7 @@ nm_utils_is_json_object (const char *str, GError **error)
|
|||
|
||||
/* valid JSON (depending on the definition) can also be a literal.
|
||||
* Here we only allow objects. */
|
||||
if (!json_is_object (json)) {
|
||||
if (!nm_json_is_object (json)) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
|
|
@ -5532,19 +5529,6 @@ nm_utils_is_json_object (const char *str, GError **error)
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
#else /* !WITH_JSON_VALIDATION */
|
||||
g_return_val_if_fail (!error || !*error, FALSE);
|
||||
|
||||
if (!str || !str[0]) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
str ? _("value is NULL") : _("value is empty"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return _nm_utils_is_json_object_no_validation (str, error);
|
||||
#endif
|
||||
}
|
||||
|
||||
static char *
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "nm-std-aux/c-list-util.h"
|
||||
#include "nm-glib-aux/nm-enum-utils.h"
|
||||
#include "nm-glib-aux/nm-str-buf.h"
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "systemd/nm-sd-utils-shared.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
|
|
@ -7125,17 +7126,19 @@ test_nm_utils_check_valid_json (void)
|
|||
{
|
||||
_json_config_check_valid (NULL, FALSE);
|
||||
_json_config_check_valid ("", FALSE);
|
||||
#if WITH_JSON_VALIDATION
|
||||
_json_config_check_valid ("{ }", TRUE);
|
||||
_json_config_check_valid ("{ \"a\" : 1 }", TRUE);
|
||||
_json_config_check_valid ("{ \"a\" : }", FALSE);
|
||||
#else
|
||||
|
||||
/* Without JSON library everything except empty string is considered valid */
|
||||
nmtst_json_vt_reset (FALSE);
|
||||
_json_config_check_valid ("{ }", TRUE);
|
||||
_json_config_check_valid ("{'%!-a1} ", TRUE);
|
||||
_json_config_check_valid (" {'%!-a1}", TRUE);
|
||||
_json_config_check_valid ("{'%!-a1", FALSE);
|
||||
#endif
|
||||
|
||||
if (nmtst_json_vt_reset (TRUE)) {
|
||||
_json_config_check_valid ("{ }", TRUE);
|
||||
_json_config_check_valid ("{ \"a\" : 1 }", TRUE);
|
||||
_json_config_check_valid ("{ \"a\" : }", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -7172,86 +7175,96 @@ _team_config_equal_check (const char *conf1,
|
|||
static void
|
||||
test_nm_utils_team_config_equal (void)
|
||||
{
|
||||
_team_config_equal_check ("",
|
||||
"",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("",
|
||||
" ",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{}",
|
||||
"{ }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{}",
|
||||
"{",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"a\": 1 }",
|
||||
"{ \"a\": 1 }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"a\": 1 }",
|
||||
"{ \"a\": 1 }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
int with_json_vt;
|
||||
|
||||
/* team config */
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"loadbalance\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"loadbalance\"} }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
|
||||
FALSE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
|
||||
FALSE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\" ] } }",
|
||||
FALSE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
for (with_json_vt = 0; with_json_vt < 2; with_json_vt++) {
|
||||
const NMJsonVt *vt;
|
||||
|
||||
/* team port config */
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
|
||||
TRUE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
!WITH_JSON_VALIDATION);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
vt = nmtst_json_vt_reset (!!with_json_vt);
|
||||
|
||||
_team_config_equal_check ("",
|
||||
"",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("",
|
||||
" ",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{}",
|
||||
"{ }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{}",
|
||||
"{",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"a\": 1 }",
|
||||
"{ \"a\": 1 }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"a\": 1 }",
|
||||
"{ \"a\": 1 }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
|
||||
/* team config */
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"} }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"loadbalance\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"loadbalance\"} }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth0\" : {} } }",
|
||||
"{ \"runner\" : { \"name\" : \"random\"}, \"ports\" : { \"eth1\" : {} } }",
|
||||
FALSE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
|
||||
FALSE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"roundrobin\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"roundrobin\", \"tx_hash\" : [ \"eth\", \"ipv4\", \"ipv6\" ] } }",
|
||||
FALSE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ \"runner\" : { \"name\" : \"lacp\"} }",
|
||||
"{ \"runner\" : { \"name\" : \"lacp\", \"tx_hash\" : [ \"eth\" ] } }",
|
||||
FALSE,
|
||||
!vt);
|
||||
|
||||
/* team port config */
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
|
||||
TRUE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"ethtool\"} }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
!vt);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"} }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
_team_config_equal_check ("{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth0\" : {} } }",
|
||||
"{ \"link_watch\" : { \"name\" : \"arp_ping\"}, \"ports\" : { \"eth1\" : {} } }",
|
||||
TRUE,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
nmtst_json_vt_reset (TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "nm-keyfile/nm-keyfile-utils.h"
|
||||
#include "nm-keyfile/nm-keyfile-internal.h"
|
||||
#include "nm-simple-connection.h"
|
||||
|
|
@ -627,7 +628,7 @@ test_team_conf_read_invalid (void)
|
|||
gs_unref_object NMConnection *con = NULL;
|
||||
NMSettingTeam *s_team;
|
||||
|
||||
if (!WITH_JSON_VALIDATION) {
|
||||
if (!nm_json_vt ()) {
|
||||
g_test_skip ("team test requires JSON validation");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/pkt_sched.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-utils-private.h"
|
||||
|
|
@ -32,15 +33,6 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* assert that the define is just a plain integer (boolean). */
|
||||
|
||||
G_STATIC_ASSERT ( (WITH_JSON_VALIDATION) == 1
|
||||
|| (WITH_JSON_VALIDATION) == 0);
|
||||
|
||||
_nm_unused static const int _with_json_validation = WITH_JSON_VALIDATION;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* converts @dict to a connection. In this case, @dict must be good, without warnings, so that
|
||||
* NM_SETTING_PARSE_FLAGS_STRICT and NM_SETTING_PARSE_FLAGS_BEST_EFFORT yield the exact same results. */
|
||||
static NMConnection *
|
||||
|
|
@ -978,6 +970,24 @@ test_dcb_bandwidth_sums (void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_nm_json (void)
|
||||
{
|
||||
g_assert (NM_IN_SET (WITH_JANSSON, 0, 1));
|
||||
|
||||
#if WITH_JANSSON
|
||||
g_assert (nm_json_vt ());
|
||||
#else
|
||||
g_assert (!nm_json_vt ());
|
||||
#endif
|
||||
|
||||
#if WITH_JANSSON != defined (JANSSON_SONAME)
|
||||
#error "WITH_JANSON and JANSSON_SONAME are defined inconsistently."
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_test_team_config_sync (const char *team_config,
|
||||
int notify_peer_count,
|
||||
|
|
@ -1000,7 +1010,7 @@ _test_team_config_sync (const char *team_config,
|
|||
guint i, j;
|
||||
gboolean found;
|
||||
|
||||
if (!WITH_JSON_VALIDATION) {
|
||||
if (!nm_json_vt ()) {
|
||||
g_test_skip ("team test requires JSON validation");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1265,7 +1275,7 @@ _test_team_port_config_sync (const char *team_port_config,
|
|||
guint i, j;
|
||||
gboolean found;
|
||||
|
||||
if (!WITH_JSON_VALIDATION) {
|
||||
if (!nm_json_vt ()) {
|
||||
g_test_skip ("team test requires JSON validation");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1397,7 +1407,7 @@ _check_team_setting (NMSetting *setting)
|
|||
: nm_setting_team_get_config (NM_SETTING_TEAM (setting)),
|
||||
NULL);
|
||||
|
||||
if (WITH_JSON_VALIDATION)
|
||||
if (nm_json_vt ())
|
||||
nmtst_assert_setting_is_equal (setting, setting2, NM_SETTING_COMPARE_FLAG_EXACT);
|
||||
|
||||
g_clear_object (&setting2);
|
||||
|
|
@ -4095,6 +4105,7 @@ main (int argc, char **argv)
|
|||
g_test_add_func ("/libnm/settings/bridge/vlans", test_bridge_vlans);
|
||||
g_test_add_func ("/libnm/settings/bridge/verify", test_bridge_verify);
|
||||
|
||||
g_test_add_func ("/libnm/test_nm_json", test_nm_json);
|
||||
g_test_add_func ("/libnm/settings/team/sync_runner_from_config_roundrobin",
|
||||
test_runner_roundrobin_sync_from_config);
|
||||
g_test_add_func ("/libnm/settings/team/sync_runner_from_config_broadcast",
|
||||
|
|
|
|||
12
meson.build
12
meson.build
|
|
@ -253,9 +253,10 @@ libudev_dep = dependency('libudev', version: '>= 175')
|
|||
dbus_dep = dependency('dbus-1', version: '>= 1.1')
|
||||
libndp_dep = dependency('libndp')
|
||||
|
||||
jansson_dep = dependency('jansson', version: '>= 2.5', required: false)
|
||||
jansson_dep = dependency('jansson', version: '>= 2.7', required: false)
|
||||
config_h.set10('WITH_JANSSON', jansson_dep.found())
|
||||
|
||||
jansson_msg = 'no'
|
||||
if jansson_dep.found()
|
||||
jansson_libdir = jansson_dep.get_pkgconfig_variable('libdir')
|
||||
res = run_command(find_program('eu-readelf', 'readelf'), '-d', join_paths(jansson_libdir, 'libjansson.so'))
|
||||
|
|
@ -267,6 +268,7 @@ if jansson_dep.found()
|
|||
endforeach
|
||||
assert(jansson_soname != '', 'Unable to determine Jansson SONAME')
|
||||
config_h.set_quoted('JANSSON_SONAME', jansson_soname)
|
||||
jansson_msg = 'yes (soname: ' + jansson_soname + ')'
|
||||
endif
|
||||
|
||||
libsystemd_dep = dependency('libsystemd', version: '>= 209', required: false)
|
||||
|
|
@ -497,12 +499,6 @@ if enable_teamdctl
|
|||
assert(libteamdctl_dep.found(), 'You must have libteamdctl installed to build. Use -Dteamdctl=false to disable it')
|
||||
endif
|
||||
|
||||
enable_json_validation = get_option('json_validation')
|
||||
if enable_json_validation
|
||||
assert(jansson_dep.found(), 'jansson is needed for team configuration validation. Use -Djson_validation=false to disable it')
|
||||
endif
|
||||
config_h.set10('WITH_JSON_VALIDATION', enable_json_validation)
|
||||
|
||||
# polkit
|
||||
enable_polkit = get_option('polkit')
|
||||
if enable_polkit
|
||||
|
|
@ -1013,6 +1009,7 @@ if enable_ppp
|
|||
output += ' ' + pppd_path + ' plugins:' + pppd_plugin_dir
|
||||
endif
|
||||
output += '\n'
|
||||
output += ' jansson: ' + jansson_msg + '\n'
|
||||
output += ' modemmanager-1: ' + enable_modem_manager.to_string() + '\n'
|
||||
output += ' ofono: ' + enable_ofono.to_string() + '\n'
|
||||
output += ' concheck: ' + enable_concheck.to_string() + '\n'
|
||||
|
|
@ -1047,7 +1044,6 @@ output += '\n'
|
|||
output += ' code coverage: ' + get_option('b_coverage').to_string() + '\n'
|
||||
output += ' LTO: ' + enable_lto.to_string() + '\n'
|
||||
output += ' Linker garbage collection: ' + enable_ld_gc.to_string() + '\n'
|
||||
output += ' JSON validation for libnm: ' + enable_json_validation.to_string() + '\n'
|
||||
output += ' crypto: ' + crypto + '\n'
|
||||
output += ' sanitizers: ' + get_option('b_sanitize') + '\n'
|
||||
output += ' Mozilla Public Suffix List: ' + enable_libpsl.to_string() + '\n'
|
||||
|
|
|
|||
|
|
@ -69,6 +69,5 @@ option('valgrind', type: 'array', value: ['no'], description: 'Use valgrind to m
|
|||
option('valgrind_suppressions', type: 'string', value: '', description: 'Use specific valgrind suppression file')
|
||||
option('ld_gc', type: 'boolean', value: true, description: 'Enable garbage collection of unused symbols on linking')
|
||||
option('libpsl', type: 'boolean', value: true, description: 'Link against libpsl')
|
||||
option('json_validation', type: 'boolean', value: true, description: 'Enable JSON validation in libnm')
|
||||
option('crypto', type: 'combo', choices: ['nss', 'gnutls'], value: 'nss', description: 'Cryptography library to use for certificate and key operations')
|
||||
option('qt', type: 'boolean', value: true, description: 'enable Qt examples')
|
||||
|
|
|
|||
|
|
@ -12,11 +12,6 @@
|
|||
|
||||
#include <jansson.h>
|
||||
|
||||
/* Added in Jansson v2.7 */
|
||||
#ifndef json_boolean_value
|
||||
#define json_boolean_value json_is_true
|
||||
#endif
|
||||
|
||||
/* Added in Jansson v2.8 */
|
||||
#ifndef json_object_foreach_safe
|
||||
#define json_object_foreach_safe(object, n, key, value) \
|
||||
|
|
@ -30,106 +25,6 @@
|
|||
NM_AUTO_DEFINE_FCN0 (json_t *, _nm_auto_decref_json, json_decref)
|
||||
#define nm_auto_decref_json nm_auto(_nm_auto_decref_json)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_bool (const json_t *elem,
|
||||
bool *out_val)
|
||||
{
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!json_is_boolean (elem))
|
||||
return -EINVAL;
|
||||
|
||||
NM_SET_OUT (out_val, json_boolean_value (elem));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_int32 (const json_t *elem,
|
||||
gint32 *out_val)
|
||||
{
|
||||
json_int_t v;
|
||||
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!json_is_integer (elem))
|
||||
return -EINVAL;
|
||||
|
||||
v = json_integer_value (elem);
|
||||
if ( v < (gint64) G_MININT32
|
||||
|| v > (gint64) G_MAXINT32)
|
||||
return -ERANGE;
|
||||
|
||||
NM_SET_OUT (out_val, v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_int (const json_t *elem,
|
||||
int *out_val)
|
||||
{
|
||||
json_int_t v;
|
||||
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!json_is_integer (elem))
|
||||
return -EINVAL;
|
||||
|
||||
v = json_integer_value (elem);
|
||||
if ( v < (gint64) G_MININT
|
||||
|| v > (gint64) G_MAXINT)
|
||||
return -ERANGE;
|
||||
|
||||
NM_SET_OUT (out_val, v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_string (const json_t *elem,
|
||||
const char **out_val)
|
||||
{
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!json_is_string (elem))
|
||||
return -EINVAL;
|
||||
|
||||
NM_SET_OUT (out_val, json_string_value (elem));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS
|
||||
#include "nm-value-type.h"
|
||||
static inline gboolean
|
||||
nm_value_type_from_json (NMValueType value_type,
|
||||
const json_t *elem,
|
||||
gpointer out_val)
|
||||
{
|
||||
switch (value_type) {
|
||||
case NM_VALUE_TYPE_BOOL: return (nm_jansson_json_as_bool (elem, out_val) > 0);
|
||||
case NM_VALUE_TYPE_INT32: return (nm_jansson_json_as_int32 (elem, out_val) > 0);
|
||||
case NM_VALUE_TYPE_INT: return (nm_jansson_json_as_int (elem, out_val) > 0);
|
||||
|
||||
/* warning: this overwrites/leaks the previous value. You better have *out_val
|
||||
* point to uninitialized memory or NULL. */
|
||||
case NM_VALUE_TYPE_STRING: return (nm_jansson_json_as_string (elem, out_val) > 0);
|
||||
|
||||
case NM_VALUE_TYPE_UNSPEC:
|
||||
break;
|
||||
}
|
||||
nm_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* WITH_JANSON */
|
||||
|
||||
#endif /* __NM_JANSSON_H__ */
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
* Copyright (C) 2017 - 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-json-aux.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -96,9 +98,9 @@ _gstr_append_string_len (GString *gstr,
|
|||
}
|
||||
|
||||
void
|
||||
nm_json_aux_gstr_append_string_len (GString *gstr,
|
||||
const char *str,
|
||||
gsize n)
|
||||
nm_json_gstr_append_string_len (GString *gstr,
|
||||
const char *str,
|
||||
gsize n)
|
||||
{
|
||||
g_return_if_fail (gstr);
|
||||
|
||||
|
|
@ -106,8 +108,8 @@ nm_json_aux_gstr_append_string_len (GString *gstr,
|
|||
}
|
||||
|
||||
void
|
||||
nm_json_aux_gstr_append_string (GString *gstr,
|
||||
const char *str)
|
||||
nm_json_gstr_append_string (GString *gstr,
|
||||
const char *str)
|
||||
{
|
||||
g_return_if_fail (gstr);
|
||||
|
||||
|
|
@ -118,14 +120,14 @@ nm_json_aux_gstr_append_string (GString *gstr,
|
|||
}
|
||||
|
||||
void
|
||||
nm_json_aux_gstr_append_obj_name (GString *gstr,
|
||||
const char *key,
|
||||
char start_container)
|
||||
nm_json_gstr_append_obj_name (GString *gstr,
|
||||
const char *key,
|
||||
char start_container)
|
||||
{
|
||||
g_return_if_fail (gstr);
|
||||
g_return_if_fail (key);
|
||||
|
||||
nm_json_aux_gstr_append_string (gstr, key);
|
||||
nm_json_gstr_append_string (gstr, key);
|
||||
|
||||
if (start_container != '\0') {
|
||||
nm_assert (NM_IN_SET (start_container, '[', '{'));
|
||||
|
|
@ -133,3 +135,136 @@ nm_json_aux_gstr_append_obj_name (GString *gstr,
|
|||
} else
|
||||
g_string_append (gstr, ": ");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMJsonVt vt;
|
||||
void *dl_handle;
|
||||
} NMJsonVtInternal;
|
||||
|
||||
static NMJsonVtInternal *
|
||||
_nm_json_vt_internal_load (void)
|
||||
{
|
||||
NMJsonVtInternal *v;
|
||||
const char *soname;
|
||||
void *handle;
|
||||
|
||||
v = g_new0 (NMJsonVtInternal, 1);
|
||||
|
||||
#if WITH_JANSSON && defined (JANSSON_SONAME)
|
||||
G_STATIC_ASSERT_EXPR (NM_STRLEN (JANSSON_SONAME) > 0);
|
||||
nm_assert (strlen (JANSSON_SONAME) > 0);
|
||||
soname = JANSSON_SONAME;
|
||||
#elif !WITH_JANSSON && !defined (JANSSON_SONAME)
|
||||
soname = NULL;
|
||||
#else
|
||||
#error "WITH_JANSON and JANSSON_SONAME are defined inconsistently."
|
||||
#endif
|
||||
|
||||
if (!soname)
|
||||
return v;
|
||||
|
||||
handle = dlopen (soname, RTLD_LAZY
|
||||
| RTLD_LOCAL
|
||||
| RTLD_NODELETE
|
||||
#if !defined (ASAN_BUILD)
|
||||
| RTLD_DEEPBIND
|
||||
#endif
|
||||
| 0);
|
||||
if (!handle)
|
||||
return v;
|
||||
|
||||
#define TRY_BIND_SYMBOL(symbol) \
|
||||
G_STMT_START { \
|
||||
void *_sym = dlsym (handle, #symbol); \
|
||||
\
|
||||
if (!_sym) \
|
||||
goto fail_symbol; \
|
||||
v->vt.nm_ ## symbol = _sym; \
|
||||
} G_STMT_END
|
||||
|
||||
TRY_BIND_SYMBOL (json_array);
|
||||
TRY_BIND_SYMBOL (json_array_append_new);
|
||||
TRY_BIND_SYMBOL (json_array_get);
|
||||
TRY_BIND_SYMBOL (json_array_size);
|
||||
TRY_BIND_SYMBOL (json_delete);
|
||||
TRY_BIND_SYMBOL (json_dumps);
|
||||
TRY_BIND_SYMBOL (json_false);
|
||||
TRY_BIND_SYMBOL (json_integer);
|
||||
TRY_BIND_SYMBOL (json_integer_value);
|
||||
TRY_BIND_SYMBOL (json_loads);
|
||||
TRY_BIND_SYMBOL (json_object);
|
||||
TRY_BIND_SYMBOL (json_object_del);
|
||||
TRY_BIND_SYMBOL (json_object_get);
|
||||
TRY_BIND_SYMBOL (json_object_iter);
|
||||
TRY_BIND_SYMBOL (json_object_iter_key);
|
||||
TRY_BIND_SYMBOL (json_object_iter_next);
|
||||
TRY_BIND_SYMBOL (json_object_iter_value);
|
||||
TRY_BIND_SYMBOL (json_object_key_to_iter);
|
||||
TRY_BIND_SYMBOL (json_object_set_new);
|
||||
TRY_BIND_SYMBOL (json_object_size);
|
||||
TRY_BIND_SYMBOL (json_string);
|
||||
TRY_BIND_SYMBOL (json_string_value);
|
||||
TRY_BIND_SYMBOL (json_true);
|
||||
|
||||
v->vt.loaded = TRUE;
|
||||
v->dl_handle = handle;
|
||||
return v;
|
||||
|
||||
fail_symbol:
|
||||
dlclose (&handle);
|
||||
*v = (NMJsonVtInternal) { };
|
||||
return v;
|
||||
}
|
||||
|
||||
const NMJsonVt *_nm_json_vt_ptr = NULL;
|
||||
|
||||
const NMJsonVt *
|
||||
_nm_json_vt_init (void)
|
||||
{
|
||||
NMJsonVtInternal *v;
|
||||
|
||||
again:
|
||||
v = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
|
||||
if (G_UNLIKELY (!v)) {
|
||||
v = _nm_json_vt_internal_load ();
|
||||
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, NULL, v)) {
|
||||
if (v->dl_handle)
|
||||
dlclose (v->dl_handle);
|
||||
g_free (v);
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* we transfer ownership. */
|
||||
}
|
||||
|
||||
nm_assert (v && v == g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr));
|
||||
return &v->vt;
|
||||
}
|
||||
|
||||
const NMJsonVt *
|
||||
nmtst_json_vt_reset (gboolean loaded)
|
||||
{
|
||||
NMJsonVtInternal *v_old;
|
||||
NMJsonVtInternal *v;
|
||||
|
||||
v_old = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
|
||||
|
||||
if (!loaded) {
|
||||
/* load a fake instance for testing. */
|
||||
v = g_new0 (NMJsonVtInternal, 1);
|
||||
} else
|
||||
v = _nm_json_vt_internal_load ();
|
||||
|
||||
if (!g_atomic_pointer_compare_and_exchange ((gpointer *) &_nm_json_vt_ptr, v_old, v))
|
||||
g_assert_not_reached ();
|
||||
|
||||
if (v_old) {
|
||||
if (v_old->dl_handle)
|
||||
dlclose (v_old->dl_handle);
|
||||
g_free ((gpointer *) v_old);
|
||||
}
|
||||
|
||||
return v->vt.loaded ? &v->vt : NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,281 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/*
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
* Copyright (C) 2017 - 2019 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_JSON_AUX_H__
|
||||
#define __NM_JSON_AUX_H__
|
||||
|
||||
#include "nm-value-type.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline GString *
|
||||
nm_json_aux_gstr_append_delimiter (GString *gstr)
|
||||
nm_json_gstr_append_delimiter (GString *gstr)
|
||||
{
|
||||
g_string_append (gstr, ", ");
|
||||
return gstr;
|
||||
}
|
||||
|
||||
void nm_json_aux_gstr_append_string_len (GString *gstr,
|
||||
const char *str,
|
||||
gsize n);
|
||||
void nm_json_gstr_append_string_len (GString *gstr,
|
||||
const char *str,
|
||||
gsize n);
|
||||
|
||||
void nm_json_aux_gstr_append_string (GString *gstr,
|
||||
const char *str);
|
||||
void nm_json_gstr_append_string (GString *gstr,
|
||||
const char *str);
|
||||
|
||||
static inline void
|
||||
nm_json_aux_gstr_append_bool (GString *gstr,
|
||||
gboolean v)
|
||||
nm_json_gstr_append_bool (GString *gstr,
|
||||
gboolean v)
|
||||
{
|
||||
g_string_append (gstr, v ? "true" : "false");
|
||||
}
|
||||
|
||||
static inline void
|
||||
nm_json_aux_gstr_append_int64 (GString *gstr,
|
||||
gint64 v)
|
||||
nm_json_gstr_append_int64 (GString *gstr,
|
||||
gint64 v)
|
||||
{
|
||||
g_string_append_printf (gstr, "%"G_GINT64_FORMAT, v);
|
||||
}
|
||||
|
||||
void nm_json_aux_gstr_append_obj_name (GString *gstr,
|
||||
const char *key,
|
||||
char start_container);
|
||||
void nm_json_gstr_append_obj_name (GString *gstr,
|
||||
const char *key,
|
||||
char start_container);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_JSON_REJECT_DUPLICATES 0x1
|
||||
|
||||
typedef enum {
|
||||
NM_JSON_OBJECT,
|
||||
NM_JSON_ARRAY,
|
||||
NM_JSON_STRING,
|
||||
NM_JSON_INTEGER,
|
||||
NM_JSON_REAL,
|
||||
NM_JSON_TRUE,
|
||||
NM_JSON_FALSE,
|
||||
NM_JSON_NULL,
|
||||
} nm_json_type;
|
||||
|
||||
typedef struct nm_json_t {
|
||||
nm_json_type type;
|
||||
volatile size_t refcount;
|
||||
} nm_json_t;
|
||||
|
||||
typedef long long nm_json_int_t;
|
||||
|
||||
#define NM_JSON_ERROR_TEXT_LENGTH 160
|
||||
#define NM_JSON_ERROR_SOURCE_LENGTH 80
|
||||
|
||||
typedef struct nm_json_error_t {
|
||||
int line;
|
||||
int column;
|
||||
int position;
|
||||
char source[NM_JSON_ERROR_SOURCE_LENGTH];
|
||||
char text[NM_JSON_ERROR_TEXT_LENGTH];
|
||||
} nm_json_error_t;
|
||||
|
||||
typedef struct {
|
||||
gboolean loaded;
|
||||
char *(*nm_json_dumps) (const nm_json_t *json, size_t flags);
|
||||
const char *(*nm_json_object_iter_key) (void *iter);
|
||||
const char *(*nm_json_string_value) (const nm_json_t *json);
|
||||
int (*nm_json_array_append_new) (nm_json_t *json, nm_json_t *value);
|
||||
int (*nm_json_object_del) (nm_json_t *json, const char *key);
|
||||
int (*nm_json_object_set_new) (nm_json_t *json, const char *key, nm_json_t *value);
|
||||
nm_json_int_t (*nm_json_integer_value) (const nm_json_t *json);
|
||||
nm_json_t *(*nm_json_array) (void);
|
||||
nm_json_t *(*nm_json_array_get) (const nm_json_t *json, size_t index);
|
||||
nm_json_t *(*nm_json_false) (void);
|
||||
nm_json_t *(*nm_json_integer) (nm_json_int_t value);
|
||||
nm_json_t *(*nm_json_loads) (const char *string, size_t flags, nm_json_error_t *error);
|
||||
nm_json_t *(*nm_json_object) (void);
|
||||
nm_json_t *(*nm_json_object_get) (const nm_json_t *json, const char *key);
|
||||
nm_json_t *(*nm_json_object_iter_value) (void *);
|
||||
nm_json_t *(*nm_json_string) (const char *value);
|
||||
nm_json_t *(*nm_json_true) (void);
|
||||
size_t (*nm_json_array_size) (const nm_json_t *json);
|
||||
size_t (*nm_json_object_size) (const nm_json_t *json);
|
||||
void (*nm_json_delete) (nm_json_t *json);
|
||||
void *(*nm_json_object_iter) (nm_json_t *json);
|
||||
void *(*nm_json_object_iter_next) (nm_json_t *json, void *iter);
|
||||
void *(*nm_json_object_key_to_iter) (const char *key);
|
||||
} NMJsonVt;
|
||||
|
||||
extern const NMJsonVt *_nm_json_vt_ptr;
|
||||
|
||||
const NMJsonVt *_nm_json_vt_init (void);
|
||||
|
||||
static inline const NMJsonVt *
|
||||
_nm_json_vt (void)
|
||||
{
|
||||
const NMJsonVt *vt;
|
||||
|
||||
vt = g_atomic_pointer_get ((gpointer *) &_nm_json_vt_ptr);
|
||||
if (G_UNLIKELY (!vt)) {
|
||||
vt = _nm_json_vt_init ();
|
||||
nm_assert (vt);
|
||||
}
|
||||
return vt;
|
||||
}
|
||||
|
||||
static inline const NMJsonVt *
|
||||
nm_json_vt (void)
|
||||
{
|
||||
const NMJsonVt *vt;
|
||||
|
||||
vt = _nm_json_vt();
|
||||
return vt->loaded ? vt : NULL;
|
||||
}
|
||||
|
||||
static inline const NMJsonVt *
|
||||
nm_json_vt_assert (void)
|
||||
{
|
||||
const NMJsonVt *vt;
|
||||
|
||||
vt = _nm_json_vt();
|
||||
nm_assert (vt->loaded);
|
||||
return vt;
|
||||
}
|
||||
|
||||
const NMJsonVt *nmtst_json_vt_reset (gboolean loaded);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_json_boolean(vt, val) \
|
||||
((val) ? (vt)->nm_json_true () : (vt)->nm_json_false ())
|
||||
|
||||
static inline void
|
||||
nm_json_decref (const NMJsonVt *vt, nm_json_t *json)
|
||||
{
|
||||
/* Our ref-counting is not threadsafe, unlike libjansson's. But we never
|
||||
* share one json_t instance between threads, and if we would, we would very likely
|
||||
* wrap a mutex around it. */
|
||||
if ( json
|
||||
&& json->refcount != (size_t) -1
|
||||
&& --json->refcount == 0)
|
||||
vt->nm_json_delete (json);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_nm_auto_decref_json (nm_json_t **p_json)
|
||||
{
|
||||
if ( *p_json
|
||||
&& (*p_json)->refcount != (size_t) -1
|
||||
&& --(*p_json)->refcount == 0)
|
||||
nm_json_vt ()->nm_json_delete (*p_json);
|
||||
}
|
||||
|
||||
#define nm_auto_decref_json nm_auto(_nm_auto_decref_json)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* the following are implemented as pure macros in jansson.h.
|
||||
* They can be used directly, however, add a nm_json* variant,
|
||||
* to make it explict we don't accidentally use jansson ABI. */
|
||||
|
||||
#define nm_json_typeof(json) ((json)->type)
|
||||
#define nm_json_is_object(json) ((json) && nm_json_typeof(json) == NM_JSON_OBJECT)
|
||||
#define nm_json_is_array(json) ((json) && nm_json_typeof(json) == NM_JSON_ARRAY)
|
||||
#define nm_json_is_string(json) ((json) && nm_json_typeof(json) == NM_JSON_STRING)
|
||||
#define nm_json_is_integer(json) ((json) && nm_json_typeof(json) == NM_JSON_INTEGER)
|
||||
#define nm_json_is_real(json) ((json) && nm_json_typeof(json) == NM_JSON_REAL)
|
||||
#define nm_json_is_number(json) (nm_json_is_integer(json) || nm_json_is_real(json))
|
||||
#define nm_json_is_true(json) ((json) && nm_json_typeof(json) == NM_JSON_TRUE)
|
||||
#define nm_json_is_false(json) ((json) && nm_json_typeof(json) == NM_JSON_FALSE)
|
||||
#define nm_json_boolean_value nm_json_is_true
|
||||
#define nm_json_is_boolean(json) (nm_json_is_true(json) || nm_json_is_false(json))
|
||||
#define nm_json_is_null(json) ((json) && nm_json_typeof(json) == NM_JSON_NULL)
|
||||
|
||||
#define nm_json_array_foreach(vt, array, index, value) \
|
||||
for(index = 0; \
|
||||
index < vt->nm_json_array_size (array) && (value = vt->nm_json_array_get (array, index)); \
|
||||
index++)
|
||||
|
||||
#define nm_json_object_foreach(vt, object, key, value) \
|
||||
for(key = vt->nm_json_object_iter_key (vt->nm_json_object_iter (object)); \
|
||||
key && (value = vt->nm_json_object_iter_value (vt->nm_json_object_key_to_iter (key))); \
|
||||
key = vt->nm_json_object_iter_key (vt->nm_json_object_iter_next (object, vt->nm_json_object_key_to_iter (key))))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_bool (const nm_json_t *elem,
|
||||
bool *out_val)
|
||||
{
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!nm_json_is_boolean (elem))
|
||||
return -EINVAL;
|
||||
|
||||
NM_SET_OUT (out_val, nm_json_boolean_value (elem));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_int32 (const NMJsonVt *vt,
|
||||
const nm_json_t *elem,
|
||||
gint32 *out_val)
|
||||
{
|
||||
nm_json_int_t v;
|
||||
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!nm_json_is_integer (elem))
|
||||
return -EINVAL;
|
||||
|
||||
v = vt->nm_json_integer_value (elem);
|
||||
if ( v < (gint64) G_MININT32
|
||||
|| v > (gint64) G_MAXINT32)
|
||||
return -ERANGE;
|
||||
|
||||
NM_SET_OUT (out_val, v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_int (const NMJsonVt *vt,
|
||||
const nm_json_t *elem,
|
||||
int *out_val)
|
||||
{
|
||||
nm_json_int_t v;
|
||||
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!nm_json_is_integer (elem))
|
||||
return -EINVAL;
|
||||
|
||||
v = vt->nm_json_integer_value (elem);
|
||||
if ( v < (gint64) G_MININT
|
||||
|| v > (gint64) G_MAXINT)
|
||||
return -ERANGE;
|
||||
|
||||
NM_SET_OUT (out_val, v);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_jansson_json_as_string (const NMJsonVt *vt,
|
||||
const nm_json_t *elem,
|
||||
const char **out_val)
|
||||
{
|
||||
if (!elem)
|
||||
return 0;
|
||||
|
||||
if (!nm_json_is_string (elem))
|
||||
return -EINVAL;
|
||||
|
||||
NM_SET_OUT (out_val, vt->nm_json_string_value (elem));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef NM_VALUE_TYPE_DEFINE_FUNCTIONS
|
||||
#include "nm-value-type.h"
|
||||
|
||||
static inline void
|
||||
nm_value_type_to_json (NMValueType value_type,
|
||||
GString *gstr,
|
||||
|
|
@ -53,17 +285,38 @@ nm_value_type_to_json (NMValueType value_type,
|
|||
nm_assert (gstr);
|
||||
|
||||
switch (value_type) {
|
||||
case NM_VALUE_TYPE_BOOL: nm_json_aux_gstr_append_bool (gstr, *((const bool *) p_field)); return;
|
||||
case NM_VALUE_TYPE_INT32: nm_json_aux_gstr_append_int64 (gstr, *((const gint32 *) p_field)); return;
|
||||
case NM_VALUE_TYPE_INT: nm_json_aux_gstr_append_int64 (gstr, *((const int *) p_field)); return;
|
||||
case NM_VALUE_TYPE_STRING: nm_json_aux_gstr_append_string (gstr, *((const char *const *) p_field)); return;
|
||||
case NM_VALUE_TYPE_BOOL: nm_json_gstr_append_bool (gstr, *((const bool *) p_field)); return;
|
||||
case NM_VALUE_TYPE_INT32: nm_json_gstr_append_int64 (gstr, *((const gint32 *) p_field)); return;
|
||||
case NM_VALUE_TYPE_INT: nm_json_gstr_append_int64 (gstr, *((const int *) p_field)); return;
|
||||
case NM_VALUE_TYPE_STRING: nm_json_gstr_append_string (gstr, *((const char *const *) p_field)); return;
|
||||
case NM_VALUE_TYPE_UNSPEC:
|
||||
break;
|
||||
}
|
||||
nm_assert_not_reached ();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
static inline gboolean
|
||||
nm_value_type_from_json (const NMJsonVt *vt,
|
||||
NMValueType value_type,
|
||||
const nm_json_t *elem,
|
||||
gpointer out_val)
|
||||
{
|
||||
switch (value_type) {
|
||||
case NM_VALUE_TYPE_BOOL: return (nm_jansson_json_as_bool (elem, out_val) > 0);
|
||||
case NM_VALUE_TYPE_INT32: return (nm_jansson_json_as_int32 (vt, elem, out_val) > 0);
|
||||
case NM_VALUE_TYPE_INT: return (nm_jansson_json_as_int (vt, elem, out_val) > 0);
|
||||
|
||||
#endif /* __NM_JSON_AUX_H__ */
|
||||
/* warning: this overwrites/leaks the previous value. You better have *out_val
|
||||
* point to uninitialized memory or NULL. */
|
||||
case NM_VALUE_TYPE_STRING: return (nm_jansson_json_as_string (vt, elem, out_val) > 0);
|
||||
|
||||
case NM_VALUE_TYPE_UNSPEC:
|
||||
break;
|
||||
}
|
||||
nm_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* NM_VALUE_TYPE_DEFINE_FUNCTIONS */
|
||||
|
||||
#endif /* __NM_JSON_AUX_H__ */
|
||||
|
|
|
|||
|
|
@ -1,23 +1,43 @@
|
|||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
test_unit = 'test-shared-general'
|
||||
|
||||
c_flags = [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)',
|
||||
]
|
||||
|
||||
exe = executable(
|
||||
test_unit,
|
||||
test_unit + '.c',
|
||||
c_args: c_flags,
|
||||
'test-shared-general',
|
||||
'test-shared-general.c',
|
||||
c_args: [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)',
|
||||
],
|
||||
dependencies: libnm_utils_base_dep,
|
||||
link_with: libnm_systemd_logging_stub,
|
||||
)
|
||||
|
||||
test(
|
||||
'shared/nm-glib-aux/' + test_unit,
|
||||
'shared/nm-glib-aux/test-shared-general',
|
||||
test_script,
|
||||
args: test_args + [exe.full_path()],
|
||||
timeout: default_test_timeout,
|
||||
)
|
||||
|
||||
if jansson_dep.found()
|
||||
exe = executable(
|
||||
'test-json-aux',
|
||||
'test-json-aux.c',
|
||||
c_args: [
|
||||
'-DNETWORKMANAGER_COMPILATION_TEST',
|
||||
'-DNETWORKMANAGER_COMPILATION=(NM_NETWORKMANAGER_COMPILATION_GLIB|NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG)',
|
||||
],
|
||||
dependencies: [
|
||||
libnm_utils_base_dep,
|
||||
jansson_dep,
|
||||
dl_dep,
|
||||
],
|
||||
link_with: libnm_systemd_logging_stub,
|
||||
)
|
||||
|
||||
test(
|
||||
'shared/nm-glib-aux/test-json-aux',
|
||||
test_script,
|
||||
args: test_args + [exe.full_path()],
|
||||
timeout: default_test_timeout,
|
||||
)
|
||||
endif
|
||||
|
|
|
|||
163
shared/nm-glib-aux/tests/test-json-aux.c
Normal file
163
shared/nm-glib-aux/tests/test-json-aux.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
|
||||
#define NM_TEST_UTILS_NO_LIBNM 1
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
|
||||
#include "nm-utils/nm-test-utils.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_jansson (void)
|
||||
{
|
||||
const NMJsonVt *vt;
|
||||
nm_auto_decref_json nm_json_t *js1 = NULL;
|
||||
nm_auto_decref_json nm_json_t *js2 = NULL;
|
||||
|
||||
#define _ASSERT_FIELD(type1, type2, field) \
|
||||
G_STMT_START { \
|
||||
G_STATIC_ASSERT_EXPR (sizeof (((type1 *) NULL)->field) == sizeof (((type2 *) NULL)->field)); \
|
||||
G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (type1, field) == G_STRUCT_OFFSET (type2, field)); \
|
||||
} G_STMT_END
|
||||
|
||||
G_STATIC_ASSERT_EXPR (NM_JSON_REJECT_DUPLICATES == JSON_REJECT_DUPLICATES);
|
||||
|
||||
G_STATIC_ASSERT_EXPR (sizeof (nm_json_type) == sizeof (json_type));
|
||||
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_OBJECT == JSON_OBJECT);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_ARRAY == JSON_ARRAY);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_STRING == JSON_STRING);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_INTEGER == JSON_INTEGER);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_REAL == JSON_REAL);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_TRUE == JSON_TRUE);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_FALSE == JSON_FALSE);
|
||||
G_STATIC_ASSERT_EXPR ((int) NM_JSON_NULL == JSON_NULL);
|
||||
|
||||
G_STATIC_ASSERT_EXPR (sizeof (nm_json_int_t) == sizeof (json_int_t));
|
||||
|
||||
G_STATIC_ASSERT_EXPR (sizeof (nm_json_t) == sizeof (json_t));
|
||||
_ASSERT_FIELD (nm_json_t, json_t, refcount);
|
||||
_ASSERT_FIELD (nm_json_t, json_t, type);
|
||||
|
||||
G_STATIC_ASSERT_EXPR (NM_JSON_ERROR_TEXT_LENGTH == JSON_ERROR_TEXT_LENGTH);
|
||||
G_STATIC_ASSERT_EXPR (NM_JSON_ERROR_SOURCE_LENGTH == JSON_ERROR_SOURCE_LENGTH);
|
||||
|
||||
G_STATIC_ASSERT_EXPR (sizeof (nm_json_error_t) == sizeof (json_error_t));
|
||||
_ASSERT_FIELD (nm_json_error_t, json_error_t, line);
|
||||
_ASSERT_FIELD (nm_json_error_t, json_error_t, column);
|
||||
_ASSERT_FIELD (nm_json_error_t, json_error_t, position);
|
||||
_ASSERT_FIELD (nm_json_error_t, json_error_t, source);
|
||||
_ASSERT_FIELD (nm_json_error_t, json_error_t, text);
|
||||
|
||||
vt = nm_json_vt ();
|
||||
|
||||
g_assert (vt);
|
||||
g_assert (vt->loaded);
|
||||
|
||||
js1 = vt->nm_json_loads ("{ \"a\": 5 }", 0, NULL);
|
||||
g_assert (js1);
|
||||
nm_json_decref (vt, g_steal_pointer (&js1));
|
||||
|
||||
js2 = vt->nm_json_loads ("{ \"a\": 6 }", 0, NULL);
|
||||
g_assert (js2);
|
||||
|
||||
#define CHECK_FCN(vt, fcn, nm_type, js_type) \
|
||||
G_STMT_START { \
|
||||
const NMJsonVt *const _vt = (vt); \
|
||||
_nm_unused nm_type = (_vt->nm_##fcn); \
|
||||
_nm_unused js_type = (fcn); \
|
||||
\
|
||||
g_assert (_vt->nm_##fcn); \
|
||||
g_assert (_f_nm); \
|
||||
g_assert (_f_js); \
|
||||
g_assert (_f_nm == _vt->nm_##fcn); \
|
||||
} G_STMT_END
|
||||
|
||||
CHECK_FCN (vt, json_array,
|
||||
nm_json_t *(*_f_nm) (void),
|
||||
json_t *(*_f_js) (void));
|
||||
CHECK_FCN (vt, json_array_append_new,
|
||||
int (*_f_nm) (nm_json_t *, nm_json_t *),
|
||||
int (*_f_js) ( json_t *, json_t *));
|
||||
CHECK_FCN (vt, json_array_get,
|
||||
nm_json_t *(*_f_nm) (const nm_json_t *, gsize ),
|
||||
json_t *(*_f_js) (const json_t *, size_t));
|
||||
CHECK_FCN (vt, json_array_size,
|
||||
gsize (*_f_nm) (const nm_json_t *),
|
||||
size_t (*_f_js) (const json_t *));
|
||||
CHECK_FCN (vt, json_delete,
|
||||
void (*_f_nm) (nm_json_t *),
|
||||
void (*_f_js) ( json_t *));
|
||||
CHECK_FCN (vt, json_dumps,
|
||||
char *(*_f_nm) (const nm_json_t *, gsize ),
|
||||
char *(*_f_js) (const json_t *, size_t));
|
||||
CHECK_FCN (vt, json_false,
|
||||
nm_json_t *(*_f_nm) (void),
|
||||
json_t *(*_f_js) (void));
|
||||
CHECK_FCN (vt, json_integer,
|
||||
nm_json_t *(*_f_nm) (nm_json_int_t),
|
||||
json_t *(*_f_js) ( json_int_t));
|
||||
CHECK_FCN (vt, json_integer_value,
|
||||
nm_json_int_t (*_f_nm) (const nm_json_t *),
|
||||
json_int_t (*_f_js) (const json_t *));
|
||||
CHECK_FCN (vt, json_loads,
|
||||
nm_json_t *(*_f_nm) (const char *, gsize , nm_json_error_t *),
|
||||
json_t *(*_f_js) (const char *, size_t, json_error_t *));
|
||||
CHECK_FCN (vt, json_object,
|
||||
nm_json_t *(*_f_nm) (void),
|
||||
json_t *(*_f_js) (void));
|
||||
CHECK_FCN (vt, json_object_del,
|
||||
int (*_f_nm) (nm_json_t *, const char *),
|
||||
int (*_f_js) ( json_t *, const char *));
|
||||
CHECK_FCN (vt, json_object_get,
|
||||
nm_json_t *(*_f_nm) (const nm_json_t *, const char *),
|
||||
json_t *(*_f_js) (const json_t *, const char *));
|
||||
CHECK_FCN (vt, json_object_iter,
|
||||
void *(*_f_nm) (nm_json_t *),
|
||||
void *(*_f_js) ( json_t *));
|
||||
CHECK_FCN (vt, json_object_iter_key,
|
||||
const char *(*_f_nm) (void *),
|
||||
const char *(*_f_js) (void *));
|
||||
CHECK_FCN (vt, json_object_iter_next,
|
||||
void *(*_f_nm) (nm_json_t *, void *),
|
||||
void *(*_f_js) ( json_t *, void *));
|
||||
CHECK_FCN (vt, json_object_iter_value,
|
||||
nm_json_t *(*_f_nm) (void *),
|
||||
json_t *(*_f_js) (void *));
|
||||
CHECK_FCN (vt, json_object_key_to_iter,
|
||||
void *(*_f_nm) (const char *),
|
||||
void *(*_f_js) (const char *));
|
||||
CHECK_FCN (vt, json_object_set_new,
|
||||
int (*_f_nm) (nm_json_t *, const char *, nm_json_t *),
|
||||
int (*_f_js) ( json_t *, const char *, json_t *));
|
||||
CHECK_FCN (vt, json_object_size,
|
||||
gsize (*_f_nm) (const nm_json_t *),
|
||||
size_t (*_f_js) (const json_t *));
|
||||
CHECK_FCN (vt, json_string,
|
||||
nm_json_t *(*_f_nm) (const char *),
|
||||
json_t *(*_f_js) (const char *));
|
||||
CHECK_FCN (vt, json_string_value,
|
||||
const char *(*_f_nm) (const nm_json_t *),
|
||||
const char *(*_f_js) (const json_t *));
|
||||
CHECK_FCN (vt, json_true,
|
||||
nm_json_t *(*_f_nm) (void),
|
||||
json_t *(*_f_js) (void));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
nmtst_init (&argc, &argv, TRUE);
|
||||
|
||||
g_test_add_func ("/general/test_jansson", test_jansson);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "nm-glib-aux/nm-json-aux.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-wired.h"
|
||||
|
|
@ -9129,7 +9130,7 @@ test_read_team_master_invalid (gconstpointer user_data)
|
|||
gs_free_error GError *error = NULL;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
|
||||
if (WITH_JSON_VALIDATION) {
|
||||
if (nm_json_vt ()) {
|
||||
_connection_from_file_fail (PATH_NAME, NULL, TYPE_ETHERNET, &error);
|
||||
|
||||
g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue