[evolution-data-server] I#309 - EContact: Inline locally stored image does not retain its mime type



commit eae4e9b5268c841d8f9b667e7d9bb592f11ac496
Author: Milan Crha <mcrha redhat com>
Date:   Mon Mar 8 17:35:33 2021 +0100

    I#309 - EContact: Inline locally stored image does not retain its mime type
    
    This broke with commit 0394a3bd9cd0b0cbf3a9bc1eac70f5a4849f6df6 for the file
    backend, because the EContact's e_contact_inline_local_photos() could not
    decipher the original MIME type from the file extension.
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/309

 src/addressbook/libebook-contacts/e-contact.c      | 37 ++++++++++++++++++--
 .../client/test-book-client-photo-is-uri.c         | 39 ++++++++++++++++++----
 tests/libebook/data/vcards/logo-1.vcf              |  2 +-
 tests/libebook/data/vcards/photo-1.vcf             |  2 +-
 tests/libedata-book/test-book-meta-backend.c       |  6 ++++
 5 files changed, 76 insertions(+), 10 deletions(-)
---
diff --git a/src/addressbook/libebook-contacts/e-contact.c b/src/addressbook/libebook-contacts/e-contact.c
index 0b3edc5ee..54f14fd84 100644
--- a/src/addressbook/libebook-contacts/e-contact.c
+++ b/src/addressbook/libebook-contacts/e-contact.c
@@ -2633,6 +2633,7 @@ mime_type_from_filename (const gchar *filename)
        gchar *extension;
        gchar *mime_type;
        gchar *content_type;
+       guint len;
 
        extension = strrchr (filename, '.');
        if (extension)
@@ -2641,8 +2642,40 @@ mime_type_from_filename (const gchar *filename)
        if (!extension)
                return NULL;
 
-       mime_type = g_uri_unescape_string (extension, NULL);
-       content_type = g_content_type_from_mime_type (mime_type);
+       len = strlen (extension);
+
+       if (len == 3 || len == 4) {
+               mime_type = g_strconcat ("image/", extension, NULL);
+
+       /* The '/' is URL-escaped to '%2F' and the '%' is replaced to '-',
+          to avoid URL-escaping in the URI */
+       } else if (strstr (extension, "-2F") || strstr (extension, "-2f")) {
+               gchar *copy, *pp, *ww;
+
+               copy = g_strdup (extension);
+
+               /* De-mangle dashes to percent marks; cannot recognize valid dashes,
+                  but the extension might be "image-2Fext", which should be fine
+                  (it decodes to "image/ext" at the end). */
+               for (pp = copy, ww = pp; *pp; pp++, ww++) {
+                       if (*pp == '-' && pp[1] == '2' && (pp[2] == 'F' || pp[2] == 'f')) {
+                               *ww = '/';
+                               pp += 2;
+                       } else if (pp != ww) {
+                               *ww = *pp;
+                       }
+               }
+
+               *ww = '\0';
+
+               mime_type = g_uri_unescape_string (copy, NULL);
+
+               g_free (copy);
+       } else {
+               mime_type = g_uri_unescape_string (extension, NULL);
+       }
+
+       content_type = mime_type ? g_content_type_from_mime_type (mime_type) : NULL;
 
        if (!content_type) {
                g_free (mime_type);
diff --git a/tests/libebook/client/test-book-client-photo-is-uri.c 
b/tests/libebook/client/test-book-client-photo-is-uri.c
index 077e15cd0..0fb7a4fd6 100644
--- a/tests/libebook/client/test-book-client-photo-is-uri.c
+++ b/tests/libebook/client/test-book-client-photo-is-uri.c
@@ -65,6 +65,8 @@ print_contact (EContact *contact)
        g_assert (photo != NULL);
        g_assert (photo->type == E_CONTACT_PHOTO_TYPE_URI);
        g_print ("Test passed with photo uri: %s\n", photo->data.uri);
+
+       e_contact_photo_free (photo);
 }
 
 static void
@@ -139,6 +141,9 @@ give_james_brown_micheal_jacksons_face (EBookClient *book)
 
        if (!e_book_client_modify_contact_sync (book, james, E_BOOK_OPERATION_FLAG_NONE, NULL, &error))
                g_error ("Failed to modify contact with cross referenced photo: %s", error->message);
+
+       g_object_unref (micheal);
+       g_object_unref (james);
 }
 
 static void
@@ -160,7 +165,7 @@ update_contact_inline (EBookClient *book,
 
        photo = e_contact_photo_new ();
        photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
-       photo->data.inlined.mime_type = NULL;
+       photo->data.inlined.mime_type = g_strdup ("image/png");
        photo->data.inlined.data = data;
        photo->data.inlined.length = length;
 
@@ -171,6 +176,8 @@ update_contact_inline (EBookClient *book,
 
        if (!e_book_client_modify_contact_sync (book, contact, E_BOOK_OPERATION_FLAG_NONE, NULL, &error))
                g_error ("Failed to modify contact with inline photo data: %s", error->message);
+
+       g_object_unref (contact);
 }
 
 /* This assertion is made a couple of times in the view-complete
@@ -180,13 +187,14 @@ static void
 assert_uri_exists (EBookClient *book,
                    const gchar *uid)
 {
-       EContact      *contact;
+       EContact *contact;
        EContactPhoto *photo;
-       const gchar   *filename;
-       GError        *error = NULL;
+       gchar *filename;
+       gboolean success;
+       GError *error = NULL;
 
        if (!e_book_client_get_contact_sync (book, uid, &contact, NULL, &error))
-         g_error ("Unable to get contact: %s", error->message);
+               g_error ("Unable to get contact: %s", error->message);
 
        g_assert (contact);
 
@@ -199,6 +207,21 @@ assert_uri_exists (EBookClient *book,
 
        /* The file should absolutely exist at this point */
        g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
+
+       e_contact_photo_free (photo);
+
+       success = e_contact_inline_local_photos (contact, &error);
+       g_assert_no_error (error);
+       g_assert (success);
+
+       photo = e_contact_get (contact, E_CONTACT_PHOTO);
+       g_assert (photo);
+       g_assert (photo->type == E_CONTACT_PHOTO_TYPE_INLINED);
+       g_assert_cmpstr (e_contact_photo_get_mime_type (photo), ==, "image/png");
+
+       e_contact_photo_free (photo);
+       g_object_unref (contact);
+       g_free (filename);
 }
 
 static void
@@ -284,7 +307,7 @@ add_contact_inline (EBookClient *book)
 
        photo = e_contact_photo_new ();
        photo->type = E_CONTACT_PHOTO_TYPE_INLINED;
-       photo->data.inlined.mime_type = NULL;
+       photo->data.inlined.mime_type = g_strdup ("image/png");
        photo->data.inlined.data = data;
        photo->data.inlined.length = length;
 
@@ -298,6 +321,8 @@ add_contact_inline (EBookClient *book)
                g_error ("Failed to add contact");
 
        micheal_jackson_uid = e_contact_get (contact, E_CONTACT_UID);
+
+       g_object_unref (contact);
 }
 
 static void
@@ -322,6 +347,8 @@ add_contact_uri (EBookClient *book)
                g_error ("Failed to add contact");
 
        james_brown_uid = e_contact_get (contact, E_CONTACT_UID);
+
+       g_object_unref (contact);
 }
 
 static void
diff --git a/tests/libebook/data/vcards/logo-1.vcf b/tests/libebook/data/vcards/logo-1.vcf
index ad1de8c66..b6cd77277 100644
--- a/tests/libebook/data/vcards/logo-1.vcf
+++ b/tests/libebook/data/vcards/logo-1.vcf
@@ -3,7 +3,7 @@ VERSION:3.0
 UID:logo-1
 FN:logo
 N:;logo;;;
-LOGO;TYPE="X-EVOLUTION-UNKNOWN";ENCODING=b:/9j/4AAQSkZJRgABAQEASABIAAD/2wB
+LOGO;TYPE="PNG";ENCODING=b:/9j/4AAQSkZJRgABAQEASABIAAD/2wB
  DABYPEBMQDhYTEhMYFxYaIDYjIB4eIEIvMic2TkVSUU1FTEpWYXxpVlx1XUpMbJNtdYCEi4yLV
  GiZo5eHonyIi4b/2wBDARcYGCAcID8jIz+GWUxZhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoa
  GhoaGhoaGhoaGhoaGhoaGhoaGhoaGhob/wgARCABAAEADAREAAhEBAxEB/8QAFgABAQEAAAAAA
diff --git a/tests/libebook/data/vcards/photo-1.vcf b/tests/libebook/data/vcards/photo-1.vcf
index 4bf5bcec3..d32816503 100644
--- a/tests/libebook/data/vcards/photo-1.vcf
+++ b/tests/libebook/data/vcards/photo-1.vcf
@@ -3,7 +3,7 @@ VERSION:3.0
 UID:photo-1
 FN:photo
 N:;photo;;;
-PHOTO;TYPE="X-EVOLUTION-UNKNOWN";ENCODING=b:iVBORw0KGgoAAAANSUhEUgAAAEAAAAB
+PHOTO;TYPE="jpeg";ENCODING=b:iVBORw0KGgoAAAANSUhEUgAAAEAAAAB
  ACAIAAAAlC+aJAAAKo0lEQVRo3n1aW7LcuA4j6OzkLujufxOzgu5gPsQHIHdNqpKc03bbEh8gC
  Ar//98/D74Pvonvk98nvw++mZ8Hf5/8PPk38XnwffLz4Jv5/ZN+Jz5P/n3wOR/q1cSnn/b9U8/
  /PPlNfP9gb8j8ngU8+X3wyX7yfPd8+Of83DdnnlV9E0QQgQBi/oD9ExlxLiACCJCBiGAE++Pg+
diff --git a/tests/libedata-book/test-book-meta-backend.c b/tests/libedata-book/test-book-meta-backend.c
index aae2e654c..b3fdddd6e 100644
--- a/tests/libedata-book/test-book-meta-backend.c
+++ b/tests/libedata-book/test-book-meta-backend.c
@@ -697,6 +697,7 @@ test_one_photo (EBookMetaBackend *meta_backend,
        gchar *new_content = NULL;
        gsize orig_len = 0, new_len = 0;
        gchar *filename;
+       gchar *mime_type;
        gboolean success;
        GError *error = NULL;
 
@@ -715,6 +716,9 @@ test_one_photo (EBookMetaBackend *meta_backend,
        g_assert_nonnull (orig_content);
        g_assert_cmpint (orig_len, >, 0);
 
+       mime_type = g_strdup (e_contact_photo_get_mime_type (photo));
+       g_assert_nonnull (mime_type);
+
        orig_content = g_memdup (orig_content, (guint) orig_len);
 
        e_contact_photo_free (photo);
@@ -754,9 +758,11 @@ test_one_photo (EBookMetaBackend *meta_backend,
        new_content = (gchar *) e_contact_photo_get_inlined (photo, &new_len);
        g_assert_nonnull (new_content);
        g_assert_cmpmem (orig_content, orig_len, new_content, new_len);
+       g_assert_cmpstr (mime_type, ==, e_contact_photo_get_mime_type (photo));
 
        e_contact_photo_free (photo);
        g_free (orig_content);
+       g_free (mime_type);
 
        /* Also try with remote URI, which should be left as is */
        photo = e_contact_photo_new ();


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