evolution-3.6.4/em-format/e-mail-parser-multipart-alternative.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-parser-multipart-alternative.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-parser-multipart-alternative.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-mail-parser-multipart-alternative.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  */
 18 
 19 #ifdef HAVE_CONFIG_H
 20 #include <config.h>
 21 #endif
 22 
 23 #include "e-mail-format-extensions.h"
 24 
 25 #include <em-format/e-mail-parser-extension.h>
 26 #include <em-format/e-mail-parser.h>
 27 #include <em-format/e-mail-part-utils.h>
 28 #include <e-util/e-util.h>
 29 
 30 #include <camel/camel.h>
 31 
 32 #include <string.h>
 33 
 34 typedef struct _EMailParserMultipartAlternative {
 35 	GObject parent;
 36 } EMailParserMultipartAlternative;
 37 
 38 typedef struct _EMailParserMultipartAlternativeClass {
 39 	GObjectClass parent_class;
 40 } EMailParserMultipartAlternativeClass;
 41 
 42 static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
 43 static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
 44 
 45 G_DEFINE_TYPE_EXTENDED (
 46 	EMailParserMultipartAlternative,
 47 	e_mail_parser_multipart_alternative,
 48 	G_TYPE_OBJECT,
 49 	0,
 50 	G_IMPLEMENT_INTERFACE (
 51 		E_TYPE_MAIL_EXTENSION,
 52 		e_mail_parser_mail_extension_interface_init)
 53 	G_IMPLEMENT_INTERFACE (
 54 		E_TYPE_MAIL_PARSER_EXTENSION,
 55 		e_mail_parser_parser_extension_interface_init));
 56 
 57 static const gchar * parser_mime_types[] = { "multipart/alternative", NULL };
 58 
 59 static gboolean
 60 related_display_part_is_attachment (CamelMimePart *part)
 61 {
 62 	CamelMimePart *display_part;
 63 
 64 	display_part = e_mail_part_get_related_display_part (part, NULL);
 65 	return display_part && e_mail_part_is_attachment (display_part);
 66 }
 67 
 68 static GSList *
 69 empe_mp_alternative_parse (EMailParserExtension *extension,
 70                            EMailParser *parser,
 71                            CamelMimePart *part,
 72                            GString *part_id,
 73                            GCancellable *cancellable)
 74 {
 75 	CamelMultipart *mp;
 76 	gint i, nparts, bestid = 0;
 77 	CamelMimePart *best = NULL;
 78 	GSList *parts;
 79 	EMailExtensionRegistry *reg;
 80 
 81 	if (g_cancellable_is_cancelled (cancellable))
 82 		return NULL;
 83 
 84 	reg = e_mail_parser_get_extension_registry (parser);
 85 
 86 	mp = (CamelMultipart *) camel_medium_get_content ((CamelMedium *) part);
 87 
 88 	if (!CAMEL_IS_MULTIPART (mp)) {
 89 		return e_mail_parser_parse_part_as (
 90 				parser, part, part_id,
 91 				"application/vnd.evolution.source",
 92 				cancellable);
 93 	}
 94 
 95 	/* as per rfc, find the last part we know how to display */
 96 	nparts = camel_multipart_get_number (mp);
 97 	for (i = 0; i < nparts; i++) {
 98 		CamelMimePart *mpart;
 99 		CamelDataWrapper *data_wrapper;
100 		CamelContentType *type;
101 		CamelStream *null_stream;
102 		gchar *mime_type;
103 		gsize content_size;
104 
105 		if (g_cancellable_is_cancelled (cancellable))
106 			return NULL;
107 
108 		/* is it correct to use the passed in *part here? */
109 		mpart = camel_multipart_get_part (mp, i);
110 
111 		if (mpart == NULL)
112 			continue;
113 
114 		/* This may block even though the stream does not.
115 		 * XXX Pretty inefficient way to test if the MIME part
116 		 *     is empty.  Surely there's a quicker way? */
117 		null_stream = camel_stream_null_new ();
118 		data_wrapper = camel_medium_get_content (CAMEL_MEDIUM (mpart));
119 		camel_data_wrapper_decode_to_stream_sync (
120 			data_wrapper, null_stream, cancellable, NULL);
121 		content_size = CAMEL_STREAM_NULL (null_stream)->written;
122 		g_object_unref (null_stream);
123 
124 		if (content_size == 0)
125 			continue;
126 
127 		type = camel_mime_part_get_content_type (mpart);
128 		mime_type = camel_content_type_simple (type);
129 
130 		camel_strdown (mime_type);
131 
132 		if (!e_mail_part_is_attachment (mpart) &&
133 			 ((camel_content_type_is (type, "multipart", "related") == 0) ||
134 			  !related_display_part_is_attachment (mpart)) &&
135 		    (e_mail_extension_registry_get_for_mime_type (reg, mime_type) ||
136 			((best == NULL) &&
137 			 (e_mail_extension_registry_get_fallback (reg, mime_type)))))
138 		{
139 			best = mpart;
140 			bestid = i;
141 		}
142 
143 		g_free (mime_type);
144 	}
145 
146 	if (best) {
147 		gint len = part_id->len;
148 
149 		g_string_append_printf (part_id, ".alternative.%d", bestid);
150 
151 		parts = e_mail_parser_parse_part (
152 			parser, best, part_id, cancellable);
153 
154 		g_string_truncate (part_id, len);
155 	} else {
156 		parts = e_mail_parser_parse_part_as (
157 			parser, part, part_id, "multipart/mixed", cancellable);
158 	}
159 
160 	return parts;
161 }
162 
163 static const gchar **
164 empe_mp_alternative_mime_types (EMailExtension *extension)
165 {
166 	return parser_mime_types;
167 }
168 
169 static void
170 e_mail_parser_multipart_alternative_class_init (EMailParserMultipartAlternativeClass *class)
171 {
172 }
173 
174 static void
175 e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
176 {
177 	iface->parse = empe_mp_alternative_parse;
178 }
179 
180 static void
181 e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
182 {
183 	iface->mime_types = empe_mp_alternative_mime_types;
184 }
185 
186 static void
187 e_mail_parser_multipart_alternative_init (EMailParserMultipartAlternative *parser)
188 {
189 
190 }