From ea0e4fc2567edfc0d20141025837e2bd9c64c0cb Mon Sep 17 00:00:00 2001
From: opneErler BUildteam <buildteam@openeuler.org>
Date: Fri, 5 Jun 2020 15:46:37 +0800
Subject: [PATCH] fix memleaks in asn1 arrat2tree

---
 lib/ASN1.y       | 91 ++++++++++++++++++++++++--------------------------------
 lib/parser_aux.c |  2 +-
 lib/structure.c  | 20 +++++++++----
 3 files changed, 54 insertions(+), 59 deletions(-)

diff --git a/lib/ASN1.y b/lib/ASN1.y
index 5009173..b540457 100644
--- a/lib/ASN1.y
+++ b/lib/ASN1.y
@@ -661,13 +661,11 @@ int
 asn1_parser2tree (const char *file, asn1_node * definitions,
                   char *error_desc)
 {
-
-  p_tree = NULL;
-
   if (*definitions != NULL)
-    return ASN1_ELEMENT_NOT_EMPTY;
-
-  *definitions = NULL;
+   {
+     result_parse =  ASN1_ELEMENT_NOT_EMPTY;
+     goto error;
+   }
 
   file_name = file;
 
@@ -677,54 +675,43 @@ asn1_parser2tree (const char *file, asn1_node * definitions,
   if (file_asn1 == NULL)
     {
       result_parse = ASN1_FILE_NOT_FOUND;
+      goto error;
     }
-  else
-    {
-      result_parse = ASN1_SUCCESS;
-
-      line_number = 1;
-      yyparse ();
-
-      fclose (file_asn1);
-
-      if (result_parse == ASN1_SUCCESS)
-        {                       /* syntax OK */
-          /* set IMPLICIT or EXPLICIT property */
-          _asn1_set_default_tag (p_tree);
-          /* set CONST_SET and CONST_NOT_USED */
-          _asn1_type_set_config (p_tree);
-          /* check the identifier definitions */
-          result_parse = _asn1_check_identifier (p_tree);
-          if (result_parse == ASN1_SUCCESS)
-            {                   /* all identifier defined */
-              /* Delete the list and keep the ASN1 structure */
-              _asn1_delete_list (e_list);
-              e_list = NULL;
-              /* Convert into DER coding the value assign to INTEGER constants */
-              _asn1_change_integer_value (p_tree);
-              /* Expand the IDs of OBJECT IDENTIFIER constants */
-              result_parse = _asn1_expand_object_id (&e_list, p_tree);
-              if (result_parse != ASN1_SUCCESS)
-                goto error;
-
-              *definitions = p_tree;
-            }
-          else                  /* some identifiers not defined */
-            {
-              /* Delete the list and the ASN1 structure */
-              _asn1_delete_list_and_nodes (e_list);
-              e_list = NULL;
-            }
-        }
-      else                      /* syntax error */
-        {
-          /* Delete the list and the ASN1 structure */
-          _asn1_delete_list_and_nodes (e_list);
-          e_list = NULL;
-        }
-    }
+  result_parse = ASN1_SUCCESS;
+  line_number = 1;
+  yyparse ();
+
+  fclose (file_asn1);
+
+  if (result_parse != ASN1_SUCCESS)
+    goto error;
+
+  /* set IMPLICIT or EXPLICIT property */
+  _asn1_set_default_tag (p_tree);
+  /* set CONST_SET and CONST_NOT_USED */
+  _asn1_type_set_config (p_tree);
+  /* check the identifier definitions */
+  result_parse = _asn1_check_identifier (p_tree);
+  if (result_parse != ASN1_SUCCESS)
+    goto error;
+  /* Convert into DER coding the value assign to INTEGER constants */
+  _asn1_change_integer_value (p_tree);
+  /* Expand the IDs of OBJECT IDENTIFIER constants */
+  result_parse = _asn1_expand_object_id (&e_list, p_tree);
+  if (result_parse != ASN1_SUCCESS)
+    goto error; 
+/* success */
+  *definitions = p_tree;
+  _asn1_delete_list (e_list);
+  e_list = NULL;
+  p_tree = NULL;
+  *error_desc = 0;
+  return result_parse;
+error:
+  _asn1_delete_list_and_nodes (e_list);
+  e_list = NULL;
+  p_tree = NULL;
 
- error:
   _asn1_create_errorDescription (result_parse, error_desc);
 
   return result_parse;
diff --git a/lib/parser_aux.c b/lib/parser_aux.c
index 0fead92..5b3e55b 100644
--- a/lib/parser_aux.c
+++ b/lib/parser_aux.c
@@ -730,7 +730,7 @@ _asn1_expand_object_id (list_type **list, asn1_node node)
 			  || !(p3->type & CONST_ASSIGN))
 			return ASN1_ELEMENT_NOT_FOUND;
 		      _asn1_set_down (p, p2->right);
-		      if (p2->down)
+		      while (p2->down)
 			_asn1_delete_structure (*list, &p2->down, 0);
 		      _asn1_delete_node_from_list(*list, p2);
 		      _asn1_remove_node (p2, 0);
diff --git a/lib/structure.c b/lib/structure.c
index 7f52380..642816a 100644
--- a/lib/structure.c
+++ b/lib/structure.c
@@ -206,11 +206,11 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
 	*definitions = p;
 
       if (move == DOWN) {
-        if (p_last && p_last->down)
+        while (p_last && p_last->down)
 	  _asn1_delete_structure (e_list, &p_last->down, 0); 
 	_asn1_set_down (p_last, p);
       } else if (move == RIGHT) {
-        if (p_last && p_last->right)
+        while (p_last && p_last->right)
 	  _asn1_delete_structure (e_list, &p_last->right, 0);
 	_asn1_set_right (p_last, p);
       }
@@ -314,7 +314,7 @@ int
 _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags)
 {
   asn1_node p, p2, p3;
-
+  int flag_t = 1;
   if (*structure == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
 
@@ -344,7 +344,11 @@ _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int f
 		{
 		  p3 = _asn1_find_up (p);
 		  if (p3)
+		  {
 		    _asn1_set_down (p3, p2);
+		    p2 = NULL;
+		    flag_t = 0;
+		  }  
 		  else
 		    {
 		      if (p->right)
@@ -352,15 +356,19 @@ _asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int f
 		    }
 		}
 	      else
-		_asn1_set_right (p3, p2);
+		{
+		  _asn1_set_right (p3, p2);
+		  p2 = NULL;
+		  flag_t = 0;
+		}
 	      if (e_list)
 		_asn1_delete_node_from_list (e_list, p);
 	      _asn1_remove_node (p, flags);
-	      p = NULL;
+	      p = p2;
 	    }
 	}
     }
-
+if (flag_t)
   *structure = NULL;
   return ASN1_SUCCESS;
 }
-- 
1.8.3.1

