diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2022-11-28 14:42:22 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2022-12-01 12:07:24 +0000 |
commit | 90a8b2dd90173da43ce71af82ade177fdedf2af0 (patch) | |
tree | f5932d384965f9990e3550b2933b33e7f8c1eb36 | |
parent | 0515eb13d8d1034625f489e77077c42c8cc0acf7 (diff) | |
download | libmbim-90a8b2dd90173da43ce71af82ade177fdedf2af0.tar.gz |
libmbim-glib,tlv: duplicate UTF-16 string to ensure alignment
../src/libmbim-glib/mbim-tlv.c:261:13: warning: cast from
'guint8 *' (aka 'unsigned char *') to 'const gunichar2 *' (aka 'const
unsigned short *') increases required alignment from 1 to 2
[-Wcast-align]
utf16 = (const gunichar2 *) MBIM_TLV_FIELD_DATA (self);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We cannot dereference an element in the array of 16bit elements safely
if the array was casted from an unaligned bytearray. We must duplicate
the array with proper alignment, and then we can dereference each
element one by one.
Fixes https://gitlab.freedesktop.org/mobile-broadband/libmbim/-/issues/35
-rw-r--r-- | src/libmbim-glib/mbim-tlv.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/src/libmbim-glib/mbim-tlv.c b/src/libmbim-glib/mbim-tlv.c index 18a3f65..283abc2 100644 --- a/src/libmbim-glib/mbim-tlv.c +++ b/src/libmbim-glib/mbim-tlv.c @@ -246,8 +246,7 @@ gchar * mbim_tlv_string_get (const MbimTlv *self, GError **error) { - const gunichar2 *utf16 = NULL; - g_autofree gunichar2 *utf16d = NULL; + g_autofree gunichar2 *tmp = NULL; guint32 size; g_return_val_if_fail (self != NULL, NULL); @@ -258,23 +257,20 @@ mbim_tlv_string_get (const MbimTlv *self, return NULL; } - utf16 = (const gunichar2 *) MBIM_TLV_FIELD_DATA (self); + /* Duplicate array unconditionally to avoid alignment issues as we don't + * know if the 16bit array is aligned properly or not in the TLV */ size = MBIM_TLV_GET_DATA_LENGTH (self); + tmp = (gunichar2 *) g_memdup ((gconstpointer) MBIM_TLV_FIELD_DATA (self), size); /* For BE systems, convert from LE to BE */ if (G_BYTE_ORDER == G_BIG_ENDIAN) { guint i; - utf16d = (gunichar2 *) g_malloc (size); for (i = 0; i < (size / 2); i++) - utf16d[i] = GUINT16_FROM_LE (utf16[i]); + tmp[i] = GUINT16_FROM_LE (tmp[i]); } - return g_utf16_to_utf8 (utf16d ? utf16d : utf16, - size / 2, - NULL, - NULL, - error); + return g_utf16_to_utf8 (tmp, size / 2, NULL, NULL, error); } /*****************************************************************************/ |