evolution-3.6.4/em-format/e-mail-parser-text-plain.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-parser-text-plain.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-parser-text-plain.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-text-plain.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-inline-filter.h>
 28 #include <em-format/e-mail-part-utils.h>
 29 #include <e-util/e-util.h>
 30 
 31 #include <glib/gi18n-lib.h>
 32 #include <camel/camel.h>
 33 #include <ctype.h>
 34 
 35 typedef struct _EMailParserTextPlain {
 36 	GObject parent;
 37 } EMailParserTextPlain;
 38 
 39 typedef struct _EMailParserTextPlainClass {
 40 	GObjectClass parent_class;
 41 } EMailParserTextPlainClass;
 42 
 43 static void e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface);
 44 static void e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface);
 45 
 46 G_DEFINE_TYPE_EXTENDED (
 47 	EMailParserTextPlain,
 48 	e_mail_parser_text_plain,
 49 	G_TYPE_OBJECT,
 50 	0,
 51 	G_IMPLEMENT_INTERFACE (
 52 		E_TYPE_MAIL_EXTENSION,
 53 		e_mail_parser_mail_extension_interface_init)
 54 	G_IMPLEMENT_INTERFACE (
 55 		E_TYPE_MAIL_PARSER_EXTENSION,
 56 		e_mail_parser_parser_extension_interface_init));
 57 
 58 static const gchar *parser_mime_types[] = { "text/plain", "text/*", NULL };
 59 
 60 static gboolean
 61 part_is_empty (CamelMimePart *part)
 62 {
 63 	CamelDataWrapper *dw;
 64 	GByteArray *ba;
 65 	guint i;
 66 
 67 	dw = camel_medium_get_content (CAMEL_MEDIUM (part));
 68 	ba = camel_data_wrapper_get_byte_array (dw);
 69 
 70 	if (!ba)
 71 		return TRUE;
 72 
 73 	for (i = 0; i < ba->len; i++) {
 74 
 75 		/* Checks for \n, \t, \f, \r, \v and space */
 76 		if (!isspace (ba->data[i]))
 77 			return FALSE;
 78 	}
 79 
 80 	return TRUE;
 81 }
 82 
 83 static GSList *
 84 process_part (EMailParser *parser,
 85               GString *part_id,
 86               gint part_number,
 87               CamelMimePart *part,
 88               gboolean is_attachment,
 89               GCancellable *cancellable)
 90 {
 91 	CamelContentType *type;
 92 	EMailPart *empart;
 93 	gint s_len = part_id->len;
 94 	GSList *parts;
 95 
 96 	if (part_is_empty (part)) {
 97 		return g_slist_alloc ();
 98 	}
 99 
100 	type = camel_mime_part_get_content_type (part);
101 	if (!camel_content_type_is (type, "text", "*")) {
102 
103 		parts = e_mail_parser_parse_part (
104 				parser, CAMEL_MIME_PART (part),
105 				part_id, cancellable);
106 		return parts;
107 
108 	} else if (!camel_content_type_is (type, "text", "calendar")) {
109 
110 		g_string_append_printf (part_id, ".plain_text.%d", part_number);
111 
112 		empart = e_mail_part_new (part, part_id->str);
113 		empart->mime_type = camel_content_type_simple (type);
114 
115 		g_string_truncate (part_id, s_len);
116 
117 		if (is_attachment) {
118 
119 			return e_mail_parser_wrap_as_attachment (
120 					parser, part,
121 					g_slist_append (NULL, empart),
122 					part_id, cancellable);
123 
124 		}
125 
126 		return g_slist_append (NULL, empart);
127 	}
128 
129 	g_string_append_printf (part_id, ".inline.%d", part_number);
130 
131 	parts = e_mail_parser_parse_part (
132 			parser, CAMEL_MIME_PART (part),
133 			part_id, cancellable);
134 
135 	g_string_truncate (part_id, s_len);
136 
137 	return parts;
138 }
139 
140 static GSList *
141 empe_text_plain_parse (EMailParserExtension *extension,
142                        EMailParser *parser,
143                        CamelMimePart *part,
144                        GString *part_id,
145                        GCancellable *cancellable)
146 {
147 	GSList *parts;
148 	CamelStream *filtered_stream, *null;
149 	CamelMultipart *mp;
150 	CamelDataWrapper *dw;
151 	CamelContentType *type;
152 	gint i, count;
153 	EMailInlineFilter *inline_filter;
154 	gboolean charset_added = FALSE;
155 	const gchar *snoop_type = NULL;
156 	gboolean is_attachment;
157 
158 	if (g_cancellable_is_cancelled (cancellable))
159 		return NULL;
160 
161 	dw = camel_medium_get_content ((CamelMedium *) part);
162 	if (!dw)
163 		return NULL;
164 
165 	/* This scans the text part for inline-encoded data, creates
166 	 * a multipart of all the parts inside it. */
167 
168 	/* FIXME: We should discard this multipart if it only contains
169 	 * the original text, but it makes this hash lookup more complex */
170 	if (!dw->mime_type)
171 		snoop_type = e_mail_part_snoop_type (part);
172 
173 	/* if we had to snoop the part type to get here, then
174 	 * use that as the base type, yuck */
175 	if (snoop_type == NULL
176 		|| (type = camel_content_type_decode (snoop_type)) == NULL) {
177 		type = dw->mime_type;
178 		camel_content_type_ref (type);
179 	}
180 
181 	if (dw->mime_type && type != dw->mime_type && camel_content_type_param (dw->mime_type, "charset")) {
182 		camel_content_type_set_param (type, "charset", camel_content_type_param (dw->mime_type, "charset"));
183 		charset_added = TRUE;
184 	}
185 
186 	null = camel_stream_null_new ();
187 	filtered_stream = camel_stream_filter_new (null);
188 	g_object_unref (null);
189 	inline_filter = e_mail_inline_filter_new (
190 		camel_mime_part_get_encoding (part),
191 		type,
192 		camel_mime_part_get_filename (part));
193 
194 	camel_stream_filter_add (
195 		CAMEL_STREAM_FILTER (filtered_stream),
196 		CAMEL_MIME_FILTER (inline_filter));
197 	camel_data_wrapper_decode_to_stream_sync (
198 		dw, (CamelStream *) filtered_stream, cancellable, NULL);
199 	camel_stream_close ((CamelStream *) filtered_stream, cancellable, NULL);
200 	g_object_unref (filtered_stream);
201 
202 	if (!e_mail_inline_filter_found_any (inline_filter)) {
203 		g_object_unref (inline_filter);
204 		camel_content_type_unref (type);
205 
206 		return process_part (
207 			parser, part_id, 0,
208 			part, e_mail_part_is_attachment (part),
209 			cancellable);
210 	}
211 
212 	mp = e_mail_inline_filter_get_multipart (inline_filter);
213 
214 	if (charset_added) {
215 		camel_content_type_set_param (type, "charset", NULL);
216 	}
217 
218 	g_object_unref (inline_filter);
219 	camel_content_type_unref (type);
220 
221 	/* We handle our made-up multipart here, so we don't recursively call ourselves */
222 	count = camel_multipart_get_number (mp);
223 	parts = NULL;
224 
225 	is_attachment = ((count == 1) && (e_mail_part_is_attachment (part)));
226 
227 	for (i = 0; i < count; i++) {
228 		CamelMimePart *newpart = camel_multipart_get_part (mp, i);
229 
230 		if (!newpart)
231 			continue;
232 
233 		parts = g_slist_concat (
234 			parts,
235 			process_part (
236 				parser, part_id, i,
237 				newpart, is_attachment,
238 				cancellable));
239 	}
240 
241 	g_object_unref (mp);
242 
243 	return parts;
244 }
245 
246 static const gchar **
247 empe_text_plain_mime_types (EMailExtension *extension)
248 {
249 	return parser_mime_types;
250 }
251 
252 static void
253 e_mail_parser_text_plain_class_init (EMailParserTextPlainClass *class)
254 {
255 }
256 
257 static void
258 e_mail_parser_parser_extension_interface_init (EMailParserExtensionInterface *iface)
259 {
260 	iface->parse = empe_text_plain_parse;
261 }
262 
263 static void
264 e_mail_parser_mail_extension_interface_init (EMailExtensionInterface *iface)
265 {
266 	iface->mime_types = empe_text_plain_mime_types;
267 }
268 
269 static void
270 e_mail_parser_text_plain_init (EMailParserTextPlain *parser)
271 {
272 
273 }