From 66ae13f012a7416db839c6d6158b9c85cd9a27c5 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 26 Dec 2017 09:28:54 +0100 Subject: [PATCH 1/6] core: load jansson on demand Avoid using it if the symbols clash is detected. (cherry picked from commit cd476e4dc922f0acfd65b02639032ee67339ad95) --- Makefile.am | 12 +++-- configure.ac | 12 ++++- libnm-core/nm-jansson.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ libnm-core/nm-jansson.h | 46 +++++++++++++++++++ libnm-core/nm-utils.c | 78 +++++++++++++++++++------------ 5 files changed, 232 insertions(+), 35 deletions(-) create mode 100644 libnm-core/nm-jansson.c create mode 100644 libnm-core/nm-jansson.h diff --git a/Makefile.am b/Makefile.am index a189262c1..69d61c4fe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -518,6 +518,14 @@ libnm_core_lib_c_real = \ libnm-core/nm-utils.c \ libnm-core/nm-vpn-editor-plugin.c \ libnm-core/nm-vpn-plugin-info.c + +if WITH_JANSSON +libnm_core_lib_h_priv += \ + libnm-core/nm-jansson.h +libnm_core_lib_c_real += \ + libnm-core/nm-jansson.c +endif + libnm_core_lib_c_mkenums = \ libnm-core/nm-core-enum-types.c @@ -598,10 +606,6 @@ libnm_core_libnm_core_la_LIBADD = \ $(UUID_LIBS) \ $(LIBUDEV_LIBS) -if WITH_JANSSON -libnm_core_libnm_core_la_LIBADD += $(JANSSON_LIBS) -endif - libnm_core_libnm_core_la_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) diff --git a/configure.ac b/configure.ac index 05ba94971..5b5090318 100644 --- a/configure.ac +++ b/configure.ac @@ -664,7 +664,17 @@ 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_JANSSON, 1, [Define if JANSSON is enabled]) + + AC_DEFINE(WITH_JANSSON, 1, [Define if JANSSON is enabled]) + + AC_CHECK_TOOLS(READELF, [eu-readelf readelf]) + JANSSON_LIBDIR=`$PKG_CONFIG --variable=libdir jansson` + JANSSON_SONAME=`$READELF -d $JANSSON_LIBDIR/libjansson.so |sed -n 's/.*SONAME.*\[[\([^]]*\)]]/\1/p'` + + if test "$JANSSON_SONAME" = ""; then + AC_MSG_ERROR(Unable to locate the Jansson library) + fi + AC_DEFINE_UNQUOTED(JANSSON_SONAME, "$JANSSON_SONAME", [Define to path to the Jansson shared library]) fi AM_CONDITIONAL(WITH_JANSSON, test "${enable_json_validation}" != "no") diff --git a/libnm-core/nm-jansson.c b/libnm-core/nm-jansson.c new file mode 100644 index 000000000..0f7bd3213 --- /dev/null +++ b/libnm-core/nm-jansson.c @@ -0,0 +1,119 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2017, 2018 Red Hat, Inc. + */ + +#define _GNU_SOURCE +#include + +#include "nm-default.h" + +#define NM_JAONSSON_C +#include "nm-jansson.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_object_iter_at; +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_object_iter_at); + 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; + + 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; + + handle = dlopen (JANSSON_SONAME, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND); + if (!handle) + goto out; + + /* Now do the actual binding. */ + if (!bind_symbols (handle)) + goto out; + + state = AVAILABLE; +out: + return state == AVAILABLE; +} diff --git a/libnm-core/nm-jansson.h b/libnm-core/nm-jansson.h new file mode 100644 index 000000000..043986878 --- /dev/null +++ b/libnm-core/nm-jansson.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2017, 2018 Red Hat, Inc. + */ + +gboolean nm_jansson_load (void); + +#ifndef NM_JAONSSON_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_object_iter_at (*_nm_jansson_json_object_iter_at) +#define json_integer_value (*_nm_jansson_json_integer_value) +#define json_string_value (*_nm_jansson_json_string_value) +#endif diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index ce3536c84..8d7bf08f9 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -36,6 +36,7 @@ #include #if WITH_JANSSON +#include "nm-jansson.h" #include #endif @@ -4891,6 +4892,41 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to) /*****************************************************************************/ +static gboolean +_nm_utils_is_json_object_no_validation (const char *str, GError **error) +{ + if (str) { + /* libjansson also requires only utf-8 encoding. */ + if (!g_utf8_validate (str, -1, NULL)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("not valid utf-8")); + return FALSE; + } + while (g_ascii_isspace (str[0])) + str++; + } + + /* do some very basic validation to see if this might be a JSON object. */ + if (str[0] == '{') { + gsize l; + + l = strlen (str) - 1; + while (l > 0 && g_ascii_isspace (str[l])) + l--; + + if (str[l] == '}') + return TRUE; + } + + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("is not a JSON object")); + return FALSE; +} + #if WITH_JANSSON /* Added in Jansson v2.3 (released Jan 27 2012) */ @@ -5363,6 +5399,9 @@ nm_utils_is_json_object (const char *str, GError **error) return FALSE; } + if (!nm_jansson_load ()) + return _nm_utils_is_json_object_no_validation (str, error); + json = json_loads (str, JSON_REJECT_DUPLICATES, &jerror); if (!json) { g_set_error (error, @@ -5413,6 +5452,8 @@ _nm_utils_team_config_equal (const char *conf1, if (nm_streq0 (conf1, conf2)) return TRUE; + else if (!nm_jansson_load ()) + return FALSE; /* A NULL configuration is equivalent to default value '{}' */ json1 = json_loads (conf1 ?: "{}", JSON_REJECT_DUPLICATES, &jerror); @@ -5470,6 +5511,9 @@ _nm_utils_team_config_get (const char *conf, if (!key) return NULL; + if (!nm_jansson_load ()) + return NULL; + json = json_loads (conf ?: "{}", JSON_REJECT_DUPLICATES, &jerror); /* Invalid json in conf */ @@ -5577,6 +5621,9 @@ _nm_utils_team_config_set (char **conf, g_return_val_if_fail (key, FALSE); + if (!nm_jansson_load ()) + return FALSE; + json = json_loads (*conf?: "{}", JSON_REJECT_DUPLICATES, &jerror); if (!json) return FALSE; @@ -5694,19 +5741,6 @@ nm_utils_is_json_object (const char *str, GError **error) { g_return_val_if_fail (!error || !*error, FALSE); - if (str) { - /* libjansson also requires only utf-8 encoding. */ - if (!g_utf8_validate (str, -1, NULL)) { - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("not valid utf-8")); - return FALSE; - } - while (g_ascii_isspace (str[0])) - str++; - } - if (!str || !str[0]) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -5715,23 +5749,7 @@ nm_utils_is_json_object (const char *str, GError **error) return FALSE; } - /* do some very basic validation to see if this might be a JSON object. */ - if (str[0] == '{') { - gsize l; - - l = strlen (str) - 1; - while (l > 0 && g_ascii_isspace (str[l])) - l--; - - if (str[l] == '}') - return TRUE; - } - - g_set_error_literal (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("is not a JSON object")); - return FALSE; + return _nm_utils_is_json_object_no_validation (str, error); } gboolean -- 2.14.3 From 75dfbfcef40c44b2a04779351d0974b5e36818c2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Jan 2018 07:10:24 +0100 Subject: [PATCH 2/6] libnm/trivial: don't use non-leading tabs (cherry picked from commit 950a14128bc249626af0770f0003cf83d491bd54) --- libnm-core/nm-jansson.h | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/libnm-core/nm-jansson.h b/libnm-core/nm-jansson.h index 043986878..e3718d93c 100644 --- a/libnm-core/nm-jansson.h +++ b/libnm-core/nm-jansson.h @@ -19,28 +19,28 @@ gboolean nm_jansson_load (void); #ifndef NM_JAONSSON_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_object_iter_at (*_nm_jansson_json_object_iter_at) -#define json_integer_value (*_nm_jansson_json_integer_value) -#define json_string_value (*_nm_jansson_json_string_value) +#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_object_iter_at (*_nm_jansson_json_object_iter_at) +#define json_integer_value (*_nm_jansson_json_integer_value) +#define json_string_value (*_nm_jansson_json_string_value) #endif -- 2.14.3 From bbcb9ebefcffab302d192dcd60c084c2698dff24 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Jan 2018 06:20:18 +0100 Subject: [PATCH 3/6] libnm: rename "libnm-core/nm-jansson.h" to "libnm-core/nm-json.h" We already have "shared/nm-utils/nm-jansson.h". Avoid reusing the same file name. (cherry picked from commit b6b6baa7735e09a95fa9504e9a9746cdc4e970e6) --- Makefile.am | 4 +- libnm-core/nm-jansson.c | 119 ------------------------------------------------ libnm-core/nm-jansson.h | 46 ------------------- libnm-core/nm-json.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++ libnm-core/nm-json.h | 46 +++++++++++++++++++ libnm-core/nm-utils.c | 2 +- 6 files changed, 168 insertions(+), 168 deletions(-) delete mode 100644 libnm-core/nm-jansson.c delete mode 100644 libnm-core/nm-jansson.h create mode 100644 libnm-core/nm-json.c create mode 100644 libnm-core/nm-json.h diff --git a/Makefile.am b/Makefile.am index 69d61c4fe..639921d50 100644 --- a/Makefile.am +++ b/Makefile.am @@ -521,9 +521,9 @@ libnm_core_lib_c_real = \ if WITH_JANSSON libnm_core_lib_h_priv += \ - libnm-core/nm-jansson.h + libnm-core/nm-json.h libnm_core_lib_c_real += \ - libnm-core/nm-jansson.c + libnm-core/nm-json.c endif libnm_core_lib_c_mkenums = \ diff --git a/libnm-core/nm-jansson.c b/libnm-core/nm-jansson.c deleted file mode 100644 index 0f7bd3213..000000000 --- a/libnm-core/nm-jansson.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2017, 2018 Red Hat, Inc. - */ - -#define _GNU_SOURCE -#include - -#include "nm-default.h" - -#define NM_JAONSSON_C -#include "nm-jansson.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_object_iter_at; -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_object_iter_at); - 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; - - 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; - - handle = dlopen (JANSSON_SONAME, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND); - if (!handle) - goto out; - - /* Now do the actual binding. */ - if (!bind_symbols (handle)) - goto out; - - state = AVAILABLE; -out: - return state == AVAILABLE; -} diff --git a/libnm-core/nm-jansson.h b/libnm-core/nm-jansson.h deleted file mode 100644 index e3718d93c..000000000 --- a/libnm-core/nm-jansson.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2017, 2018 Red Hat, Inc. - */ - -gboolean nm_jansson_load (void); - -#ifndef NM_JAONSSON_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_object_iter_at (*_nm_jansson_json_object_iter_at) -#define json_integer_value (*_nm_jansson_json_integer_value) -#define json_string_value (*_nm_jansson_json_string_value) -#endif diff --git a/libnm-core/nm-json.c b/libnm-core/nm-json.c new file mode 100644 index 000000000..1f7d4398a --- /dev/null +++ b/libnm-core/nm-json.c @@ -0,0 +1,119 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2017, 2018 Red Hat, Inc. + */ + +#define _GNU_SOURCE +#include + +#include "nm-default.h" + +#define NM_JAONSSON_C +#include "nm-json.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_object_iter_at; +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_object_iter_at); + 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; + + 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; + + handle = dlopen (JANSSON_SONAME, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE | RTLD_DEEPBIND); + if (!handle) + goto out; + + /* Now do the actual binding. */ + if (!bind_symbols (handle)) + goto out; + + state = AVAILABLE; +out: + return state == AVAILABLE; +} diff --git a/libnm-core/nm-json.h b/libnm-core/nm-json.h new file mode 100644 index 000000000..e3718d93c --- /dev/null +++ b/libnm-core/nm-json.h @@ -0,0 +1,46 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2017, 2018 Red Hat, Inc. + */ + +gboolean nm_jansson_load (void); + +#ifndef NM_JAONSSON_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_object_iter_at (*_nm_jansson_json_object_iter_at) +#define json_integer_value (*_nm_jansson_json_integer_value) +#define json_string_value (*_nm_jansson_json_string_value) +#endif diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 8d7bf08f9..ebbbfd3a4 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -36,7 +36,7 @@ #include #if WITH_JANSSON -#include "nm-jansson.h" +#include "nm-json.h" #include #endif -- 2.14.3 From 0aa9273d334afec1d54878587b4f7fb9e2410f92 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Jan 2018 07:15:40 +0100 Subject: [PATCH 4/6] libnm: fix spelling for NM_JAONSSON_C define (cherry picked from commit 288877848067c08abfd82d3ee72765f89ec79968) --- libnm-core/nm-json.c | 2 +- libnm-core/nm-json.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libnm-core/nm-json.c b/libnm-core/nm-json.c index 1f7d4398a..d58898ce2 100644 --- a/libnm-core/nm-json.c +++ b/libnm-core/nm-json.c @@ -21,7 +21,7 @@ #include "nm-default.h" -#define NM_JAONSSON_C +#define NM_JANSSON_C #include "nm-json.h" void *_nm_jansson_json_object_iter_value; diff --git a/libnm-core/nm-json.h b/libnm-core/nm-json.h index e3718d93c..50b52e4f2 100644 --- a/libnm-core/nm-json.h +++ b/libnm-core/nm-json.h @@ -18,7 +18,7 @@ gboolean nm_jansson_load (void); -#ifndef NM_JAONSSON_C +#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) -- 2.14.3 From 5269978e379c3a03cb5b159beef747329a645446 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Jan 2018 07:17:06 +0100 Subject: [PATCH 5/6] libnm: add include guard to nm-json.h (cherry picked from commit ee56c9250fc88eb1983bc587dc5052a70cb88e0f) --- libnm-core/nm-json.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libnm-core/nm-json.h b/libnm-core/nm-json.h index 50b52e4f2..513b8d369 100644 --- a/libnm-core/nm-json.h +++ b/libnm-core/nm-json.h @@ -15,6 +15,8 @@ * * Copyright 2017, 2018 Red Hat, Inc. */ +#ifndef __NM_JSON_H__ +#define __NM_JSON_H__ gboolean nm_jansson_load (void); @@ -44,3 +46,5 @@ gboolean nm_jansson_load (void); #define json_integer_value (*_nm_jansson_json_integer_value) #define json_string_value (*_nm_jansson_json_string_value) #endif + +#endif /* __NM_JSON_H__ */ -- 2.14.3 From ec630dc256b3e9cb80cd3ca9872c5a405ae21646 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 9 Jan 2018 07:30:31 +0100 Subject: [PATCH 6/6] libnm: cleanup include in "libnm-core/nm-json.c" We already define _GNU_SOURCE in "config.h", depending on configure checks. Also, we always should first include "config.h" (which means to first include "nm-default.h"). Also, we don't need the entire , suffices. (cherry picked from commit 84576ce86155e195985a1924c90782eb9e2e5beb) --- libnm-core/nm-json.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libnm-core/nm-json.c b/libnm-core/nm-json.c index d58898ce2..f9042b1f3 100644 --- a/libnm-core/nm-json.c +++ b/libnm-core/nm-json.c @@ -16,14 +16,13 @@ * Copyright 2017, 2018 Red Hat, Inc. */ -#define _GNU_SOURCE -#include - #include "nm-default.h" #define NM_JANSSON_C #include "nm-json.h" +#include + void *_nm_jansson_json_object_iter_value; void *_nm_jansson_json_object_key_to_iter; void *_nm_jansson_json_integer; -- 2.14.3