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