Merge pull request #153 from brchiu/vlm_master_fix_most_memory_leakage

Fix some memory leakage found till now
diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c
index ad44dcb..4b466b5 100644
--- a/asn1c/asn1c.c
+++ b/asn1c/asn1c.c
@@ -65,6 +65,7 @@
     int ret;                        /* Return value from misc functions */
     int ch;                         /* Command line character */
     int i;                          /* Index in some loops */
+    int exit_code = 0;              /* Exit code */
 
     /*
      * Process command-line options.
@@ -262,7 +263,8 @@
         new_asn = asn1p_parse_file(av[i], asn1_parser_flags);
         if(new_asn == NULL) {
             fprintf(stderr, "Cannot parse \"%s\"\n", av[i]);
-            exit(EX_DATAERR);
+            exit_code = EX_DATAERR;
+            goto cleanup;
         }
 
         /*
@@ -286,7 +288,10 @@
      * Dump the parsed ASN.1 tree if -E specified and -F is NOT given.
      */
     if(print_arg__print_out && !print_arg__fix_n_print) {
-        if(asn1print(asn, asn1_printer_flags)) exit(EX_SOFTWARE);
+        if(asn1print(asn, asn1_printer_flags)) {
+            exit_code = EX_SOFTWARE;
+            goto cleanup;
+        }
         return 0;
     }
 
@@ -294,7 +299,10 @@
      * Read in the files from skeletons/standard-modules
      */
     if(importStandardModules(asn, skeletons_dir)) {
-        if(warnings_as_errors) exit(EX_DATAERR);
+        if(warnings_as_errors) {
+            exit_code = EX_DATAERR;
+            goto cleanup;
+        }
     }
 
     /*
@@ -310,14 +318,18 @@
         case 0:
         break; /* All clear */
     case -1:
-        exit(EX_DATAERR); /* Fatal failure */
+        exit_code = EX_DATAERR; /* Fatal failure */
+        goto cleanup;
     }
 
     /*
      * Dump the parsed ASN.1 tree if -E specified and -F is given.
      */
     if(print_arg__print_out && print_arg__fix_n_print) {
-        if(asn1print(asn, asn1_printer_flags)) exit(EX_SOFTWARE);
+        if(asn1print(asn, asn1_printer_flags)) {
+            exit_code = EX_SOFTWARE;
+            goto cleanup;
+        }
         return 0;
     }
 
@@ -327,10 +339,13 @@
      */
     if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, ac + optind,
                     optind, av - optind)) {
-        exit(EX_SOFTWARE);
+        exit_code = EX_SOFTWARE;
     }
 
+cleanup:
     asn1p_delete(asn);
+    asn1p_lex_destroy();
+    if (exit_code) exit(exit_code);
 
     return 0;
 }
@@ -415,6 +430,7 @@
             TQ_ADD(&(asn->modules), mod, mod_next);
         }
         asn1p_delete(new_asn);
+        asn1p_lex_destroy();
 
 #ifdef _WIN32
     } while(_findnext(dir, &c_file) == 0);
diff --git a/libasn1compiler/asn1c_constraint.c b/libasn1compiler/asn1c_constraint.c
index e67590a..0b502b6 100644
--- a/libasn1compiler/asn1c_constraint.c
+++ b/libasn1compiler/asn1c_constraint.c
@@ -267,6 +267,7 @@
 		 */
 		assert(range->el_count == 0);
 		/* The full range is specified. Ignore it. */
+		asn1constraint_range_free(range);
 		return 0;
 	}
 
diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c
index e486a33..04063ce 100644
--- a/libasn1fix/asn1fix_constr.c
+++ b/libasn1fix/asn1fix_constr.c
@@ -60,7 +60,7 @@
 		coft = asn1p_expr_clone(terminal, 1 /* Skip extensions */);
 		if(!coft) return -1;	/* ENOMEM */
 
-		if(0) {
+		if(1) {
 			asn1p_expr_free(memb);	/* Don't need it anymore*/
 		} else {
 			/* Actual removal clashes with constraints... skip. */
diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c
index aefb15c..312a65b 100644
--- a/libasn1fix/asn1fix_cws.c
+++ b/libasn1fix/asn1fix_cws.c
@@ -206,12 +206,14 @@
 		ref = asn1p_ref_new(arg->expr->_lineno);
 		asn1p_ref_add_component(ref, p, RLT_UNKNOWN);
 		assert(ref);
-	
+
 		expr = asn1f_lookup_symbol(arg, arg->mod, arg->expr->rhs_pspecs, ref);
 		if(!expr) {
 			FATAL("Cannot find %s referenced by %s at line %d",
 				p, arg->expr->Identifier,
 				arg->expr->_lineno);
+			asn1p_ref_free(ref);
+			free(p);
 			return -1;
 		}
 	}
diff --git a/libasn1fix/asn1fix_misc.c b/libasn1fix/asn1fix_misc.c
index 23005b9..88e8d18 100644
--- a/libasn1fix/asn1fix_misc.c
+++ b/libasn1fix/asn1fix_misc.c
@@ -26,7 +26,7 @@
         size_t tmp_len = (len);                     \
         if(tmp_len >= managedptr_len) {             \
             free(managedptr);                       \
-            managedptr = malloc(tmp_len + 1);       \
+            managedptr = calloc(1, tmp_len + 1);    \
             if(managedptr) {                        \
                 managedptr_len = tmp_len;           \
             } else {                                \
diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c
index 4340066..6065a7a 100644
--- a/libasn1parser/asn1p_expr.c
+++ b/libasn1parser/asn1p_expr.c
@@ -222,8 +222,8 @@
 asn1p_expr_add_many(asn1p_expr_t *to, asn1p_expr_t *from_what) {
 	asn1p_expr_t *expr;
 	TQ_FOR(expr, &(from_what->members), next) {
-        expr->parent_expr = to;
-    }
+		expr->parent_expr = to;
+	}
 	TQ_CONCAT(&(to->members), &(from_what->members), next);
 }
 
@@ -257,9 +257,25 @@
 		asn1p_constraint_free(expr->constraints);
 		asn1p_constraint_free(expr->combined_constraints);
 		asn1p_paramlist_free(expr->lhs_params);
+		asn1p_expr_free(expr->rhs_pspecs);
 		asn1p_value_free(expr->value);
 		asn1p_value_free(expr->marker.default_value);
 		asn1p_wsyntx_free(expr->with_syntax);
+		if(expr->specializations.pspec) {
+			int pspec;
+			for(pspec = 0; pspec < expr->specializations.pspecs_count; pspec++) {
+				asn1p_expr_free(expr->specializations.pspec[pspec].rhs_pspecs);
+				asn1p_expr_free(expr->specializations.pspec[pspec].my_clone);
+			}
+			free(expr->specializations.pspec);
+		}
+		if(expr->object_class_matrix.row) {
+			int row;
+			for(row = 0; row < expr->object_class_matrix.rows; row++) {
+				asn1p_ioc_row_delete(expr->object_class_matrix.row[row]);
+			}
+			free(expr->object_class_matrix.row);
+		}
 
 		if(expr->data && expr->data_free)
 			expr->data_free(expr->data);
diff --git a/libasn1parser/asn1p_l.l b/libasn1parser/asn1p_l.l
index 6deeca7..f221327 100644
--- a/libasn1parser/asn1p_l.l
+++ b/libasn1parser/asn1p_l.l
@@ -209,7 +209,7 @@
 
 '[0-9A-F \t\r\v\f\n]+'H {
 		/* " \t\r\n" weren't allowed in ASN.1:1990. */
-		asn1p_lval.tv_str = yytext;
+		asn1p_lval.tv_str = strdup(yytext);
 		return TOK_hstring;
 	}
 
diff --git a/libasn1parser/asn1p_module.c b/libasn1parser/asn1p_module.c
index 95ac50d..10aa94c 100644
--- a/libasn1parser/asn1p_module.c
+++ b/libasn1parser/asn1p_module.c
@@ -26,12 +26,19 @@
 asn1p_module_free(asn1p_module_t *mod) {
 	if(mod) {
 		asn1p_expr_t *expr;
+		asn1p_xports_t *xports;
 
 		free(mod->ModuleName);
 		free(mod->source_file_name);
 
 		asn1p_oid_free(mod->module_oid);
 
+		while((xports = TQ_REMOVE(&(mod->exports), xp_next)))
+			asn1p_xports_free(xports);
+
+		while((xports = TQ_REMOVE(&(mod->imports), xp_next)))
+			asn1p_xports_free(xports);
+
 		while((expr = TQ_REMOVE(&(mod->members), next)))
 			asn1p_expr_free(expr);
 
diff --git a/libasn1parser/asn1p_xports.c b/libasn1parser/asn1p_xports.c
index 35104df..8f46ac1 100644
--- a/libasn1parser/asn1p_xports.c
+++ b/libasn1parser/asn1p_xports.c
@@ -25,8 +25,14 @@
 void
 asn1p_xports_free(asn1p_xports_t *xp) {
 	if(xp) {
+		asn1p_expr_t *expr;
+
 		free(xp->fromModuleName);
 		asn1p_oid_free(xp->identifier.oid);
+
+		while((expr = TQ_REMOVE(&(xp->members), next)))
+			asn1p_expr_free(expr);
+
 		free(xp);
 	}
 }
diff --git a/libasn1parser/asn1p_y.c b/libasn1parser/asn1p_y.c
index 9d355b7..11acfae 100644
--- a/libasn1parser/asn1p_y.c
+++ b/libasn1parser/asn1p_y.c
@@ -2449,6 +2449,10 @@
 		AL_IMPORT((yyval.a_module), exports, (yyvsp[(1) - (3)].a_module), xp_next);
 		AL_IMPORT((yyval.a_module), imports, (yyvsp[(2) - (3)].a_module), xp_next);
 		AL_IMPORT((yyval.a_module), members, (yyvsp[(3) - (3)].a_module), next);
+
+		asn1p_module_free((yyvsp[(1) - (3)].a_module));
+		asn1p_module_free((yyvsp[(2) - (3)].a_module));
+		asn1p_module_free((yyvsp[(3) - (3)].a_module));
 	}
     break;
 
@@ -2469,6 +2473,8 @@
 			break;
 		}
 		AL_IMPORT((yyval.a_module), members, (yyvsp[(2) - (2)].a_module), next);
+
+		asn1p_module_free((yyvsp[(2) - (2)].a_module));
 	}
     break;
 
@@ -2925,7 +2931,7 @@
     {
 		(yyval.a_expr) = NEW_EXPR();
 		checkmem((yyval.a_expr));
-		(yyval.a_expr)->Identifier = "?";
+		(yyval.a_expr)->Identifier = strdup("?");
 		(yyval.a_expr)->expr_type = A1TC_REFERENCE;
 		(yyval.a_expr)->meta_type = AMT_VALUE;
 		(yyval.a_expr)->value = (yyvsp[(1) - (1)].a_value);
@@ -2989,6 +2995,7 @@
     {
         (yyval.a_expr) = (yyvsp[(1) - (5)].a_expr);
 		asn1p_expr_add_many((yyval.a_expr), (yyvsp[(4) - (5)].a_expr));
+		asn1p_expr_free((yyvsp[(4) - (5)].a_expr));
 	}
     break;
 
@@ -3324,6 +3331,8 @@
 		} else {
 			if((yyval.a_expr)->constraints) {
 				assert(!(yyvsp[(2) - (3)].a_expr));
+				/* Check this : optConstraints is not used ?! */
+				asn1p_constraint_free((yyvsp[(3) - (3)].a_constr));
 			} else {
 				(yyval.a_expr)->constraints = (yyvsp[(3) - (3)].a_constr);
 			}
@@ -4412,6 +4421,7 @@
 		(yyval.a_constr) = asn1p_constraint_new(yylineno);
 		(yyval.a_constr)->type = ACT_CT_CTNG;
 		(yyval.a_constr)->value = asn1p_value_fromtype((yyvsp[(2) - (2)].a_expr));
+		asn1p_expr_free((yyvsp[(2) - (2)].a_expr));
 	}
     break;
 
diff --git a/libasn1parser/asn1p_y.y b/libasn1parser/asn1p_y.y
index 910989a..b8406b6 100644
--- a/libasn1parser/asn1p_y.y
+++ b/libasn1parser/asn1p_y.y
@@ -529,6 +529,10 @@
 		AL_IMPORT($$, exports, $1, xp_next);
 		AL_IMPORT($$, imports, $2, xp_next);
 		AL_IMPORT($$, members, $3, next);
+
+		asn1p_module_free($1);
+		asn1p_module_free($2);
+		asn1p_module_free($3);
 	}
 	;
 
@@ -544,6 +548,7 @@
 			break;
 		}
 		AL_IMPORT($$, members, $2, next);
+		asn1p_module_free($2);
 	}
 	;
 
@@ -874,6 +879,7 @@
 		ret = asn1p_ref_add_component($$.governor, $1, 0);
 		checkmem(ret == 0);
 		$$.argument = $3;
+		free($1);
 	}
 	| TypeRefName ':' TypeRefName {
 		int ret;
@@ -881,6 +887,7 @@
 		ret = asn1p_ref_add_component($$.governor, $1, 0);
 		checkmem(ret == 0);
 		$$.argument = $3;
+		free($1);
 	}
 	| BasicTypeId ':' Identifier {
 		int ret;
@@ -919,7 +926,7 @@
 	| SimpleValue {
 		$$ = NEW_EXPR();
 		checkmem($$);
-		$$->Identifier = "?";
+		$$->Identifier = strdup("?");
 		$$->expr_type = A1TC_REFERENCE;
 		$$->meta_type = AMT_VALUE;
 		$$->value = $1;
@@ -972,8 +979,9 @@
 		asn1p_expr_add($$, $3);
 	}
 	| ComponentTypeLists ',' TOK_VBracketLeft ComponentTypeLists TOK_VBracketRight {
-        $$ = $1;
+		$$ = $1;
 		asn1p_expr_add_many($$, $4);
+		asn1p_expr_free($4);
 	}
 	;
 
@@ -1225,6 +1233,8 @@
 		} else {
 			if($$->constraints) {
 				assert(!$2);
+				/* Check this : optConstraints is not used ?! */
+				asn1p_constraint_free($3);
 			} else {
 				$$->constraints = $3;
 			}
@@ -1316,6 +1326,7 @@
 		checkmem(ret == 0);
 		$$->expr_type = ASN_TYPE_ANY;
 		$$->meta_type = AMT_TYPE;
+		free($4);
 	}
 	| TOK_INSTANCE TOK_OF ComplexTypeReference {
 		$$ = NEW_EXPR();
@@ -1349,6 +1360,7 @@
 		ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
 		checkmem(ret == 0);
 		free($1);
+		free($3);
 	}
 	| ObjectClassReference '.' TypeRefName {
 		int ret;
@@ -1359,6 +1371,7 @@
 		ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
 		checkmem(ret == 0);
 		free($1);
+		free($3);
 	}
 	| TOK_typereference '.' Identifier {
 		int ret;
@@ -1369,6 +1382,7 @@
 		ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
 		checkmem(ret == 0);
 		free($1);
+		free($3);
 	}
 	| ObjectClassReference {
 		int ret;
@@ -1438,14 +1452,17 @@
 	TOK_typefieldreference {
 		$$ = asn1p_ref_new(yylineno);
 		asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
+		free($1);
 	}
 	| FieldName '.' TOK_typefieldreference {
 		$$ = $$;
 		asn1p_ref_add_component($$, $3, RLT_AmpUppercase);
+		free($3);
 	}
 	| FieldName '.' TOK_valuefieldreference {
 		$$ = $$;
 		asn1p_ref_add_component($$, $3, RLT_Amplowercase);
+		free($3);
 	}
 	;
 
@@ -1453,12 +1470,15 @@
 	TOK_capitalreference {
 		$$ = asn1p_ref_new(yylineno);
 		asn1p_ref_add_component($$, $1, RLT_CAPITALS);
+		free($1);
 	}
 /*
 	| TypeRefName '.' TOK_capitalreference {
 		$$ = asn1p_ref_new(yylineno);
 		asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
 		asn1p_ref_add_component($$, $3, RLT_CAPITALS);
+		free($1);
+		free($3);
 	}
 */
 	;
@@ -1515,10 +1535,12 @@
 	| TOK_bstring {
 		$$ = _convert_bitstring2binary($1, 'B');
 		checkmem($$);
+		free($1);
 	}
 	| TOK_hstring {
 		$$ = _convert_bitstring2binary($1, 'H');
 		checkmem($$);
+		free($1);
 	}
 	| RestrictedCharacterStringValue {
 		$$ = $$;
@@ -1849,6 +1871,7 @@
 		ref = asn1p_ref_new(yylineno);
 		asn1p_ref_add_component(ref, $2, RLT_lowercase);
 		$$->value = asn1p_value_fromref(ref, 0);
+		free($2);
 	}
 	;
 
@@ -1892,10 +1915,12 @@
 	TOK_bstring {
 		$$ = _convert_bitstring2binary($1, 'B');
 		checkmem($$);
+		free($1);
 	}
 	| TOK_hstring {
 		$$ = _convert_bitstring2binary($1, 'H');
 		checkmem($$);
+		free($1);
 	}
 	;
 
@@ -1993,6 +2018,7 @@
 		$$ = asn1p_constraint_new(yylineno);
 		$$->type = ACT_CT_CTNG;
 		$$->value = asn1p_value_fromtype($2);
+		asn1p_expr_free($2);
 	}
 	;
 
@@ -2026,6 +2052,7 @@
 		ct->type = ACT_EL_VALUE;
 		ct->value = asn1p_value_fromref(ref, 0);
 		CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
+		free($2);
 	}
 	;
 
@@ -2094,6 +2121,8 @@
 		$$[l1] = '.';
 		memcpy($$ + l1 + 1, $3, l3);
 		$$[l1 + 1 + l3] = '\0';
+		free($1);
+		free($3);
 	}
 	;
 
diff --git a/libasn1parser/asn1parser.c b/libasn1parser/asn1parser.c
index 2ade9e9..42982c6 100644
--- a/libasn1parser/asn1parser.c
+++ b/libasn1parser/asn1parser.c
@@ -53,8 +53,10 @@
 
 	if(ret == 0) {
 		assert(a);
-		if(_asn1p_fix_modules(a, "-"))
+		if(_asn1p_fix_modules(a, "-")) {
+			asn1p_delete(a);
 			return NULL;	/* FIXME: destroy (a) */
+		}
 	} else if(a) {
 		asn1p_delete(a);
 		a = NULL;
@@ -110,8 +112,10 @@
 
 	if(ret == 0) {
 		assert(a);
-		if(_asn1p_fix_modules(a, filename))
+		if(_asn1p_fix_modules(a, filename)) {
+			asn1p_delete(a);
 			return NULL;	/* FIXME: destroy (a) */
+		}
 	} else if(a) {
 		asn1p_delete(a);
 		a = NULL;
diff --git a/libasn1parser/asn1parser.h b/libasn1parser/asn1parser.h
index e83b747..4926c77 100644
--- a/libasn1parser/asn1parser.h
+++ b/libasn1parser/asn1parser.h
@@ -70,5 +70,6 @@
 	enum asn1p_flags);
 
 int asn1p_atoi(const char *ptr, asn1c_integer_t *r_value);
+int asn1p_lex_destroy();
 
 #endif	/* ASN1PARSER_H */