From f16d1ff9a283276d105b50391d30f4b9039d5f80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de>
Date: Tue, 23 Jul 2019 12:04:56 +0200
Subject: [PATCH] Fix two memleaks in asn1_array2tree()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Tim Rühsen <tim.ruehsen@gmx.de>
---
 lib/parser_aux.c |  2 +-
 lib/parser_aux.h |  1 +
 lib/structure.c  | 22 +++++++++++++---------
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/lib/parser_aux.c b/lib/parser_aux.c
index 9df1152..fec4175 100644
--- a/lib/parser_aux.c
+++ b/lib/parser_aux.c
@@ -548,7 +548,7 @@ _asn1_find_up (asn1_node_const node)
 /* Function : _asn1_delete_node_from_list                         */
 /* Description: deletes the list element given                    */
 /******************************************************************/
-static void
+void
 _asn1_delete_node_from_list (list_type *list, asn1_node node)
 {
   list_type *p = list;
diff --git a/lib/parser_aux.h b/lib/parser_aux.h
index 019f55e..598e684 100644
--- a/lib/parser_aux.h
+++ b/lib/parser_aux.h
@@ -42,6 +42,7 @@ void _asn1_delete_list (list_type *e_list);
 
 void _asn1_delete_list_and_nodes (list_type *e_list);
 
+void _asn1_delete_node_from_list (list_type *list, asn1_node node);
 
 asn1_node
 _asn1_set_value (asn1_node node, const void *value, unsigned int len);
diff --git a/lib/structure.c b/lib/structure.c
index 590439c..1de5226 100644
--- a/lib/structure.c
+++ b/lib/structure.c
@@ -192,8 +192,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
 
   move = UP;
 
-  k = 0;
-  while (array[k].value || array[k].type || array[k].name)
+  for (k = 0; array[k].value || array[k].type || array[k].name; k++)
     {
       type = convert_old_type (array[k].type);
 
@@ -206,10 +205,19 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
       if (*definitions == NULL)
 	*definitions = p;
 
-      if (move == DOWN)
+      if (move == DOWN) {
+        if (p_last && p_last->down) {
+	  _asn1_delete_node_from_list (e_list, p_last->down);
+	  _asn1_remove_node (p_last->down, 0);
+	}
 	_asn1_set_down (p_last, p);
-      else if (move == RIGHT)
+      } else if (move == RIGHT) {
+        if (p_last && p_last->right) {
+	  _asn1_delete_node_from_list (e_list, p_last->right);
+	  _asn1_remove_node (p_last->down, 0);
+	}
 	_asn1_set_right (p_last, p);
+      }
 
       p_last = p;
 
@@ -219,11 +227,8 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
 	move = RIGHT;
       else
 	{
-	  while (1)
+	  while (p_last != *definitions)
 	    {
-	      if (p_last == *definitions)
-		break;
-
 	      p_last = _asn1_find_up (p_last);
 
 	      if (p_last == NULL)
@@ -237,7 +242,6 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
 		}
 	    }			/* while */
 	}
-      k++;
     }				/* while */
 
   if (p_last == *definitions)
-- 
1.8.3.1

