From 66ae13f012a7416db839c6d6158b9c85cd9a27c5 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
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 <link.h>
+
+#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 <linux/pkt_sched.h>

 #if WITH_JANSSON
+#include "nm-jansson.h"
 #include <jansson.h>
 #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 <thaller@redhat.com>
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 <thaller@redhat.com>
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 <link.h>
-
-#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 <link.h>
+
+#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 <linux/pkt_sched.h>

 #if WITH_JANSSON
-#include "nm-jansson.h"
+#include "nm-json.h"
 #include <jansson.h>
 #endif

--
2.14.3


From 0aa9273d334afec1d54878587b4f7fb9e2410f92 Mon Sep 17 00:00:00 2001
From: Thomas Haller <thaller@redhat.com>
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 <thaller@redhat.com>
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 <thaller@redhat.com>
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 <link.h>, <dlfcn.h> 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 <link.h>
-
 #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;
--
2.14.3
