[evolution-mapi] Bug #691772 - Long text/html message constructed as text/plain only



commit 6c6ca888675aac48b5082bf81bb6a2df0f42c142
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jan 15 14:04:52 2013 +0100

    Bug #691772 - Long text/html message constructed as text/plain only

 src/libexchangemapi/e-mapi-cal-utils.c  |   28 +++++++++++--
 src/libexchangemapi/e-mapi-connection.c |   62 +++++++++++++++++++++++-------
 src/libexchangemapi/e-mapi-connection.h |    4 ++
 src/libexchangemapi/e-mapi-mail-utils.c |   56 +++++++++++++--------------
 src/libexchangemapi/e-mapi-utils.c      |    2 +-
 5 files changed, 102 insertions(+), 50 deletions(-)
---
diff --git a/src/libexchangemapi/e-mapi-cal-utils.c b/src/libexchangemapi/e-mapi-cal-utils.c
index cffb29c..b0b6d9c 100644
--- a/src/libexchangemapi/e-mapi-cal-utils.c
+++ b/src/libexchangemapi/e-mapi-cal-utils.c
@@ -891,13 +891,31 @@ e_mapi_cal_util_object_to_comp (EMapiConnection *conn,
 	icalcomponent_set_summary (ical_comp, str);
 
 	ui32 = e_mapi_util_find_array_propval (&object->properties, PidTagInternetCodepage);
-	str = e_mapi_util_find_array_propval (&object->properties, PidTagBody);
-	if (str) {
+	if (e_mapi_object_contains_prop (object, PidTagBody)) {
+		uint64_t text_cb = 0;
+		const uint8_t *text_lpb = NULL;
 		gchar *utf8_str = NULL;
-		uint32_t proptag = e_mapi_util_find_array_proptag (&object->properties, PidTagBody);
+		uint32_t proptag;
 
-		if (e_mapi_utils_ensure_utf8_string (proptag, ui32, (const guint8 *) str, strlen (str), &utf8_str))
-			str = utf8_str;
+		proptag = e_mapi_util_find_array_proptag (&object->properties, PidTagBody);
+		if (!proptag) {
+			EMapiStreamedProp *stream = e_mapi_object_get_streamed (object, PidTagBody);
+			if (stream)
+				proptag = stream->proptag;
+			else
+				proptag = PidTagBody;
+		}
+
+		if (e_mapi_object_get_bin_prop (object, proptag, &text_cb, &text_lpb)) {
+			if (e_mapi_utils_ensure_utf8_string (proptag, ui32, text_lpb, text_cb, &utf8_str))
+				str = utf8_str;
+			else if (text_lpb [text_cb] != 0) {
+				utf8_str = g_strndup ((const gchar *) text_lpb, text_cb);
+				str = utf8_str;
+			}
+		} else {
+			str = "";
+		}
 
 		icalcomponent_set_description (ical_comp, str);
 
diff --git a/src/libexchangemapi/e-mapi-connection.c b/src/libexchangemapi/e-mapi-connection.c
index 7637c52..e41222c 100644
--- a/src/libexchangemapi/e-mapi-connection.c
+++ b/src/libexchangemapi/e-mapi-connection.c
@@ -2132,8 +2132,8 @@ has_embedded_message_with_html (EMapiObject *object)
 		if (!attach->embedded_object)
 			continue;
 
-		if (e_mapi_util_find_array_propval (&attach->embedded_object->properties, PidTagHtml) &&
-		    !e_mapi_util_find_array_propval (&attach->embedded_object->properties, PidTagBody))
+		if (e_mapi_object_contains_prop (attach->embedded_object, PidTagHtml) &&
+		    !e_mapi_object_contains_prop (attach->embedded_object, PidTagBody))
 			return TRUE;
 
 		if (has_embedded_message_with_html (attach->embedded_object))
@@ -2232,8 +2232,8 @@ traverse_attachments_for_body (EMapiConnection *conn,
 			mapi_object_init (&obj_attach);
 			mapi_object_init (&obj_embedded);
 
-			if (e_mapi_util_find_array_propval (&attach->embedded_object->properties, PidTagHtml) &&
-			    !e_mapi_util_find_array_propval (&attach->embedded_object->properties, PidTagBody)) {
+			if (e_mapi_object_contains_prop (attach->embedded_object, PidTagHtml) &&
+			    !e_mapi_object_contains_prop (attach->embedded_object, PidTagBody)) {
 				struct SPropTagArray *tags;
 
 				if (OpenAttach (obj_message, *pattach_num, &obj_attach) != MAPI_E_SUCCESS)
@@ -2312,7 +2312,7 @@ ensure_additional_properties_cb (EMapiConnection *conn,
 	for (ii = 0; ii < G_N_ELEMENTS (additional_properties); ii++) {
 		uint32_t prop = additional_properties[ii].orig_proptag;
 
-		if (!e_mapi_util_find_array_propval (&object->properties, prop)) {
+		if (!e_mapi_object_contains_prop (object, prop)) {
 			if (get_namedid_name (prop)) {
 				prop = e_mapi_connection_resolve_named_prop (conn, eap->obj_folder, prop, cancellable, NULL);
 			}
@@ -2545,7 +2545,7 @@ fetch_object_attachment_cb (EMapiConnection *conn,
 
 	attach_method = e_mapi_util_find_row_propval (srow, PidTagAttachMethod);
 	if (attach_method && *attach_method == ATTACH_BY_VALUE) {
-		if (!e_mapi_util_find_array_propval (&attachment->properties, PidTagAttachDataBinary)) {
+		if (!e_mapi_attachment_contains_prop (attachment, PidTagAttachDataBinary)) {
 			uint64_t cb = 0;
 			uint8_t *lpb = NULL;
 
@@ -2668,7 +2668,7 @@ e_mapi_connection_fetch_object_internal (EMapiConnection *conn,
 	talloc_free (np_nameid);
 
 	/* ensure certain properties */
-	if (!e_mapi_util_find_array_propval (&object->properties, PidTagHtml)) {
+	if (!e_mapi_object_contains_prop (object, PidTagHtml)) {
 		uint8_t best_body = 0;
 
 		if (GetBestBody (obj_message, &best_body) == MAPI_E_SUCCESS && best_body == olEditorHTML) {
@@ -2685,7 +2685,7 @@ e_mapi_connection_fetch_object_internal (EMapiConnection *conn,
 		}
 	}
 
-	if (!e_mapi_util_find_array_propval (&object->properties, PidTagBody)) {
+	if (!e_mapi_object_contains_prop (object, PidTagBody)) {
 		uint64_t cb = 0;
 		uint8_t *lpb = NULL;
 
@@ -3012,7 +3012,7 @@ internal_get_summary_cb (EMapiConnection *conn,
 		for (ii = 0; ii < gsd->prop_count; ii++) {
 			/* skip errors and already included properties */
 			if ((gsd->lpProps[ii].ulPropTag & 0xFFFF) == PT_ERROR
-			    || e_mapi_util_find_array_propval (&object->properties, gsd->lpProps[ii].ulPropTag))
+			    || e_mapi_object_contains_prop (object, gsd->lpProps[ii].ulPropTag))
 				continue;
 
 			object->properties.cValues++;
@@ -7124,6 +7124,16 @@ e_mapi_attachment_get_bin_prop (EMapiAttachment *attachment,
 	return FALSE;
 }
 
+gboolean
+e_mapi_attachment_contains_prop (EMapiAttachment *attachment,
+				 uint32_t proptag)
+{
+	g_return_val_if_fail (attachment != NULL, FALSE);
+
+	return e_mapi_attachment_get_streamed (attachment, proptag) != NULL ||
+	       e_mapi_util_find_array_propval (&attachment->properties, proptag) != NULL;
+}
+
 EMapiObject *
 e_mapi_object_new (TALLOC_CTX *mem_ctx)
 {
@@ -7269,7 +7279,7 @@ e_mapi_object_get_bin_prop (EMapiObject *object,
 			    const uint8_t **lpb)
 {
 	EMapiStreamedProp *streamed;
-	const struct SBinary_short *bin;
+	gconstpointer value;
 
 	g_return_val_if_fail (object != NULL, FALSE);
 	g_return_val_if_fail (cb != NULL, FALSE);
@@ -7286,17 +7296,39 @@ e_mapi_object_get_bin_prop (EMapiObject *object,
 		return TRUE;
 	}
 
-	bin = e_mapi_util_find_array_propval (&object->properties, proptag);
-	if (bin) {
-		*cb = bin->cb;
-		*lpb = bin->lpb;
+	value = e_mapi_util_find_array_propval (&object->properties, proptag);
+	if (value) {
+		if ((proptag & 0xFFFF) == PT_BINARY) {
+			const struct SBinary_short *bin = value;
 
-		return TRUE;
+			*cb = bin->cb;
+			*lpb = bin->lpb;
+
+			return TRUE;
+		}
+
+		if ((proptag & 0xFFFF) == PT_STRING8 ||
+		    (proptag & 0xFFFF) == PT_UNICODE) {
+			*cb = strlen (value);
+			*lpb = value;
+
+			return TRUE;
+		}
 	}
 
 	return FALSE;
 }
 
+gboolean
+e_mapi_object_contains_prop (EMapiObject *object,
+			     uint32_t proptag)
+{
+	g_return_val_if_fail (object != NULL, FALSE);
+
+	return e_mapi_object_get_streamed (object, proptag) != NULL ||
+	       e_mapi_util_find_array_propval (&object->properties, proptag) != NULL;
+}
+
 EMapiPermissionEntry *
 e_mapi_permission_entry_new (const gchar *username,
 			     const struct SBinary_short *entry_id,
diff --git a/src/libexchangemapi/e-mapi-connection.h b/src/libexchangemapi/e-mapi-connection.h
index 0a49273..5cf7f5b 100644
--- a/src/libexchangemapi/e-mapi-connection.h
+++ b/src/libexchangemapi/e-mapi-connection.h
@@ -115,6 +115,8 @@ gboolean		e_mapi_attachment_get_bin_prop	(EMapiAttachment *attachment,
 							 uint32_t proptag,
 							 uint64_t *cb,
 							 const uint8_t **lpb);
+gboolean		e_mapi_attachment_contains_prop	(EMapiAttachment *attachment,
+							 uint32_t proptag);
 
 EMapiObject *		e_mapi_object_new		(TALLOC_CTX *mem_ctx);
 void			e_mapi_object_free		(EMapiObject *object);
@@ -132,6 +134,8 @@ gboolean		e_mapi_object_get_bin_prop	(EMapiObject *object,
 							 uint32_t proptag,
 							 uint64_t *cb,
 							 const uint8_t **lpb);
+gboolean		e_mapi_object_contains_prop	(EMapiObject *object,
+							 uint32_t proptag);
 
 #define E_MAPI_PERMISSION_MEMBER_ID_ANONYMOUS_CLIENT	(~((uint64_t) 0))
 #define E_MAPI_PERMISSION_MEMBER_ID_DEFAULT_USER	((uint64_t) 0)
diff --git a/src/libexchangemapi/e-mapi-mail-utils.c b/src/libexchangemapi/e-mapi-mail-utils.c
index 31ece18..fd522b7 100644
--- a/src/libexchangemapi/e-mapi-mail-utils.c
+++ b/src/libexchangemapi/e-mapi-mail-utils.c
@@ -168,7 +168,8 @@ e_mapi_mail_utils_decode_recipients (EMapiConnection *conn,
 static void
 build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t proptag)
 {
-	gconstpointer value;
+	uint64_t str_cb = 0;
+	const uint8_t *str_lpb = NULL;
 
 	g_return_if_fail (part != NULL);
 	g_return_if_fail (object != NULL);
@@ -176,8 +177,7 @@ build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t prop
 
 	camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_8BIT);
 
-	value = e_mapi_util_find_array_propval (&object->properties, proptag);
-	if (value || (proptag == PidTagHtml && e_mapi_object_get_streamed (object, proptag))) {
+	if (e_mapi_object_get_bin_prop (object, proptag, &str_cb, &str_lpb)) {
 		const gchar *type = NULL;
 		gchar *buff = NULL, *in_utf8;
 		const uint32_t *pcpid = e_mapi_util_find_array_propval (&object->properties, PidTagInternetCodepage);
@@ -188,10 +188,17 @@ build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t prop
 			type = "text/html";
 		}
 
-		proptag = e_mapi_util_find_array_proptag (&object->properties, proptag);
+		if (!e_mapi_util_find_array_proptag (&object->properties, proptag)) {
+			EMapiStreamedProp *stream = e_mapi_object_get_streamed (object, proptag);
+			if (stream)
+				proptag = stream->proptag;
+		} else {
+			proptag = e_mapi_util_find_array_proptag (&object->properties, proptag);
+		}
+
 		if (pcpid && *pcpid && (proptag & 0xFFFF) != PT_UNICODE) {
 			uint32_t cpid = *pcpid;
-	
+
 			if (cpid == 20127)
 				buff = g_strdup_printf ("%s; charset=\"us-ascii\"", type);
 			else if (cpid == 20866)
@@ -214,27 +221,18 @@ build_body_part_content (CamelMimePart *part, EMapiObject *object, uint32_t prop
 		in_utf8 = NULL;
 
 		if (proptag == PidTagHtml) {
-			uint64_t cb = 0;
-			const uint8_t *lpb = NULL;
-
-			if (!e_mapi_object_get_bin_prop (object, proptag, &cb, &lpb)) {
-				g_warn_if_reached ();
-				cb = 0;
-				lpb = (const uint8_t *) "";
-			}
-
-			if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, lpb, cb, &in_utf8))
+			if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, str_lpb, str_cb, &in_utf8))
 				camel_mime_part_set_content (part, in_utf8, strlen (in_utf8), type);
 			else
-				camel_mime_part_set_content (part, (const gchar *) lpb, cb, type);
+				camel_mime_part_set_content (part, (const gchar *) str_lpb, str_cb, type);
 			
 		} else {
-			const gchar *str = value;
-
-			if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, (const guint8 *) str, strlen (str), &in_utf8))
-				str = in_utf8;
+			if (e_mapi_utils_ensure_utf8_string (proptag, pcpid, str_lpb, str_cb, &in_utf8)) {
+				str_lpb = (const uint8_t *) in_utf8;
+				str_cb = strlen (in_utf8);
+			}
 
-			camel_mime_part_set_content (part, str, strlen (str), type);
+			camel_mime_part_set_content (part, (const gchar *) str_lpb, str_cb, type);
 		}
 
 		g_free (in_utf8);
@@ -617,12 +615,12 @@ build_multipart_related (EMapiObject *object, GSList *inline_attachments)
 	camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (m_related), "multipart/related");
 	camel_multipart_set_boundary (m_related, NULL);
 
-	if (e_mapi_util_find_array_propval (&object->properties, PidTagHtml)) {
+	if (e_mapi_object_contains_prop (object, PidTagHtml)) {
 		part = camel_mime_part_new ();
 		build_body_part_content (part, object, PidTagHtml);
 		camel_multipart_add_part (m_related, part);
 		g_object_unref (part);
-	} else if (e_mapi_util_find_array_propval (&object->properties, PidTagBody)) {
+	} else if (e_mapi_object_contains_prop (object, PidTagBody)) {
 		part = camel_mime_part_new ();
 		build_body_part_content (part, object, PidTagBody);
 		camel_multipart_add_part (m_related, part);
@@ -644,14 +642,14 @@ build_multipart_alternative (EMapiObject *object, GSList *inline_attachments)
 	camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (m_alternative), "multipart/alternative");
 	camel_multipart_set_boundary (m_alternative, NULL);
 
-	if (e_mapi_util_find_array_propval (&object->properties, PidTagBody)) {
+	if (e_mapi_object_contains_prop (object, PidTagBody)) {
 		part = camel_mime_part_new ();
 		build_body_part_content (part, object, PidTagBody);
 		camel_multipart_add_part (m_alternative, part);
 		g_object_unref (part);
 	}
 
-	if (e_mapi_util_find_array_propval (&object->properties, PidTagHtml)) {
+	if (e_mapi_object_contains_prop (object, PidTagHtml)) {
 		part = camel_mime_part_new ();
 		if (inline_attachments) {
 			CamelMultipart *m_related;
@@ -863,8 +861,8 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 	}
 
 	build_alternative = !build_calendar
-		&& e_mapi_util_find_array_propval (&object->properties, PidTagHtml)
-		&& e_mapi_util_find_array_propval (&object->properties, PidTagBody);
+		&& e_mapi_object_contains_prop (object, PidTagHtml)
+		&& e_mapi_object_contains_prop (object, PidTagBody);
 	build_related = !build_calendar && !build_alternative && inline_attachments;
 
 	if (build_calendar) {
@@ -882,7 +880,7 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 		multipart_body = camel_multipart_new ();
 		camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (multipart_body), "multipart/mixed");
 		camel_multipart_set_boundary (multipart_body, NULL);
-		if (e_mapi_util_find_array_propval (&object->properties, PidTagHtml))
+		if (e_mapi_object_contains_prop (object, PidTagHtml))
 			build_body_part_content (part, object, PidTagHtml);
 		else
 			build_body_part_content (part, object, PidTagBody);
@@ -890,7 +888,7 @@ e_mapi_mail_utils_object_to_message (EMapiConnection *conn, /* const */ EMapiObj
 		g_object_unref (part);
 	} else {
 		/* Flat message */
-		if (e_mapi_util_find_array_propval (&object->properties, PidTagHtml))
+		if (e_mapi_object_contains_prop (object, PidTagHtml))
 			build_body_part_content (CAMEL_MIME_PART (msg), object, PidTagHtml);
 		else
 			build_body_part_content (CAMEL_MIME_PART (msg), object, PidTagBody);
diff --git a/src/libexchangemapi/e-mapi-utils.c b/src/libexchangemapi/e-mapi-utils.c
index a876df1..fc5c2c0 100644
--- a/src/libexchangemapi/e-mapi-utils.c
+++ b/src/libexchangemapi/e-mapi-utils.c
@@ -331,7 +331,7 @@ e_mapi_util_find_array_proptag (struct mapi_SPropValue_array *properties, uint32
 		}
 	}
 
-	return proptag;
+	return 0;
 }
 
 enum MAPISTATUS



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