Explorar o código

presence_dialoginfo: fixed several libxml2 API usage leaks

- reported by dkovik, GH#155
Daniel-Constantin Mierla %!s(int64=10) %!d(string=hai) anos
pai
achega
6390b05068
Modificáronse 1 ficheiros con 44 adicións e 25 borrados
  1. 44 25
      modules/presence_dialoginfo/notify_body.c

+ 44 - 25
modules/presence_dialoginfo/notify_body.c

@@ -78,12 +78,25 @@ void free_xml_body(char* body)
 str* dlginfo_agg_nbody_empty(str* pres_user, str* pres_domain)
 {
 	str* n_body= NULL;
+	str* body_array;
+	char* body;
 
 	LM_DBG("creating empty dialog for [pres_user]=%.*s [pres_domain]= %.*s\n",
 			pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
 
-	str* body_array = (str*)pkg_malloc(sizeof(str));
-	char* body = (char*)pkg_malloc(DIALOGINFO_EMPTY_BODY_SIZE);
+	/* dcm: note to double check - pkg allocation might not be needed */
+	body_array = (str*)pkg_malloc(sizeof(str));
+	if(body_array==NULL) {
+		LM_ERR("No more pkg\n");
+		return NULL;
+	}
+	body = (char*)pkg_malloc(DIALOGINFO_EMPTY_BODY_SIZE);
+	if(body==NULL) {
+		LM_ERR("No more pkg\n");
+		pkg_free(body_array);
+		return NULL;
+	}
+
 	sprintf(body, DIALOGINFO_EMPTY_BODY);//, pres_user->len, pres_user->s, pres_domain->len, pres_domain->s);
 	body_array->s = body;
 	body_array->len = strlen(body);
@@ -91,12 +104,10 @@ str* dlginfo_agg_nbody_empty(str* pres_user, str* pres_domain)
 
 	n_body= agregate_xmls(pres_user, pres_domain, &body_array, 1);
 	LM_DBG("[n_body]=%p\n", n_body);
-	if(n_body) {
+	if(n_body!=NULL) {
 		LM_DBG("[*n_body]=%.*s\n",n_body->len, n_body->s);
-	}
-	if(n_body== NULL)
-	{
-		LM_ERR("while aggregating body\n");
+	} else {
+		LM_ERR("issues while aggregating body\n");
 	}
 
 	pkg_free(body);
@@ -201,9 +212,8 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 
 	if(j== 0)  /* no body */
 	{
-		if(xml_array)
-			pkg_free(xml_array);
-		return NULL;
+		LM_DBG("no body to be built\n");
+		goto error;
 	}
 
 	/* n: number of bodies in total */
@@ -214,7 +224,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 	/* create the new NOTIFY body  */
 	if ( (pres_user->len + pres_domain->len + 1 + 4 + 1) >= MAX_URI_SIZE) {
 		LM_ERR("entity URI too long, maximum=%d\n", MAX_URI_SIZE);
-		return NULL;
+		goto error;
 	}
 	memcpy(buf, "sip:", 4);
 	memcpy(buf+4, pres_user->s, pres_user->len);
@@ -223,8 +233,10 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 	buf[pres_user->len + 5 + pres_domain->len]= '\0';
 
 	doc = xmlNewDoc(BAD_CAST "1.0");
-	if(doc==0)
-		return NULL;
+	if(doc==0) {
+		LM_ERR("unable to create xml document\n");
+		goto error;
+	}
 
 	root_node = xmlNewNode(NULL, BAD_CAST "dialog-info");
 	if(root_node==0)
@@ -273,6 +285,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 					if (!force_single_dialog || (j==1)) {
 						xmlUnlinkNode(node);
 						if(xmlAddChild(root_node, node)== NULL) {
+							xmlFreeNode(node);
 							LM_ERR("while adding child\n");
 							goto error;
 						}
@@ -283,9 +296,14 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 						 */
 						if(strcasecmp((char*)node->name,"dialog") == 0)
 						{
-							node_id = i;
+							if(dialog_id) xmlFree(dialog_id);
 							dialog_id = xmlGetProp(node,(const xmlChar *)"id");
-							LM_DBG("Dialog id for this node : %s\n", dialog_id);
+							if(dialog_id) {
+								node_id = i;
+								LM_DBG("Dialog id for this node : %s\n", dialog_id);
+							} else {
+								LM_DBG("No dialog id for this node - index: %d\n", i);
+							}
 						}
 						state = xmlNodeGetNodeContentByName(node, "state", NULL);
 						if(state) {
@@ -371,6 +389,7 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 		}
 		xmlUnlinkNode(winner_dialog_node);
 		if(xmlAddChild(root_node, winner_dialog_node)== NULL) {
+			xmlFreeNode(winner_dialog_node);
 			LM_ERR("while adding winner-child\n");
 			goto error;
 		}
@@ -384,15 +403,13 @@ str* agregate_xmls(str* pres_user, str* pres_domain, str** body_array, int n)
 	xmlDocDumpFormatMemory(doc,(xmlChar**)(void*)&body->s, 
 			&body->len, 1);	
 
-	for(i=0; i<j; i++)
-	{
+	if(dialog_id!=NULL) xmlFree(dialog_id);
+	for(i=0; i<j; i++) {
 		if(xml_array[i]!=NULL)
 			xmlFreeDoc( xml_array[i]);
 	}
-	if (doc)
-		xmlFreeDoc(doc);
-	if(xml_array!=NULL)
-		pkg_free(xml_array);
+	if(doc) xmlFreeDoc(doc);
+	if(xml_array) pkg_free(xml_array);
 
 	xmlCleanupParser();
 	xmlMemoryDump();
@@ -409,8 +426,9 @@ error:
 		}
 		pkg_free(xml_array);
 	}
-	if(body)
-		pkg_free(body);
+	if(body) pkg_free(body);
+	if(dialog_id) xmlFree(dialog_id);
+	if(doc) xmlFreeDoc(doc);
 
 	return NULL;
 }
@@ -458,8 +476,9 @@ int check_relevant_state (xmlChar * dialog_id, xmlDocPtr * xml_array, int total_
 						{
 							/* Getting the node id so we would be sure
 							 * that terminate state from same one the same */
+							if(dialog_id_tmp) xmlFree(dialog_id_tmp);
 							dialog_id_tmp = xmlGetProp (node, (const xmlChar *) "id");
-							node_id = i;
+							if(dialog_id_tmp) node_id = i;
 						}
 						state = xmlNodeGetNodeContentByName (node, "state", NULL);
 						if (state)
@@ -503,13 +522,13 @@ int check_relevant_state (xmlChar * dialog_id, xmlDocPtr * xml_array, int total_
 								result += DEF_TRYING_NODE;
 							}
 
-
 							xmlFree (state);
 						}
 					}
 				}
 		}
 	}
+	if(dialog_id_tmp) xmlFree(dialog_id_tmp);
 	LM_DBG ("result cheching dialog %s is %d\n", dialog_id, result);
 	return result;
 }