File: | activesyncd/libeasclient/eas-email-info.c |
Warning: | line 323, column 9 Array access (from variable 'strv') results in a null pointer dereference |
1 | /* | |||
2 | * ActiveSync client library for email access | |||
3 | * | |||
4 | * Copyright © 2011 Intel Corporation. | |||
5 | * | |||
6 | * Authors: Mobica Ltd. <www.mobica.com> | |||
7 | * | |||
8 | * This library is free software; you can redistribute it and/or | |||
9 | * modify it under the terms of the GNU Lesser General Public | |||
10 | * License as published by the Free Software Foundation; either | |||
11 | * version 2.1 of the License, or (at your option) any later | |||
12 | * version. | |||
13 | * | |||
14 | * This library is distributed in the hope that it will be useful, | |||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
17 | * Lesser General Public License for more details. | |||
18 | * | |||
19 | * You should have received a copy of the GNU Lesser General Public | |||
20 | * License along with this library; if not, write to the Free | |||
21 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |||
22 | * Boston, MA 02110-1301 USA | |||
23 | * | |||
24 | */ | |||
25 | ||||
26 | #include <stdio.h> | |||
27 | #include <stdlib.h> | |||
28 | #include <string.h> | |||
29 | #include <libxml/globals.h> | |||
30 | ||||
31 | #include "eas-email-info.h" | |||
32 | #include "eas-attachment.h" | |||
33 | ||||
34 | G_DEFINE_TYPE (EasEmailInfo, eas_email_info, G_TYPE_OBJECT)static void eas_email_info_init (EasEmailInfo *self); static void eas_email_info_class_init (EasEmailInfoClass *klass); static gpointer eas_email_info_parent_class = ((void*)0); static gint EasEmailInfo_private_offset; static void eas_email_info_class_intern_init (gpointer klass) { eas_email_info_parent_class = g_type_class_peek_parent (klass); if (EasEmailInfo_private_offset != 0) g_type_class_adjust_private_offset (klass, &EasEmailInfo_private_offset); eas_email_info_class_init ((EasEmailInfoClass*) klass); } __attribute__((__unused__)) static inline gpointer eas_email_info_get_instance_private (EasEmailInfo *self) { return (((gpointer) ((guint8*) (self) + (glong) (EasEmailInfo_private_offset )))); } GType eas_email_info_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if ((__extension__ ({ typedef char _GStaticAssertCompileTimeAssertion_4[(sizeof *(&g_define_type_id__volatile ) == sizeof (gpointer)) ? 1 : -1] __attribute__((__unused__)) ; (void) (0 ? (gpointer) *(&g_define_type_id__volatile) : 0); (!(__extension__ ({ typedef char _GStaticAssertCompileTimeAssertion_5 [(sizeof *(&g_define_type_id__volatile) == sizeof (gpointer )) ? 1 : -1] __attribute__((__unused__)); __sync_synchronize ( ); (gpointer) *(&g_define_type_id__volatile); })) && g_once_init_enter (&g_define_type_id__volatile)); }))) { GType g_define_type_id = g_type_register_static_simple (((GType ) ((20) << (2))), g_intern_static_string ("EasEmailInfo" ), sizeof (EasEmailInfoClass), (GClassInitFunc) eas_email_info_class_intern_init , sizeof (EasEmailInfo), (GInstanceInitFunc) eas_email_info_init , (GTypeFlags) 0); { {{};} } (__extension__ ({ typedef char _GStaticAssertCompileTimeAssertion_6 [(sizeof *(&g_define_type_id__volatile) == sizeof (gpointer )) ? 1 : -1] __attribute__((__unused__)); (void) (0 ? *(& g_define_type_id__volatile) = (g_define_type_id) : 0); g_once_init_leave ((&g_define_type_id__volatile), (gsize) (g_define_type_id )); })); } return g_define_type_id__volatile; }; | |||
35 | ||||
36 | const gchar *sep = "\n"; | |||
37 | ||||
38 | static void | |||
39 | eas_email_info_init (EasEmailInfo *object) | |||
40 | { | |||
41 | g_debug ("eas_email_info_init++"); | |||
42 | /* initialization code */ | |||
43 | object->server_id = NULL((void*)0); | |||
44 | object->headers = NULL((void*)0); | |||
45 | object->attachments = NULL((void*)0); | |||
46 | object->categories = NULL((void*)0); | |||
47 | object->status = NULL((void*)0); | |||
48 | object->flags = 0; | |||
49 | g_debug ("eas_email_info_init--"); | |||
50 | } | |||
51 | ||||
52 | static void | |||
53 | eas_email_free_header (EasEmailHeader *header) | |||
54 | { | |||
55 | g_free (header->name); | |||
56 | g_free (header->value); | |||
57 | g_free (header); | |||
58 | } | |||
59 | ||||
60 | static void | |||
61 | eas_email_info_finalize (GObject *object) | |||
62 | { | |||
63 | EasEmailInfo *self = (EasEmailInfo*) object; | |||
64 | ||||
65 | g_debug ("eas_email_info_finalize++"); | |||
66 | /* deinitalization code */ | |||
67 | g_free (self->server_id); | |||
68 | g_free (self->status); | |||
69 | ||||
70 | g_slist_foreach (self->headers, (GFunc) eas_email_free_header, NULL((void*)0)); | |||
71 | g_slist_free (self->headers); | |||
72 | ||||
73 | g_slist_foreach (self->attachments, (GFunc) g_object_unref, NULL((void*)0)); // TODO - these should be done in dispose? | |||
74 | g_slist_free (self->attachments); // list of EasAttachments | |||
75 | ||||
76 | g_slist_foreach (self->categories, (GFunc) xmlFree, NULL((void*)0)); | |||
77 | g_slist_free (self->categories); | |||
78 | ||||
79 | G_OBJECT_CLASS (eas_email_info_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((eas_email_info_parent_class )), (((GType) ((20) << (2))))))))->finalize (object); | |||
80 | g_debug ("eas_email_info_finalize--"); | |||
81 | } | |||
82 | ||||
83 | static void | |||
84 | eas_email_info_class_init (EasEmailInfoClass *klass) | |||
85 | { | |||
86 | GObjectClass* object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass )), (((GType) ((20) << (2)))))))); | |||
87 | ||||
88 | object_class->finalize = eas_email_info_finalize; | |||
89 | } | |||
90 | ||||
91 | EasEmailInfo * | |||
92 | eas_email_info_new() | |||
93 | { | |||
94 | EasEmailInfo *object = NULL((void*)0); | |||
95 | g_debug ("eas_email_info_new++"); | |||
96 | ||||
97 | object = g_object_new (EAS_TYPE_EMAIL_INFO(eas_email_info_get_type ()) , NULL((void*)0)); | |||
98 | ||||
99 | g_debug ("eas_email_info_new--"); | |||
100 | ||||
101 | return object; | |||
102 | } | |||
103 | ||||
104 | ||||
105 | gboolean | |||
106 | eas_email_info_serialise (EasEmailInfo* self, gchar **result) | |||
107 | { | |||
108 | GString *ser; | |||
109 | gboolean ret = TRUE1; | |||
110 | gchar *temp = NULL((void*)0); | |||
111 | guint list_len = 0; | |||
112 | GSList *l = NULL((void*)0); | |||
113 | EasEmailHeader *header = NULL((void*)0); | |||
114 | EasAttachment *attachment = NULL((void*)0); | |||
115 | gchar *category = NULL((void*)0); | |||
116 | ||||
117 | g_debug ("eas_email_info_serialise++"); | |||
118 | ||||
119 | // serialise everything: | |||
120 | //server_id | |||
121 | g_debug ("serialising serverid"); | |||
122 | ser = g_string_new (self->server_id); | |||
123 | g_string_append (ser, sep); | |||
124 | ||||
125 | //headers | |||
126 | g_debug ("serialising headers"); | |||
127 | list_len = g_slist_length (self->headers); | |||
128 | g_string_append_printf (ser, "%d\n", list_len); | |||
129 | ||||
130 | for (l = self->headers; l != NULL((void*)0); l = g_slist_next (l)((l) ? (((GSList *)(l))->next) : ((void*)0))) { | |||
131 | header = l->data; | |||
132 | g_string_append_printf (ser, "%s\n%s\n", header->name, header->value); | |||
133 | } | |||
134 | ||||
135 | //attachments | |||
136 | g_debug ("serialising attachments"); | |||
137 | list_len = g_slist_length (self->attachments); | |||
138 | g_string_append_printf (ser, "%d\n", list_len); | |||
139 | ||||
140 | for (l = self->attachments; l != NULL((void*)0); l = g_slist_next (l)((l) ? (((GSList *)(l))->next) : ((void*)0))) { | |||
141 | attachment = l->data; | |||
142 | ||||
143 | if (!eas_attachment_serialise (attachment, &temp)) { | |||
144 | ret = FALSE0; | |||
145 | } else { | |||
146 | g_string_append (ser, temp); | |||
147 | g_free (temp); | |||
148 | temp = NULL((void*)0); | |||
149 | g_string_append (ser, sep); | |||
150 | } | |||
151 | } | |||
152 | ||||
153 | //flags | |||
154 | g_debug ("serialising flags"); | |||
155 | g_string_append_printf (ser, "%d\n", self->flags); | |||
156 | ||||
157 | //categories | |||
158 | g_debug ("serialising categories"); | |||
159 | list_len = g_slist_length (self->categories); | |||
160 | g_string_append_printf (ser, "%d\n", list_len); | |||
161 | for (l = self->categories; l != NULL((void*)0); l = g_slist_next (l)((l) ? (((GSList *)(l))->next) : ((void*)0))) { | |||
162 | category = l->data; | |||
163 | g_string_append_printf (ser, "%s\n", category); | |||
164 | } | |||
165 | // estimated size, date received | |||
166 | g_string_append_printf (ser, "%zu\n%ld\n%d\n", self->estimated_size, self->date_received, self->importance); | |||
167 | ||||
168 | // status | |||
169 | g_debug ("serialising status %s", self->status); | |||
170 | g_string_append_printf (ser, "%s", (self->status ? : "")); | |||
171 | ||||
172 | if (ret) { | |||
173 | *result = ser->str; | |||
174 | g_string_free (ser, FALSE0); | |||
175 | } else { | |||
176 | g_debug ("failed!"); | |||
177 | g_string_free (ser, TRUE1); | |||
178 | *result = NULL((void*)0); | |||
179 | } | |||
180 | ||||
181 | g_debug ("eas_email_info_serialise--"); | |||
182 | return ret; | |||
183 | } | |||
184 | ||||
185 | gboolean | |||
186 | eas_email_info_deserialise (EasEmailInfo* self, const gchar *data) | |||
187 | { | |||
188 | // TODO proper error handling - eg deal with get_next_field returning null | |||
189 | gboolean ret = FALSE0; | |||
190 | guint list_len = 0, i = 0; | |||
191 | EasEmailHeader *header = NULL((void*)0); | |||
192 | EasAttachment *attachment = NULL((void*)0); | |||
193 | GSList *headers = NULL((void*)0); | |||
194 | GSList *attachments = NULL((void*)0); | |||
195 | GSList *categories = NULL((void*)0); | |||
196 | gchar **strv; | |||
197 | int strvlen; | |||
198 | int idx = 0; | |||
199 | ||||
200 | g_debug ("eas_email_info_deserialise++"); | |||
201 | g_assert (self)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((self)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_ ; }), 1)) ; else g_assertion_message_expr ("libeasclient", "/data/runtests/work/sources/activesyncd/libeasclient/eas-email-info.c" , 201, ((const char*) (__func__)), "self"); } while (0); | |||
202 | g_assert (data)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_ ; if ((data)) _g_boolean_var_ = 1; else _g_boolean_var_ = 0; _g_boolean_var_ ; }), 1)) ; else g_assertion_message_expr ("libeasclient", "/data/runtests/work/sources/activesyncd/libeasclient/eas-email-info.c" , 202, ((const char*) (__func__)), "data"); } while (0); | |||
203 | ||||
204 | strv = g_strsplit (data, sep, 0); // split into array of strings | |||
| ||||
205 | if (!strv) | |||
206 | goto out; | |||
207 | ||||
208 | strvlen = g_strv_length (strv); | |||
209 | ||||
210 | idx = 0; | |||
211 | self->server_id = strv[idx++]; | |||
212 | g_debug ("server_id = %s", self->server_id); | |||
213 | ||||
214 | //headers | |||
215 | if (!strv[idx]) { | |||
216 | // This is permitted; for deleted mail we get *only* the ID | |||
217 | ret = TRUE1; | |||
218 | goto out; | |||
219 | } | |||
220 | list_len = atoi (strv[idx]); | |||
221 | g_free (strv[idx++]); | |||
222 | g_debug ("%d headers", list_len); | |||
223 | ||||
224 | if (strvlen < idx + (2 * list_len)) { | |||
225 | g_warning ("More headers than actual data"); | |||
226 | goto out; | |||
227 | } | |||
228 | for (i = 0; i < list_len; i++) { | |||
229 | header = g_malloc0 (sizeof (EasEmailHeader)); | |||
230 | header->name = strv[idx++]; | |||
231 | header->value = strv[idx++]; | |||
232 | headers = g_slist_append (headers, header); | |||
233 | } | |||
234 | self->headers = headers; | |||
235 | ||||
236 | //attachments | |||
237 | if (!strv[idx]) { | |||
238 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
239 | goto out; | |||
240 | } | |||
241 | list_len = atoi (strv[idx]); | |||
242 | g_free (strv[idx++]); | |||
243 | g_debug ("%d attachments", list_len); | |||
244 | ||||
245 | if (strvlen < idx + (3 * list_len)) { | |||
246 | g_warning ("More attachments than actual data"); | |||
247 | goto out; | |||
248 | } | |||
249 | for (i = 0; i < list_len; i++) { | |||
250 | attachment = eas_attachment_new (); | |||
251 | attachment->file_reference = (xmlChar *) strv[idx++]; | |||
252 | attachment->display_name = (xmlChar *) strv[idx++]; | |||
253 | attachment->estimated_size = atoi (strv[idx]); | |||
254 | g_free (strv[idx++]); | |||
255 | attachments = g_slist_append (attachments, attachment); | |||
256 | } | |||
257 | self->attachments = attachments; | |||
258 | ||||
259 | //flags | |||
260 | if (!strv[idx]) { | |||
261 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
262 | goto out; | |||
263 | } | |||
264 | self->flags = atoi (strv[idx]); | |||
265 | g_free (strv[idx++]); | |||
266 | g_debug ("flags = %x", self->flags); | |||
267 | ||||
268 | //categories | |||
269 | if (!strv[idx]) { | |||
270 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
271 | goto out; | |||
272 | } | |||
273 | list_len = atoi (strv[idx]); | |||
274 | g_free (strv[idx++]); | |||
275 | g_debug ("%d categories", list_len); | |||
276 | ||||
277 | if (strvlen < idx + list_len) { | |||
278 | g_warning ("More categories than actual data"); | |||
279 | goto out; | |||
280 | } | |||
281 | for (i = 0; i < list_len; i++) { | |||
282 | categories = g_slist_append (categories, strv[idx++]); | |||
283 | } | |||
284 | self->categories = categories; | |||
285 | ||||
286 | //estimated_size | |||
287 | if (!strv[idx]) { | |||
288 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
289 | goto out; | |||
290 | } | |||
291 | self->estimated_size = strtoul (strv[idx], NULL((void*)0), 10); | |||
292 | g_free (strv[idx++]); | |||
293 | g_debug ("estimated size = %zu", self->estimated_size); | |||
294 | ||||
295 | //date_received | |||
296 | if (!strv[idx]) { | |||
297 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
298 | goto out; | |||
299 | } | |||
300 | self->date_received = strtoul (strv[idx], NULL((void*)0), 10); | |||
301 | g_free (strv[idx++]); | |||
302 | g_debug ("date received = %ld", self->date_received); | |||
303 | ||||
304 | //importance | |||
305 | if (!strv[idx]) { | |||
306 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
307 | goto out; | |||
308 | } | |||
309 | self->importance = strtoul (strv[idx], NULL((void*)0), 10); | |||
310 | g_free (strv[idx++]); | |||
311 | g_debug ("importance = %d", self->importance); | |||
312 | ||||
313 | //status | |||
314 | if (!strv[idx]) { | |||
315 | g_warning ("Insufficient data in eas_email_info_serialise"); | |||
316 | goto out; | |||
317 | } | |||
318 | self->status = strv[idx++]; | |||
319 | g_debug ("status = %s", self->status); | |||
320 | ||||
321 | ret = TRUE1; | |||
322 | out: | |||
323 | while (strv[idx]) | |||
| ||||
324 | g_free (strv[idx++]); | |||
325 | g_free (strv[idx]); | |||
326 | g_free (strv); | |||
327 | ||||
328 | if (!ret) { | |||
329 | g_warning ("failed!"); | |||
330 | } | |||
331 | ||||
332 | g_debug ("eas_email_info_deserialise--"); | |||
333 | return ret; | |||
334 | } | |||
335 |