summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-09-23 10:30:50 +0200
committerThomas Haller <thaller@redhat.com>2016-09-23 10:53:43 +0200
commitc6902b4e79c682976617c5d1ea65fd5a83a78625 (patch)
treec07a1514b440ef393c44db89f67bbfbbd979a9dd
parentc6ac2310dc6e552682099e908f2786dd2e61575f (diff)
downloadNetworkManager-c6902b4e79c682976617c5d1ea65fd5a83a78625.tar.gz
libnm: expose nm_utils_is_json_object() utility function
Since we possibly already link against libjansson, we can also expose some helper utils which allows nmcli to do basic validation of JSON without requiring to duplicate the effort of using libjansson. Also, depending tighten up the cecks to ensure that we have a JSON object at hand. We are really interested in that.
-rw-r--r--libnm-core/nm-core-internal.h1
-rw-r--r--libnm-core/nm-keyfile-reader.c2
-rw-r--r--libnm-core/nm-setting-team-port.c2
-rw-r--r--libnm-core/nm-setting-team.c2
-rw-r--r--libnm-core/nm-utils.c69
-rw-r--r--libnm-core/nm-utils.h3
-rw-r--r--libnm-core/tests/test-general.c2
-rw-r--r--libnm/libnm.ver4
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c2
9 files changed, 73 insertions, 14 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index e491bce6da..6253efc2cb 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -328,7 +328,6 @@ gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
/***********************************************************/
-gboolean _nm_utils_check_valid_json (const char *json, GError **error);
gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
#endif
diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c
index 16f0c225b9..f25fa0e1a4 100644
--- a/libnm-core/nm-keyfile-reader.c
+++ b/libnm-core/nm-keyfile-reader.c
@@ -1175,7 +1175,7 @@ team_config_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key
gs_free_error GError *error = NULL;
conf = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
- if (conf && conf[0] && !_nm_utils_check_valid_json (conf, &error)) {
+ if (conf && conf[0] && !nm_utils_is_json_object (conf, &error)) {
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
_("ignoring invalid team configuration: %s"),
error->message);
diff --git a/libnm-core/nm-setting-team-port.c b/libnm-core/nm-setting-team-port.c
index e3ddbdad7c..649d958273 100644
--- a/libnm-core/nm-setting-team-port.c
+++ b/libnm-core/nm-setting-team-port.c
@@ -117,7 +117,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
}
if (priv->config) {
- if (!_nm_utils_check_valid_json (priv->config, error)) {
+ if (!nm_utils_is_json_object (priv->config, error)) {
g_prefix_error (error,
"%s.%s: ",
NM_SETTING_TEAM_PORT_SETTING_NAME,
diff --git a/libnm-core/nm-setting-team.c b/libnm-core/nm-setting-team.c
index 5bf11ed921..c49ebff2b2 100644
--- a/libnm-core/nm-setting-team.c
+++ b/libnm-core/nm-setting-team.c
@@ -89,7 +89,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
if (priv->config) {
- if (!_nm_utils_check_valid_json (priv->config, error)) {
+ if (!nm_utils_is_json_object (priv->config, error)) {
g_prefix_error (error,
"%s.%s: ",
NM_SETTING_TEAM_SETTING_NAME,
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index df75d56557..1b54b7a671 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -4375,8 +4375,20 @@ const char **nm_utils_enum_get_values (GType type, gint from, gint to)
}
#if WITH_JANSSON
+/**
+ * nm_utils_is_json_object:
+ * @str: the JSON string to test
+ * @error: optional error reason
+ *
+ * Returns: whether the passed string is valid JSON.
+ * If libnm is not compiled with libjansson support, this check will
+ * also return %TRUE for possibly invalid inputs. If that is a problem
+ * for you, you must validate the JSON yourself.
+ *
+ * Since: 1.6
+ */
gboolean
-_nm_utils_check_valid_json (const char *str, GError **error)
+nm_utils_is_json_object (const char *str, GError **error)
{
json_t *json;
json_error_t jerror;
@@ -4387,7 +4399,7 @@ _nm_utils_check_valid_json (const char *str, GError **error)
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
- "value is NULL or empty");
+ str ? _("value is NULL") : _("value is empty"));
return FALSE;
}
@@ -4396,9 +4408,19 @@ _nm_utils_check_valid_json (const char *str, GError **error)
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
- "%s at position %d",
- jerror.text,
- jerror.position);
+ _("invalid JSON at position %d (%s)"),
+ jerror.position,
+ jerror.text);
+ return FALSE;
+ }
+
+ /* valid JSON (depending on the definition) can also be a literal.
+ * Here we only allow objects. */
+ if (!json_is_object (json)) {
+ g_set_error_literal (error,
+ NM_CONNECTION_ERROR,
+ NM_CONNECTION_ERROR_INVALID_PROPERTY,
+ _("is not a JSON object"));
return FALSE;
}
@@ -4490,17 +4512,48 @@ out:
#else /* WITH_JANSSON */
gboolean
-_nm_utils_check_valid_json (const char *str, GError **error)
+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,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
- "value is NULL or empty");
+ str ? _("value is NULL") : _("value is empty"));
return FALSE;
}
- return TRUE;
+ /* do some very basic validation to see if this might be a JSON object. */
+ if (str[0] == '{') {
+ g_size 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;
}
gboolean
diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h
index 407c14e2c4..4fabfdb7b7 100644
--- a/libnm-core/nm-utils.h
+++ b/libnm-core/nm-utils.h
@@ -90,6 +90,9 @@ gboolean nm_utils_ap_mode_security_valid (NMUtilsSecurityType type,
gboolean nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type);
gboolean nm_utils_wpa_psk_valid (const char *psk);
+NM_AVAILABLE_IN_1_6
+gboolean nm_utils_is_json_object (const char *json, GError **error);
+
GVariant *nm_utils_ip4_dns_to_variant (char **dns);
char **nm_utils_ip4_dns_from_variant (GVariant *value);
GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses,
diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c
index 5dfc897114..58c2ab1443 100644
--- a/libnm-core/tests/test-general.c
+++ b/libnm-core/tests/test-general.c
@@ -4685,7 +4685,7 @@ _json_config_check_valid (const char *conf, gboolean expected)
gs_free_error GError *error = NULL;
gboolean res;
- res = _nm_utils_check_valid_json (conf, &error);
+ res = nm_utils_is_json_object (conf, &error);
g_assert_cmpint (res, ==, expected);
g_assert (res || error);
}
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index cc2fc7df62..937904d42d 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1083,3 +1083,7 @@ global:
nm_vpn_plugin_info_new_search_file;
nm_vpn_plugin_info_supports_hints;
} libnm_1_2_0;
+
+libnm_1_6_0 {
+ nm_utils_is_json_object;
+} libnm_1_4_0;
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index 5a351cfa06..80c6ca1553 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -4258,7 +4258,7 @@ read_team_config (shvarFile *ifcfg, const char *key, GError **error)
}
svUnescape (value);
- if (value && value[0] && !_nm_utils_check_valid_json (value, &local_error)) {
+ if (value && value[0] && !nm_utils_is_json_object (value, &local_error)) {
PARSE_WARNING ("ignoring invalid team configuration: %s", local_error->message);
g_clear_pointer (&value, g_free);
}