Bug Summary

File:activesyncd/eas-daemon/libeas/eas-ping-msg.c
Warning:line 216, column 6
Access to field 'type' results in a dereference of a null pointer (loaded from variable 'node')

Annotated Source Code

1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8; show-trailing-whitespace: t -*- */
2/*
3 * ActiveSync core protocol library
4 *
5 * Copyright © 2011 Intel Corporation.
6 *
7 * Authors: Mobica Ltd. <www.mobica.com>
8 *
9 * This file is provided under a dual Apache/LGPLv2.1 licence. When
10 * using or redistributing this file, you may do so under either
11 * licence.
12 *
13 *
14 * LGPLv2.1 LICENCE SUMMARY
15 *
16 * Copyright © Intel Corporation, dates as above.
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Lesser General Public
20 * License as published by the Free Software Foundation; either
21 * version 2.1 of the License, or (at your option) any later
22 * version.
23 *
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free
31 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
32 * Boston, MA 02110-1301 USA
33 *
34 *
35 * APACHE LICENCE SUMMARY
36 *
37 * Copyright © Intel Corporation, dates as above.
38 *
39 * Licensed under the Apache License, Version 2.0 (the "License");
40 * you may not use this file except in compliance with the License.
41 * You may obtain a copy of the License at
42 *
43 * http://www.apache.org/licenses/LICENSE-2.0
44 *
45 * Unless required by applicable law or agreed to in writing, software
46 * distributed under the License is distributed on an "AS IS" BASIS,
47 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48 * See the License for the specific language governing permissions and
49 * limitations under the License.
50 *
51 */
52
53#include "eas-connection-errors.h"
54#include "eas-ping-msg.h"
55#include "eas-email-info-translator.h"
56#include "eas-connection-errors.h"
57#include <eas-folder.h>
58
59struct _EasPingMsgPrivate {
60 GSList* updated_folders;
61 EasPingReqState state;
62};
63
64#define EAS_PING_MSG_PRIVATE(o)(((EasPingMsgPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((eas_ping_msg_get_type ())))))
(G_TYPE_INSTANCE_GET_PRIVATE ((o), EAS_TYPE_PING_MSG, EasPingMsgPrivate)((EasPingMsgPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((o)), ((eas_ping_msg_get_type ()))))
)
65
66
67G_DEFINE_TYPE (EasPingMsg, eas_ping_msg, EAS_TYPE_MSG_BASE)static void eas_ping_msg_init (EasPingMsg *self); static void
eas_ping_msg_class_init (EasPingMsgClass *klass); static gpointer
eas_ping_msg_parent_class = ((void*)0); static gint EasPingMsg_private_offset
; static void eas_ping_msg_class_intern_init (gpointer klass)
{ eas_ping_msg_parent_class = g_type_class_peek_parent (klass
); if (EasPingMsg_private_offset != 0) g_type_class_adjust_private_offset
(klass, &EasPingMsg_private_offset); eas_ping_msg_class_init
((EasPingMsgClass*) klass); } __attribute__((__unused__)) static
inline gpointer eas_ping_msg_get_instance_private (EasPingMsg
*self) { return (((gpointer) ((guint8*) (self) + (glong) (EasPingMsg_private_offset
)))); } GType eas_ping_msg_get_type (void) { static volatile gsize
g_define_type_id__volatile = 0; if ((__extension__ ({ typedef
char _GStaticAssertCompileTimeAssertion_7[(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_8
[(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 ((eas_msg_base_get_type
()), g_intern_static_string ("EasPingMsg"), sizeof (EasPingMsgClass
), (GClassInitFunc) eas_ping_msg_class_intern_init, sizeof (EasPingMsg
), (GInstanceInitFunc) eas_ping_msg_init, (GTypeFlags) 0); { {
{};} } (__extension__ ({ typedef char _GStaticAssertCompileTimeAssertion_9
[(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; }
;
68
69static void
70eas_ping_msg_init (EasPingMsg *object)
71{
72 EasPingMsgPrivate *priv;
73 g_debug ("eas_ping_msg_init++");
74
75 object->priv = priv = EAS_PING_MSG_PRIVATE (object)(((EasPingMsgPrivate*) g_type_instance_get_private ((GTypeInstance
*) ((object)), ((eas_ping_msg_get_type ())))))
;
76
77 g_debug ("eas_ping_msg_init--");
78}
79
80static void
81eas_ping_msg_finalize (GObject *object)
82{
83 G_OBJECT_CLASS (eas_ping_msg_parent_class)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((eas_ping_msg_parent_class
)), (((GType) ((20) << (2))))))))
->finalize (object);
84}
85
86static void
87eas_ping_msg_class_init (EasPingMsgClass *klass)
88{
89 GObjectClass* object_class = G_OBJECT_CLASS (klass)((((GObjectClass*) g_type_check_class_cast ((GTypeClass*) ((klass
)), (((GType) ((20) << (2))))))))
;
90
91 g_type_class_add_private (klass, sizeof (EasPingMsgPrivate));
92
93 object_class->finalize = eas_ping_msg_finalize;
94}
95
96EasPingMsg*
97eas_ping_msg_new ()
98{
99 EasPingMsg* msg = NULL((void*)0);
100 msg = g_object_new (EAS_TYPE_PING_MSG(eas_ping_msg_get_type ()), NULL((void*)0));
101 return msg;
102}
103
104xmlDoc*
105eas_ping_msg_build_message (EasPingMsg* self, const gchar* accountId, const gchar *heartbeat, GSList *folders)
106{
107 xmlDoc *doc = NULL((void*)0);
108 xmlNode *node = NULL((void*)0),
109 *child = NULL((void*)0),
110 *folder = NULL((void*)0);
111 GSList * iterator;
112 gchar *folder_id = NULL((void*)0);
113
114 doc = xmlNewDoc ( (xmlChar *) "1.0");
115 node = xmlNewDocNode (doc, NULL((void*)0), (xmlChar*) "Ping", NULL((void*)0));
116 xmlDocSetRootElement (doc, node);
117
118 xmlCreateIntSubset (doc,
119 (xmlChar*) "ActiveSync",
120 (xmlChar*) "-//MICROSOFT//DTD ActiveSync//EN",
121 (xmlChar*) "http://www.microsoft.com/");
122
123 xmlNewNs (node, (xmlChar *) "Ping:", NULL((void*)0));
124 child = xmlNewChild (node, NULL((void*)0), (xmlChar *) "HeartbeatInterval", (xmlChar*) heartbeat);
125 child = xmlNewChild (node, NULL((void*)0), (xmlChar *) "Folders", NULL((void*)0));
126 for (iterator = folders; iterator; iterator = iterator->next) {
127 folder_id = (gchar*) iterator->data;
128 folder = xmlNewChild (child, NULL((void*)0), (xmlChar *) "Folder", NULL((void*)0));
129 xmlNewChild (folder, NULL((void*)0), (xmlChar *) "Id", (xmlChar*) (folder_id));
130 //TODO:class needs to be set properly... need some sort of lookup from type probably
131 xmlNewChild (folder, NULL((void*)0), (xmlChar *) "Class", (xmlChar*) "Email");
132 }
133
134 return doc;
135}
136
137
138gboolean
139eas_ping_msg_parse_response (EasPingMsg* self, xmlDoc *doc, GError** error)
140{
141 gboolean ret = TRUE(!(0));
142 EasPingMsgPrivate *priv = self->priv;
143 xmlNode *node = NULL((void*)0),
144 *appData = NULL((void*)0);
145 EasError error_details;
146 gchar* folderid = NULL((void*)0);
147
148
149 g_return_val_if_fail (error == NULL || *error == NULL, FALSE)do{ if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((error == ((void*)0) || *error == ((void*)0))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) { } else
{ g_return_if_fail_warning ("libeas", ((const char*) (__func__
)), "error == NULL || *error == NULL"); return ((0)); }; }while
(0)
;
150
151 if (!doc) {
1
Assuming 'doc' is non-null
2
Taking false branch
152 g_set_error (error, EAS_CONNECTION_ERROR(eas_connection_error_quark ()),
153 EAS_CONNECTION_ERROR_XMLELEMENTNOTFOUND,
154 ("Ping Response is empty"));
155 ret = FALSE(0);
156 goto finish;
157 }
158 node = xmlDocGetRootElement ( (xmlDoc*) doc);
159 if (g_strcmp0 ( (char *) node->name, "Ping")) {
3
Assuming the condition is false
4
Taking false branch
160 g_set_error (error, EAS_CONNECTION_ERROR(eas_connection_error_quark ()),
161 EAS_CONNECTION_ERROR_XMLELEMENTNOTFOUND,
162 ("Failed to find <Ping> element"));
163 ret = FALSE(0);
164 goto finish;
165 }
166 for (node = node->children; node; node = node->next) {
5
Value assigned to 'node'
6
Assuming pointer value is null
7
Loop condition is false. Execution continues on line 215
167 if (node->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) node->name, "Status")) {
168 gchar *sync_status = (gchar *) xmlNodeGetContent (node);
169 guint status_num = atoi (sync_status);
170 xmlFree (sync_status);
171 switch (status_num) {
172 // Ping completed with no changes - re-issue command ( headers only)
173 case EAS_COMMON_STATUS_OK: {
174 g_debug ("Status 1 - resend heartbeat ");
175 priv->state = EasPingReqSendHeartbeat;
176 goto finish;
177 }
178 break;
179 // Ping completed with some folder changes - notify client to sync folders
180 case EAS_PING_STATUS_FOLDERS_UPDATED: {
181 g_debug ("Status 2 - notify client ");
182 priv->state = EasPingReqNotifyClient;
183 }
184 break;
185 default: {
186 ret = FALSE(0);
187 g_debug ("error status - return error");
188 if ( (EAS_PING_STATUS_FOLDERS_UPDATED < status_num) && (status_num <= EAS_PING_STATUS_FOLDER_HIERARCHY_ERROR)) { // it's a ping status code
189 error_details = ping_status_error_map[status_num];
190 } else {
191 if (status_num > EAS_PING_STATUS_EXCEEDSSTATUSLIMIT) // not pretty, but make sure we don't overrun array if new status added
192 status_num = EAS_PING_STATUS_EXCEEDSSTATUSLIMIT;
193
194 error_details = ping_status_error_map[status_num];
195 }
196 g_set_error (error, EAS_CONNECTION_ERROR(eas_connection_error_quark ()), error_details.code, "%s", error_details.message);
197 goto finish;
198 }
199 }
200 continue;
201 }
202 if (node->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) node->name, "Folders")) {
203 g_debug ("Got Folders ");
204 break;
205 }
206 if (node->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) node->name, "HeartbeatInterval")) {
207 g_debug ("Got <HeartbeatInterval/>");
208 break;
209 }
210 if (node->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) node->name, "MaxFolders")) {
211 g_debug ("Got <MaxFolders/>");
212 break;
213 }
214 }
215 g_debug ("about to parse folders");
216 if (node->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) node->name, "Folders")) {
8
Access to field 'type' results in a dereference of a null pointer (loaded from variable 'node')
217 g_debug ("parsing folders");
218 appData = node;
219 for (appData = appData->children; appData; appData = appData->next) {
220 if (appData->type == XML_ELEMENT_NODE && !g_strcmp0 ( (char *) appData->name, "Folder")) {
221 //TODO: fix memory cleanup for this...
222 folderid = (gchar *) xmlNodeGetContent (appData);
223 priv->updated_folders = g_slist_append (priv->updated_folders, folderid);
224 }
225 }
226 }
227 g_debug ("eas_ping_msg_parse_response--");
228
229finish:
230 if (!ret) {
231 g_assert (error == NULL || *error != NULL)do { if (__builtin_expect (__extension__ ({ int _g_boolean_var_
; if ((error == ((void*)0) || *error != ((void*)0))) _g_boolean_var_
= 1; else _g_boolean_var_ = 0; _g_boolean_var_; }), 1)) ; else
g_assertion_message_expr ("libeas", "/data/runtests/work/sources/activesyncd/eas-daemon/libeas/eas-ping-msg.c"
, 231, ((const char*) (__func__)), "error == NULL || *error != NULL"
); } while (0)
;
232 }
233 return ret;
234}
235
236EasPingReqState
237eas_ping_msg_get_state (EasPingMsg *self)
238{
239 EasPingMsgPrivate *priv = self->priv;
240 g_debug ("eas_ping_msg_get_state +-");
241 return priv->state;
242
243}
244
245GSList*
246eas_ping_msg_get_changed_folders (EasPingMsg* self)
247{
248 EasPingMsgPrivate *priv = self->priv;
249 return priv->updated_folders;
250}
251
252
253