Bug Summary

File:activesyncd/libeasclient/eas-email-info.c
Warning:line 323, column 9
Array access (from variable 'strv') results in a null pointer dereference

Annotated Source Code

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
34G_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
36const gchar *sep = "\n";
37
38static void
39eas_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
52static void
53eas_email_free_header (EasEmailHeader *header)
54{
55 g_free (header->name);
56 g_free (header->value);
57 g_free (header);
58}
59
60static void
61eas_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
83static void
84eas_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
91EasEmailInfo *
92eas_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
105gboolean
106eas_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
185gboolean
186eas_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
1
Value assigned to 'strv'
205 if (!strv)
2
Assuming 'strv' is null
3
Taking true branch
206 goto out;
4
Control jumps to line 323
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;
322out:
323 while (strv[idx])
5
Array access (from variable 'strv') results in a null pointer dereference
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