summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-03-16 11:41:56 +0100
committerAleksander Morgado <aleksander@aleksander.es>2020-03-16 11:58:27 +0100
commit80a99ca6a0c26569b837a90d96e79433d6dc910c (patch)
tree0b98c4a7d34e73a39220a6feaeb2268294f74e5d
parent1d84dcc221e54418699384f32a6fef2827e7f745 (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.c2
-rw-r--r--src/libqmi-glib/qmi-utils.c29
-rw-r--r--src/libqmi-glib/qmi-utils.h4
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);