comparison libfdproto/messages.c @ 1298:0f215b0dda5e

Fix some possible memory leaks in fd_msg_new
author Sebastien Decugis <sdecugis@freediameter.net>
date Tue, 23 Jun 2015 12:12:10 +0800
parents c9a160b815ea
children 3f1e79e1273e
comparison
equal deleted inserted replaced
1297:2fbee0e39c04 1298:0f215b0dda5e
229 init_avp(new); 229 init_avp(new);
230 230
231 if (model) { 231 if (model) {
232 struct dict_avp_data dictdata; 232 struct dict_avp_data dictdata;
233 233
234 CHECK_FCT( fd_dict_getval(model, &dictdata) ); 234 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } );
235 235
236 new->avp_model = model; 236 new->avp_model = model;
237 new->avp_public.avp_code = dictdata.avp_code; 237 new->avp_public.avp_code = dictdata.avp_code;
238 new->avp_public.avp_flags = dictdata.avp_flag_val; 238 new->avp_public.avp_flags = dictdata.avp_flag_val;
239 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val ); 239 new->avp_public.avp_len = GETINITIALSIZE(dictdata.avp_basetype, dictdata.avp_flag_val );
245 } 245 }
246 246
247 if (flags & AVPFL_SET_RAWDATA_FROM_AVP) { 247 if (flags & AVPFL_SET_RAWDATA_FROM_AVP) {
248 new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags ); 248 new->avp_rawlen = (*avp)->avp_public.avp_len - GETAVPHDRSZ( (*avp)->avp_public.avp_flags );
249 if (new->avp_rawlen) { 249 if (new->avp_rawlen) {
250 CHECK_MALLOC( new->avp_rawdata = malloc(new->avp_rawlen) ); 250 CHECK_MALLOC_DO( new->avp_rawdata = malloc(new->avp_rawlen), { free(new); return __ret__; } );
251 memset(new->avp_rawdata, 0x00, new->avp_rawlen); 251 memset(new->avp_rawdata, 0x00, new->avp_rawlen);
252 } 252 }
253 } 253 }
254 254
255 /* The new object is ready, return */ 255 /* The new object is ready, return */
283 if (model) { 283 if (model) {
284 struct dictionary *dict; 284 struct dictionary *dict;
285 struct dict_cmd_data dictdata; 285 struct dict_cmd_data dictdata;
286 struct dict_object *dictappl; 286 struct dict_object *dictappl;
287 287
288 CHECK_FCT( fd_dict_getdict(model, &dict) ); 288 CHECK_FCT_DO( fd_dict_getdict(model, &dict), { free(new); return __ret__; } );
289 CHECK_FCT( fd_dict_getval(model, &dictdata) ); 289 CHECK_FCT_DO( fd_dict_getval(model, &dictdata), { free(new); return __ret__; } );
290 290
291 new->msg_model = model; 291 new->msg_model = model;
292 new->msg_public.msg_flags = dictdata.cmd_flag_val; 292 new->msg_public.msg_flags = dictdata.cmd_flag_val;
293 new->msg_public.msg_code = dictdata.cmd_code; 293 new->msg_public.msg_code = dictdata.cmd_code;
294 294
295 /* Initialize application from the parent, if any */ 295 /* Initialize application from the parent, if any */
296 CHECK_FCT( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0) ); 296 CHECK_FCT_DO( fd_dict_search( dict, DICT_APPLICATION, APPLICATION_OF_COMMAND, model, &dictappl, 0), { free(new); return __ret__; } );
297 if (dictappl != NULL) { 297 if (dictappl != NULL) {
298 struct dict_application_data appdata; 298 struct dict_application_data appdata;
299 CHECK_FCT( fd_dict_getval(dictappl, &appdata) ); 299 CHECK_FCT_DO( fd_dict_getval(dictappl, &appdata), { free(new); return __ret__; } );
300 new->msg_public.msg_appl = appdata.application_id; 300 new->msg_public.msg_appl = appdata.application_id;
301 } 301 }
302 } 302 }
303 303
304 if (flags & MSGFL_ALLOC_ETEID) { 304 if (flags & MSGFL_ALLOC_ETEID) {
362 size_t sidlen; 362 size_t sidlen;
363 struct avp * avp; 363 struct avp * avp;
364 union avp_value val; 364 union avp_value val;
365 365
366 if (!sess_id_avp) { 366 if (!sess_id_avp) {
367 CHECK_FCT( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT) ); 367 CHECK_FCT_DO( fd_dict_search( dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sess_id_avp, ENOENT), { free(ans); return __ret__; } );
368 } 368 }
369 CHECK_FCT( fd_sess_getsid ( sess, &sid, &sidlen ) ); 369 CHECK_FCT_DO( fd_sess_getsid ( sess, &sid, &sidlen ), { free(ans); return __ret__; } );
370 CHECK_FCT( fd_msg_avp_new ( sess_id_avp, 0, &avp ) ); 370 CHECK_FCT_DO( fd_msg_avp_new ( sess_id_avp, 0, &avp ), { free(ans); return __ret__; } );
371 val.os.data = sid; 371 val.os.data = sid;
372 val.os.len = sidlen; 372 val.os.len = sidlen;
373 CHECK_FCT( fd_msg_avp_setvalue( avp, &val ) ); 373 CHECK_FCT_DO( fd_msg_avp_setvalue( avp, &val ), { free(avp); free(ans); return __ret__; } );
374 CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ) ); 374 CHECK_FCT_DO( fd_msg_avp_add( ans, MSG_BRW_FIRST_CHILD, avp ), { free(avp); free(ans); return __ret__; } );
375 ans->msg_sess = sess; 375 ans->msg_sess = sess;
376 CHECK_FCT( fd_sess_ref_msg(sess) ); 376 CHECK_FCT_DO( fd_sess_ref_msg(sess), { free(ans); return __ret__; } );
377 } 377 }
378 378
379 /* Add all Proxy-Info AVPs from the query if any */ 379 /* Add all Proxy-Info AVPs from the query if any */
380 if (! (flags & MSGFL_ANSW_NOPROXYINFO)) { 380 if (! (flags & MSGFL_ANSW_NOPROXYINFO)) {
381 struct avp * avp; 381 struct avp * avp;
382 struct fd_pei pei; 382 struct fd_pei pei;
383 struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist); 383 struct fd_list avpcpylist = FD_LIST_INITIALIZER(avpcpylist);
384 384
385 CHECK_FCT( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) ); 385 CHECK_FCT_DO( fd_msg_browse(qry, MSG_BRW_FIRST_CHILD, &avp, NULL) , { free(ans); return __ret__; } );
386 while (avp) { 386 while (avp) {
387 if ( (avp->avp_public.avp_code == AC_PROXY_INFO) 387 if ( (avp->avp_public.avp_code == AC_PROXY_INFO)
388 && (avp->avp_public.avp_vendor == 0) ) { 388 && (avp->avp_public.avp_vendor == 0) ) {
389 /* We found a Proxy-Info, need to duplicate it in the answer */ 389 /* We found a Proxy-Info, need to duplicate it in the answer */
390 390
391 /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */ 391 /* In order to avoid dealing with all different possibilities of states, we just create a buffer then parse it */
392 unsigned char * buf = NULL; 392 unsigned char * buf = NULL;
393 size_t offset = 0; 393 size_t offset = 0;
394 394
395 /* Create a buffer with the content of the AVP. This is easier than going through the list */ 395 /* Create a buffer with the content of the AVP. This is easier than going through the list */
396 CHECK_FCT( fd_msg_update_length(avp) ); 396 CHECK_FCT_DO( fd_msg_update_length(avp), { free(ans); return __ret__; } );
397 CHECK_MALLOC( buf = malloc(avp->avp_public.avp_len) ); 397 CHECK_MALLOC_DO( buf = malloc(avp->avp_public.avp_len), { free(ans); return __ret__; } );
398 CHECK_FCT( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp) ); 398 CHECK_FCT_DO( bufferize_avp(buf, avp->avp_public.avp_len, &offset, avp), { free(buf); free(ans); return __ret__; } );
399 399
400 /* Now we parse this buffer to create a copy AVP */ 400 /* Now we parse this buffer to create a copy AVP */
401 CHECK_FCT( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist) ); 401 CHECK_FCT_DO( parsebuf_list(buf, avp->avp_public.avp_len, &avpcpylist), { free(buf); free(ans); return __ret__; } );
402 402
403 /* Parse dictionary objects now to remove the dependency on the buffer */ 403 /* Parse dictionary objects now to remove the dependency on the buffer */
404 CHECK_FCT( parsedict_do_chain(dict, &avpcpylist, 0, &pei) ); 404 CHECK_FCT_DO( parsedict_do_chain(dict, &avpcpylist, 0, &pei), { /* leaking the avpcpylist -- this should never happen anyway */ free(buf); free(ans); return __ret__; } );
405 405
406 /* Done for this AVP */ 406 /* Done for this AVP */
407 free(buf); 407 free(buf);
408 408
409 /* We move this AVP now so that we do not parse again in next loop */ 409 /* We move this AVP now so that we do not parse again in next loop */
410 fd_list_move_end(&ans->msg_chain.children, &avpcpylist); 410 fd_list_move_end(&ans->msg_chain.children, &avpcpylist);
411 } 411 }
412 /* move to next AVP in the message, we can have several Proxy-Info instances */ 412 /* move to next AVP in the message, we can have several Proxy-Info instances */
413 CHECK_FCT( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL) ); 413 CHECK_FCT_DO( fd_msg_browse(avp, MSG_BRW_NEXT, &avp, NULL), { free(ans); return __ret__; } );
414 } 414 }
415 } 415 }
416 416
417 /* associate with query */ 417 /* associate with query */
418 ans->msg_query = qry; 418 ans->msg_query = qry;
"Welcome to our mercurial repository"