[evolution-data-server] I#309 - EContact: Inline locally stored image does not retain its mime type
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#309 - EContact: Inline locally stored image does not retain its mime type
- Date: Mon, 8 Mar 2021 16:38:34 +0000 (UTC)
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]