diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-03-16 11:41:56 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-03-16 11:58:27 +0100 |
commit | 80a99ca6a0c26569b837a90d96e79433d6dc910c (patch) | |
tree | 0b98c4a7d34e73a39220a6feaeb2268294f74e5d | |
parent | 1d84dcc221e54418699384f32a6fef2827e7f745 (diff) |
libqmi-glib,utils: assume non-printable UTF-8 is not expected
When a string comes in GSM7 instead of UTF-8, it may also happen that
it ends up being valid UTF-8 anyway. But, there may be cases that the
UTF-8 validity accepts non-printable characters, and that is something
we currently don't expect reported from the modem, so just go on and
assume that even if a string is valid UTF-8, it must contain all
printable UTF-8 characters, otherwise we'll attempt GSM-7 and UCS-2
decoding instead.
Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/191
(cherry picked from commit b5c46e12332adc1084bde6e3652af67009f56e3c)
-rw-r--r-- | src/libqmi-glib/qmi-message.c | 2 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-utils.c | 29 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-utils.h | 4 |
3 files changed, 34 insertions, 1 deletions
diff --git a/src/libqmi-glib/qmi-message.c b/src/libqmi-glib/qmi-message.c index ca5756d..695ec7a 100644 --- a/src/libqmi-glib/qmi-message.c +++ b/src/libqmi-glib/qmi-message.c @@ -1325,7 +1325,7 @@ qmi_message_tlv_read_string (QmiMessage *self, * but hey, the strings read using this method should all really be ASCII-7 * and we're trying to do our best to overcome modem firmware problems... */ - if (g_utf8_validate ((const gchar *)ptr, valid_string_length, NULL)) { + if (__qmi_string_utf8_validate_printable (ptr, valid_string_length)) { *out = g_malloc (valid_string_length + 1); memcpy (*out, ptr, valid_string_length); (*out)[valid_string_length] = '\0'; diff --git a/src/libqmi-glib/qmi-utils.c b/src/libqmi-glib/qmi-utils.c index 8f40b5e..162db0a 100644 --- a/src/libqmi-glib/qmi-utils.c +++ b/src/libqmi-glib/qmi-utils.c @@ -120,6 +120,35 @@ __qmi_user_allowed (uid_t uid, } /*****************************************************************************/ + +gboolean +__qmi_string_utf8_validate_printable (const guint8 *utf8, + gsize utf8_len) +{ + const gchar *p; + const gchar *init; + + g_assert (utf8); + g_assert (utf8_len); + + /* First check if valid UTF-8 */ + init = (const gchar *)utf8; + if (!g_utf8_validate (init, utf8_len, NULL)) + return FALSE; + + /* Then check if contents are printable. If one is not, + * check fails. */ + for (p = init; (gsize)(p - init) < utf8_len; p = g_utf8_next_char (p)) { + gunichar unichar; + + unichar = g_utf8_get_char (p); + if (!g_unichar_isprint (unichar)) + return FALSE; + } + return TRUE; +} + +/*****************************************************************************/ /* GSM 03.38 encoding conversion stuff, imported from ModemManager */ #define GSM_DEF_ALPHABET_SIZE 128 diff --git a/src/libqmi-glib/qmi-utils.h b/src/libqmi-glib/qmi-utils.h index 27cfe7e..7283101 100644 --- a/src/libqmi-glib/qmi-utils.h +++ b/src/libqmi-glib/qmi-utils.h @@ -86,6 +86,10 @@ gboolean __qmi_user_allowed (uid_t uid, GError **error); G_GNUC_INTERNAL +gboolean __qmi_string_utf8_validate_printable (const guint8 *utf8, + gsize utf8_len); + +G_GNUC_INTERNAL gchar *__qmi_string_utf8_from_gsm7 (const guint8 *gsm, gsize gsm_len); |