[gvfs] mtp: improve validation of received thumbnail/sample data in do_open_icon_for_read()



commit c7bb2e1f5341d03cbc7b195d756f49fdf7a0f0f5
Author: Rok Mandeljc <rok mandeljc gmail com>
Date:   Sun Aug 3 19:00:18 2014 +0200

    mtp: improve validation of received thumbnail/sample data in do_open_icon_for_read()
    
    With my tablet, the call to LIBMTP_Get_Thumbnail() in
    do_open_icon_for_read() sometimes succeeds with return code 0, but
    returns size 0 and NULL data pointer. Thus, subsequent read
    operations return no data, and Nautilus ends up with invalid
    preview icon.
    
    This patch adds validation of returned data size, and treats size
    0 same as if the call failed - reporting no icon data to be
    available and causing Nautilus to read the actual file content to
    obtain the preview icon.
    
    Also, LIBMTP_destroy_filesampledata_t() is now called regardless
    whether LIBMTP_Get_Representative_Sample() call succeeds or not.
    
    Signed-off-by: Rok Mandeljc <rok mandeljc gmail com>

 daemon/gvfsbackendmtp.c |   48 ++++++++++++++++++++++++++++------------------
 1 files changed, 29 insertions(+), 19 deletions(-)
---
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
index 38df2b8..4d5cbf8 100644
--- a/daemon/gvfsbackendmtp.c
+++ b/daemon/gvfsbackendmtp.c
@@ -1955,35 +1955,45 @@ do_open_icon_for_read (GVfsBackend *backend,
   guint id = strtol (icon_id, NULL, 16);
 
   if (id > 0) {
-    GByteArray *bytes;
+    GByteArray *bytes = NULL;
     unsigned char *data;
     unsigned int size;
-    int ret = LIBMTP_Get_Thumbnail (G_VFS_BACKEND_MTP (backend)->device, id,
-                                    &data, &size);
+    int ret;
+
+    ret = LIBMTP_Get_Thumbnail (G_VFS_BACKEND_MTP (backend)->device, id,
+                                &data, &size);
     if (ret == 0) {
       DEBUG ("File %X has thumbnail: %u\n", id, size);
-      bytes = g_byte_array_sized_new (size);
-      g_byte_array_append (bytes, data, size);
+      if (size > 0) {
+        bytes = g_byte_array_sized_new (size);
+        g_byte_array_append (bytes, data, size);
+      }
       free (data);
-    } else {
+    }
+
+    if (!bytes) {
       LIBMTP_filesampledata_t *sample_data = LIBMTP_new_filesampledata_t ();
       ret = LIBMTP_Get_Representative_Sample (G_VFS_BACKEND_MTP (backend)->device,
                                               id, sample_data);
       if (ret == 0) {
-        DEBUG ("File %X has sampledata: %u\n", id, size);
-        bytes = g_byte_array_sized_new (sample_data->size);
-        g_byte_array_append (bytes, (const guint8 *)sample_data->data, sample_data->size);
-        size = sample_data->size;
-        LIBMTP_destroy_filesampledata_t (sample_data);
-      } else {
-        DEBUG ("File %X has no thumbnail or sampledata\n", id);
-        g_vfs_job_failed (G_VFS_JOB (job),
-                          G_IO_ERROR,
-                          G_IO_ERROR_NOT_FOUND,
-                          _("No thumbnail for entity '%s'"),
-                          icon_id);
-        goto exit;
+        DEBUG ("File %X has sampledata: %u\n", id, sample_data->size);
+        if (sample_data->size > 0) {
+          bytes = g_byte_array_sized_new (sample_data->size);
+          g_byte_array_append (bytes, (const guint8 *)sample_data->data, sample_data->size);
+          size = sample_data->size;
+        }
       }
+      LIBMTP_destroy_filesampledata_t (sample_data);
+    }
+
+    if (!bytes) {
+      DEBUG ("File %X has no thumbnail or sampledata\n", id);
+      g_vfs_job_failed (G_VFS_JOB (job),
+                        G_IO_ERROR,
+                        G_IO_ERROR_NOT_FOUND,
+                        _("No thumbnail for entity '%s'"),
+                        icon_id);
+      goto exit;
     }
 
     RWHandle *handle = g_new0(RWHandle, 1);


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