No issues found
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 |
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 }