From b9f0451fa35393ceedf6d9d20b78c43578ebea5d Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Wed, 12 Jul 2017 17:57:30 +0200 Subject: New upstream version 1.8.2 --- libnm/nm-client.c | 77 ++++++++++--------- libnm/nm-device.c | 188 +++++++++++---------------------------------- libnm/nm-libnm-utils.c | 162 ++++++++++++++++++++++++++++++++++++++ libnm/nm-libnm-utils.h | 26 +++++++ libnm/nm-object.c | 10 +-- libnm/nm-property-docs.xml | 2 +- libnm/nm-settings-docs.xml | 2 +- libnm/tests/test-general.c | 69 +++++++++++++++++ 8 files changed, 345 insertions(+), 191 deletions(-) create mode 100644 libnm/nm-libnm-utils.c create mode 100644 libnm/nm-libnm-utils.h create mode 100644 libnm/tests/test-general.c (limited to 'libnm') diff --git a/libnm/nm-client.c b/libnm/nm-client.c index 47f1548e..2a91c2ff 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -91,6 +91,13 @@ G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT, #define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate)) +typedef struct { + NMClient *client; + GCancellable *cancellable; + GSimpleAsyncResult *result; + int pending_init; +} NMClientInitData; + typedef struct { NMManager *manager; NMRemoteSettings *settings; @@ -2267,13 +2274,23 @@ objects_created (NMClient *client, GDBusObjectManager *object_manager, GError ** static void name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data); +static gboolean +_om_has_name_owner (GDBusObjectManager *object_manager) +{ + gs_free char *name_owner = NULL; + + nm_assert (G_IS_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); + + name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); + return !!name_owner; +} + static gboolean init_sync (GInitable *initable, GCancellable *cancellable, GError **error) { NMClient *client = NM_CLIENT (initable); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); GList *objects, *iter; - gchar *name_owner; priv->object_manager = g_dbus_object_manager_client_new_for_bus_sync (_nm_dbus_bus_type (), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START, @@ -2285,9 +2302,7 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) if (!priv->object_manager) return FALSE; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); - if (name_owner) { - g_free (name_owner); + if (_om_has_name_owner (priv->object_manager)) { if (!objects_created (client, priv->object_manager, error)) return FALSE; @@ -2316,16 +2331,11 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error) /* Asynchronous initialization. */ -typedef struct { - NMClient *client; - GCancellable *cancellable; - GSimpleAsyncResult *result; - int pending_init; -} NMClientInitData; - static void init_async_complete (NMClientInitData *init_data) { + if (init_data->pending_init > 0) + return; g_simple_async_result_complete (init_data->result); g_object_unref (init_data->result); g_clear_object (&init_data->cancellable); @@ -2338,14 +2348,13 @@ async_inited_obj_nm (GObject *object, GAsyncResult *result, gpointer user_data) NMClientInitData *init_data = user_data; GError *error = NULL; + nm_assert (init_data && init_data->pending_init > 0); + if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error)) g_simple_async_result_take_error (init_data->result, error); - if (init_data) { - init_data->pending_init--; - if (init_data->pending_init == 0) - init_async_complete (init_data); - } + init_data->pending_init--; + init_async_complete (init_data); } static void @@ -2405,10 +2414,11 @@ unhook_om (NMClient *self) static void new_object_manager (GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (source_object); + NMClient *self = NM_CLIENT (user_data); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); - g_object_notify (G_OBJECT (user_data), NM_CLIENT_NM_RUNNING); g_clear_object (&priv->new_object_manager_cancellable); + g_object_notify (G_OBJECT (user_data), NM_CLIENT_NM_RUNNING); } static void @@ -2418,16 +2428,13 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) NMClient *client; NMClientPrivate *priv; GList *objects, *iter; - gchar *name_owner; GError *error = NULL; GDBusObjectManager *object_manager; object_manager = g_dbus_object_manager_client_new_for_bus_finish (result, &error); if (object_manager == NULL) { - if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { - g_simple_async_result_take_error (init_data->result, error); - init_async_complete (init_data); - } + g_simple_async_result_take_error (init_data->result, error); + init_async_complete (init_data); return; } @@ -2435,9 +2442,7 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) priv = NM_CLIENT_GET_PRIVATE (client); priv->object_manager = object_manager; - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)); - if (name_owner) { - g_free (name_owner); + if (_om_has_name_owner (priv->object_manager)) { if (!objects_created (client, priv->object_manager, &error)) { g_simple_async_result_take_error (init_data->result, error); init_async_complete (init_data); @@ -2458,9 +2463,9 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) async_inited_obj_nm, init_data); } g_list_free_full (objects, g_object_unref); + } - } else - init_async_complete (init_data); + init_async_complete (init_data); g_signal_connect (priv->object_manager, "notify::name-owner", G_CALLBACK (name_owner_changed), client); @@ -2497,17 +2502,15 @@ name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) NMClient *self = user_data; NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object); - gchar *name_owner; - - name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (object)); - if (name_owner) { - g_free (name_owner); - g_object_unref (object_manager); - if (priv->new_object_manager_cancellable) - g_cancellable_cancel (priv->new_object_manager_cancellable); + + nm_assert (object_manager == priv->object_manager); + + if (_om_has_name_owner (object_manager)) { + g_clear_object (&priv->object_manager); + nm_clear_g_cancellable (&priv->new_object_manager_cancellable); priv->new_object_manager_cancellable = g_cancellable_new (); prepare_object_manager (self, priv->new_object_manager_cancellable, - new_object_manager, user_data); + new_object_manager, self); } else { g_signal_handlers_disconnect_by_func (object_manager, object_added, self); unhook_om (self); diff --git a/libnm/nm-device.c b/libnm/nm-device.c index 9cbdbd00..969d08a6 100644 --- a/libnm/nm-device.c +++ b/libnm/nm-device.c @@ -26,6 +26,7 @@ #include #include +#include "nm-libnm-utils.h" #include "nm-dbus-interface.h" #include "nm-active-connection.h" #include "nm-device-bt.h" @@ -81,7 +82,7 @@ typedef struct { GPtrArray *available_connections; struct udev *udev; - char *product, *short_product; + char *product; char *vendor, *short_vendor; char *description, *bus_name; @@ -320,7 +321,6 @@ finalize (GObject *object) g_free (priv->driver_version); g_free (priv->firmware_version); g_free (priv->product); - g_free (priv->short_product); g_free (priv->vendor); g_free (priv->short_vendor); g_free (priv->description); @@ -1357,6 +1357,17 @@ _get_udev_property (NMDevice *device, return db_value; } +static char * +_get_udev_property_utf8safe (NMDevice *device, + const char *enc_prop, /* ID_XXX_ENC */ + const char *db_prop) /* ID_XXX_FROM_DATABASE */ +{ + return nm_utils_str_utf8safe_escape_take (_get_udev_property (device, + enc_prop, + db_prop), + NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL); +} + /** * nm_device_get_product: * @device: a #NMDevice @@ -1365,6 +1376,9 @@ _get_udev_property (NMDevice *device, * * Returns: the product name of the device. This is the internal string used by the * device, and must not be modified. + * + * The string is backslash escaped (C escaping) for invalid characters. The escaping + * can be reverted with g_strcompress(), however the result may not be valid UTF-8. **/ const char * nm_device_get_product (NMDevice *device) @@ -1374,15 +1388,16 @@ nm_device_get_product (NMDevice *device) g_return_val_if_fail (NM_IS_DEVICE (device), NULL); priv = NM_DEVICE_GET_PRIVATE (device); - if (!priv->product) - priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); + if (!priv->product) { + priv->product = _get_udev_property_utf8safe (device, "ID_MODEL_ENC", "ID_MODEL_FROM_DATABASE"); - /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ - if (!priv->product) - priv->product = _get_udev_property (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); + /* Sometimes ID_PRODUCT_FROM_DATABASE is used? */ + if (!priv->product) + priv->product = _get_udev_property_utf8safe (device, "ID_MODEL_ENC", "ID_PRODUCT_FROM_DATABASE"); - if (!priv->product) - priv->product = g_strdup (""); + if (!priv->product) + priv->product = g_strdup (""); + } return priv->product; } @@ -1395,6 +1410,9 @@ nm_device_get_product (NMDevice *device) * * Returns: the vendor name of the device. This is the internal string used by the * device, and must not be modified. + * + * The string is backslash escaped (C escaping) for invalid characters. The escaping + * can be reverted with g_strcompress(), however the result may not be valid UTF-8. **/ const char * nm_device_get_vendor (NMDevice *device) @@ -1406,7 +1424,7 @@ nm_device_get_vendor (NMDevice *device) priv = NM_DEVICE_GET_PRIVATE (device); if (!priv->vendor) - priv->vendor = _get_udev_property (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); + priv->vendor = _get_udev_property_utf8safe (device, "ID_VENDOR_ENC", "ID_VENDOR_FROM_DATABASE"); if (!priv->vendor) priv->vendor = g_strdup (""); @@ -1414,128 +1432,14 @@ nm_device_get_vendor (NMDevice *device) return priv->vendor; } -static const char * const ignored_words[] = { - "Semiconductor", - "Components", - "Corporation", - "Communications", - "Company", - "Corp.", - "Corp", - "Co.", - "Inc.", - "Inc", - "Incorporated", - "Ltd.", - "Limited.", - "Intel?", - "chipset", - "adapter", - "[hex]", - "NDIS", - "Module", - NULL -}; - -static const char * const ignored_phrases[] = { - "Multiprotocol MAC/baseband processor", - "Wireless LAN Controller", - "Wireless LAN Adapter", - "Wireless Adapter", - "Network Connection", - "Wireless Cardbus Adapter", - "Wireless CardBus Adapter", - "54 Mbps Wireless PC Card", - "Wireless PC Card", - "Wireless PC", - "PC Card with XJACK(r) Antenna", - "Wireless cardbus", - "Wireless LAN PC Card", - "Technology Group Ltd.", - "Communication S.p.A.", - "Business Mobile Networks BV", - "Mobile Broadband Minicard Composite Device", - "Mobile Communications AB", - "(PC-Suite Mode)", - NULL -}; - -static char * -fixup_desc_string (const char *desc) -{ - char *p, *temp; - char **words, **item; - GString *str; - int i; - - if (!desc) - return NULL; - - p = temp = g_strdup (desc); - while (*p) { - if (*p == '_' || *p == ',') - *p = ' '; - p++; - } - - /* Attempt to shorten ID by ignoring certain phrases */ - for (i = 0; ignored_phrases[i]; i++) { - p = strstr (temp, ignored_phrases[i]); - if (p) { - guint32 ignored_len = strlen (ignored_phrases[i]); - - memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */ - } - } - - /* Attempt to shorten ID by ignoring certain individual words */ - words = g_strsplit (temp, " ", 0); - str = g_string_new_len (NULL, strlen (temp)); - g_free (temp); - - for (item = words; *item; item++) { - gboolean ignore = FALSE; - - if (**item == '\0') - continue; - - for (i = 0; ignored_words[i]; i++) { - if (!strcmp (*item, ignored_words[i])) { - ignore = TRUE; - break; - } - } - - if (!ignore) { - if (str->len) - g_string_append_c (str, ' '); - g_string_append (str, *item); - } - } - g_strfreev (words); - - temp = str->str; - g_string_free (str, FALSE); - - return temp; -} - static void -get_description (NMDevice *device) +ensure_description (NMDevice *device) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); - const char *dev_product; - const char *dev_vendor; - char *pdown; - char *vdown; - GString *str; GParamSpec *name_prop; + gs_free char *short_product = NULL; - dev_product = nm_device_get_product (device); - priv->short_product = fixup_desc_string (dev_product); - - dev_vendor = nm_device_get_vendor (device); - priv->short_vendor = fixup_desc_string (dev_vendor); + priv->short_vendor = nm_str_realloc (nm_utils_fixup_desc_string (nm_device_get_vendor (device))); /* Grab device's preferred name, if any */ name_prop = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (device)), "name"); @@ -1546,28 +1450,24 @@ get_description (NMDevice *device) g_clear_pointer (&priv->description, g_free); } - if (!dev_product || !dev_vendor) { - priv->description = g_strdup (nm_device_get_iface (device)); + if ( !priv->short_vendor + || !(short_product = nm_utils_fixup_desc_string (nm_device_get_product (device)))) { + priv->description = g_strdup (nm_device_get_iface (device) ?: ""); return; } - str = g_string_new_len (NULL, strlen (priv->short_vendor) + strlen (priv->short_product) + 1); - /* Another quick hack; if all of the fixed up vendor string * is found in product, ignore the vendor. */ - pdown = g_ascii_strdown (priv->short_product, -1); - vdown = g_ascii_strdown (priv->short_vendor, -1); - if (!strstr (pdown, vdown)) { - g_string_append (str, priv->short_vendor); - g_string_append_c (str, ' '); + { + gs_free char *pdown = g_ascii_strdown (short_product, -1); + gs_free char *vdown = g_ascii_strdown (priv->short_vendor, -1); + + if (!strstr (pdown, vdown)) + priv->description = g_strconcat (priv->short_vendor, " ", short_product, NULL); + else + priv->description = g_steal_pointer (&short_product); } - g_free (pdown); - g_free (vdown); - - g_string_append (str, priv->short_product); - - priv->description = g_string_free (str, FALSE); } static const char * @@ -1580,7 +1480,7 @@ get_short_vendor (NMDevice *device) priv = NM_DEVICE_GET_PRIVATE (device); if (!priv->description) - get_description (device); + ensure_description (device); return priv->short_vendor; } @@ -1604,7 +1504,7 @@ nm_device_get_description (NMDevice *device) priv = NM_DEVICE_GET_PRIVATE (device); if (!priv->description) - get_description (device); + ensure_description (device); return priv->description; } diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c new file mode 100644 index 00000000..fbbfe2c5 --- /dev/null +++ b/libnm/nm-libnm-utils.c @@ -0,0 +1,162 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2017 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-libnm-utils.h" + +/*****************************************************************************/ + +char * +nm_utils_fixup_desc_string (const char *desc) +{ + static const char *const IGNORED_PHRASES[] = { + "Multiprotocol MAC/baseband processor", + "Wireless LAN Controller", + "Wireless LAN Adapter", + "Wireless Adapter", + "Network Connection", + "Wireless Cardbus Adapter", + "Wireless CardBus Adapter", + "54 Mbps Wireless PC Card", + "Wireless PC Card", + "Wireless PC", + "PC Card with XJACK(r) Antenna", + "Wireless cardbus", + "Wireless LAN PC Card", + "Technology Group Ltd.", + "Communication S.p.A.", + "Business Mobile Networks BV", + "Mobile Broadband Minicard Composite Device", + "Mobile Communications AB", + "(PC-Suite Mode)", + }; + static const char *const IGNORED_WORDS[] = { + "Semiconductor", + "Components", + "Corporation", + "Communications", + "Company", + "Corp.", + "Corp", + "Co.", + "Inc.", + "Inc", + "Incorporated", + "Ltd.", + "Limited.", + "Intel?", + "chipset", + "adapter", + "[hex]", + "NDIS", + "Module", + }; + char *desc_full; + char *p, *q; + int i; + + if (!desc || !desc[0]) + return NULL; + + /* restore original non-UTF-8-safe text. */ + desc_full = nm_utils_str_utf8safe_unescape_cp (desc); + + /* replace all invalid UTF-8 bytes with space. */ + p = desc_full; + while (!g_utf8_validate (p, -1, (const char **) &q)) { + /* the byte is invalid UTF-8. Replace it with space and proceed. */ + *q = ' '; + p = q + 1; + } + + /* replace '_', ',', and ASCII controll characters with space. */ + for (p = desc_full; p[0]; p++) { + if ( NM_IN_SET (*p, '_', ',') + || *p < ' ') + *p = ' '; + } + + /* Attempt to shorten ID by ignoring certain phrases */ + for (i = 0; i < G_N_ELEMENTS (IGNORED_PHRASES); i++) { + p = strstr (desc_full, IGNORED_PHRASES[i]); + if (p) { + const char *eow = &p[strlen (IGNORED_PHRASES[i])]; + + /* require that the phrase is delimited by space, or + * at the beginning or end of the description. */ + if ( (p == desc_full || p[-1] == ' ') + && NM_IN_SET (eow[0], '\0', ' ')) + memmove (p, eow, strlen (eow) + 1); /* +1 for the \0 */ + } + } + + /* Attempt to shorten ID by ignoring certain individual words. + * - word-split the description at spaces + * - coalesce multiple spaces + * - skip over IGNORED_WORDS */ + p = desc_full; + q = desc_full; + for (;;) { + char *eow; + gsize l; + + /* skip leading spaces. */ + while (p[0] == ' ') + p++; + + if (!p[0]) + break; + + /* split leading word on first space */ + eow = strchr (p, ' '); + if (eow) + *eow = '\0'; + + if (nm_utils_strv_find_first ((char **) IGNORED_WORDS, + G_N_ELEMENTS (IGNORED_WORDS), + p) >= 0) + goto next; + + l = strlen (p); + if (q != p) { + if (q != desc_full) + *q++ = ' '; + memmove (q, p, l); + } + q += l; + +next: + if (!eow) + break; + p = eow + 1; + } + + *q++ = '\0'; + + if (!desc_full[0]) { + g_free (desc_full); + return NULL; + } + + nm_assert (g_utf8_validate (desc_full, -1, NULL)); + return desc_full; +} diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h new file mode 100644 index 00000000..4a5a361c --- /dev/null +++ b/libnm/nm-libnm-utils.h @@ -0,0 +1,26 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2017 Red Hat, Inc. + */ + +#ifndef __NM_LIBNM_UTILS_H__ +#define __NM_LIBNM_UTILS_H__ + +char *nm_utils_fixup_desc_string (const char *desc); + +#endif /* __NM_LIBNM_UTILS_H__ */ diff --git a/libnm/nm-object.c b/libnm/nm-object.c index 95346e06..6bf1d063 100644 --- a/libnm/nm-object.c +++ b/libnm/nm-object.c @@ -1233,12 +1233,6 @@ get_property (GObject *object, guint prop_id, case PROP_DBUS_CONNECTION: g_value_set_object (value, g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager))); break; - case PROP_DBUS_OBJECT: - g_value_set_object (value, priv->object); - break; - case PROP_DBUS_OBJECT_MANAGER: - g_value_set_object (value, priv->object_manager); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1335,7 +1329,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) (object_class, PROP_DBUS_OBJECT, g_param_spec_object (NM_OBJECT_DBUS_OBJECT, "", "", G_TYPE_DBUS_OBJECT, - G_PARAM_READWRITE | + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); @@ -1348,7 +1342,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) (object_class, PROP_DBUS_OBJECT_MANAGER, g_param_spec_object (NM_OBJECT_DBUS_OBJECT_MANAGER, "", "", G_TYPE_DBUS_OBJECT_MANAGER, - G_PARAM_READWRITE | + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); } diff --git a/libnm/nm-property-docs.xml b/libnm/nm-property-docs.xml index 7754187d..bdcfa6e7 100644 --- a/libnm/nm-property-docs.xml +++ b/libnm/nm-property-docs.xml @@ -25,7 +25,7 @@ - + diff --git a/libnm/nm-settings-docs.xml b/libnm/nm-settings-docs.xml index d114a0ee..b5291405 100644 --- a/libnm/nm-settings-docs.xml +++ b/libnm/nm-settings-docs.xml @@ -25,7 +25,7 @@ - + diff --git a/libnm/tests/test-general.c b/libnm/tests/test-general.c new file mode 100644 index 00000000..7e0b7bb7 --- /dev/null +++ b/libnm/tests/test-general.c @@ -0,0 +1,69 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * 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, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT SC 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 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-libnm-utils.h" + +#include "nm-utils/nm-test-utils.h" + +/*****************************************************************************/ + +static void +do_test_fixup_desc_string (const char *desc, const char *expected) +{ + gs_free char *result = NULL; + + result = nm_utils_fixup_desc_string (desc); + g_assert_cmpstr (result, ==, expected); +} + +#define do_test_fixup_desc_string_same(desc) (do_test_fixup_desc_string (""desc"", ""desc"")) + +static void +test_fixup_desc_string (void) +{ + do_test_fixup_desc_string (NULL, NULL); + do_test_fixup_desc_string ("", NULL); + do_test_fixup_desc_string_same ("a"); + do_test_fixup_desc_string_same ("a b"); + do_test_fixup_desc_string ("a b ", "a b"); + do_test_fixup_desc_string (" a bbc ", "a bbc"); + do_test_fixup_desc_string (" a \xcc bbc ", "a bbc"); + do_test_fixup_desc_string (" a\xcc bbc ", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PC", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PC ", "a bbc"); + do_test_fixup_desc_string (" a\xcc""bbcWireless PC ", "a bbcWireless PC"); + do_test_fixup_desc_string (" a\xcc""bbc Wireless PCx", "a bbc Wireless PCx"); + do_test_fixup_desc_string (" a\xcc""bbc Inc Wireless PC ", "a bbc"); +} + +/*****************************************************************************/ + +NMTST_DEFINE (); + +int main (int argc, char **argv) +{ + nmtst_init (&argc, &argv, TRUE); + + g_test_add_func ("/libnm/general/fixup_desc_string", test_fixup_desc_string); + + return g_test_run (); +} -- cgit 1.3.0-6-gf8a5