From bfb6c78430c7cd0cb523e5bb4388e8de3024dfe7 Mon Sep 17 00:00:00 2001 From: David Shea Date: Tue, 14 Jul 2015 15:25:52 -0400 Subject: [PATCH] libnm: handle illegal characters in nm_utils_ssid_to_utf8() (rh #1243078) g_convert_with_fallback() will fail if the SSID contains characters that are not legal in the source encoding, which, if $LANG is not set, will be ASCII. If this happens, replace all non-ASCII and non-printable characters with '?'. It is possible that nm_utils_ssid_to_utf8() will now return an empty string (e.g., the source string is actually big-endian UTF-16 and g_strcanon() stops on the first byte), but it will not return NULL. https://bugzilla.redhat.com/show_bug.cgi?id=1243078 (cherry picked from commit 568b4ad31f36690091a03cbff0fc7c3a9556e028) --- libnm-core/nm-utils.c | 15 +++++++++++++++ libnm-util/nm-utils.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 14686ed1fd..6a7ed61f5c 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -317,6 +317,21 @@ nm_utils_ssid_to_utf8 (const guint8 *ssid, gsize len) "UTF-8", e1, "?", NULL, NULL, NULL); } + if (!converted) { + /* If there is still no converted string, the SSID probably + * contains characters not valid in the current locale. Convert + * the string to ASCII instead. + */ + + /* Use the printable range of 0x20-0x7E */ + gchar *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" + "abcdefghijklmnopqrstuvwxyz{|}~"; + + converted = g_strndup ((const gchar *)ssid, len); + g_strcanon (converted, valid_chars, '?'); + } + return converted; } diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index d0c2ca31f8..143063e7f5 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -332,6 +332,21 @@ nm_utils_ssid_to_utf8 (const GByteArray *ssid) "UTF-8", e1, "?", NULL, NULL, NULL); } + if (!converted) { + /* If there is still no converted string, the SSID probably + * contains characters not valid in the current locale. Convert + * the string to ASCII instead. + */ + + /* Use the printable range of 0x20-0x7E */ + gchar *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" + "abcdefghijklmnopqrstuvwxyz{|}~"; + + converted = g_strndup ((const gchar *)ssid->data, ssid->len); + g_strcanon (converted, valid_chars, '?'); + } + return converted; }