qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] usb-mtp: Fix build with gcc 9


From: Greg Kurz
Subject: [Qemu-devel] [PATCH] usb-mtp: Fix build with gcc 9
Date: Thu, 28 Feb 2019 18:57:32 +0100
User-agent: StGit/unknown-version

Build fails with gcc 9:

  CC      hw/usb/dev-mtp.o
hw/usb/dev-mtp.c: In function ‘usb_mtp_write_metadata’:
hw/usb/dev-mtp.c:1754:36: error: taking address of packed member of ‘struct 
<anonymous>’ may result in an unaligned pointer value 
[-Werror=address-of-packed-member]
 1754 |                             dataset->filename);
      |                             ~~~~~~~^~~~~~~~~~
cc1: all warnings being treated as errors

The way the MTP protocol encodes strings with a leading 8-bit unsigned
integer containing the string length causes the @filename field of the
packed ObjectInfo structure to be unaligned.

Use a temporary buffer for the utf16 filename instead of passing the
dataset->filename pointer around.

Signed-off-by: Greg Kurz <address@hidden>
---
 hw/usb/dev-mtp.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 4ee4fc5a893a..8a0ef7f9f4a8 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1692,13 +1692,25 @@ static void usb_mtp_write_metadata(MTPState *s, 
uint64_t dlen)
     MTPObject *o;
     MTPObject *p = usb_mtp_object_lookup(s, s->dataset.parent_handle);
     uint32_t next_handle = s->next_handle;
+    uint16_t *utf16_filename;
+    uint8_t filename_len;
 
     assert(!s->write_pending);
     assert(p != NULL);
 
-    filename = utf16_to_str(MIN(dataset->length,
-                                dlen - offsetof(ObjectInfo, filename)),
-                            dataset->filename);
+    /*
+     * MTP Specification 3.2.3 Strings
+     * Strings in PTP (and thus MTP) consist of standard 2-byte Unicode
+     * characters as defined by ISO 10646. Strings begin with a single, 8-bit
+     * unsigned integer that identifies the number of characters to follow (not
+     * bytes).
+     *
+     * This causes dataset->filename to be unaligned.
+     */
+    filename_len = MIN(dataset->length, dlen - offsetof(ObjectInfo, filename));
+    utf16_filename = g_memdup(dataset->filename, filename_len * 2);
+    filename = utf16_to_str(filename_len, utf16_filename);
+    g_free(utf16_filename);
 
     if (strchr(filename, '/')) {
         usb_mtp_queue_result(s, RES_PARAMETER_NOT_SUPPORTED, d->trans,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]