From 3dcf05bbb066f6c553beed1aee51e896532599e4 Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Thu, 4 May 2017 21:45:05 +0800 Subject: [PATCH] Fix some memory leakage found --- asn1c/asn1c.c | 28 +++++++++++++++++++------ libasn1compiler/asn1c_constraint.c | 1 + libasn1fix/asn1fix_constr.c | 2 +- libasn1fix/asn1fix_cws.c | 4 +++- libasn1fix/asn1fix_misc.c | 2 +- libasn1parser/asn1p_expr.c | 20 ++++++++++++++++-- libasn1parser/asn1p_l.l | 2 +- libasn1parser/asn1p_module.c | 7 +++++++ libasn1parser/asn1p_xports.c | 6 ++++++ libasn1parser/asn1p_y.c | 12 ++++++++++- libasn1parser/asn1p_y.y | 33 ++++++++++++++++++++++++++++-- libasn1parser/asn1parser.c | 8 ++++++-- libasn1parser/asn1parser.h | 1 + 13 files changed, 109 insertions(+), 17 deletions(-) diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c index ad44dcb5..4b466b5f 100644 --- a/asn1c/asn1c.c +++ b/asn1c/asn1c.c @@ -65,6 +65,7 @@ main(int ac, char **av) { 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 @@ main(int ac, char **av) { 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 @@ main(int ac, char **av) { * 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 @@ main(int ac, char **av) { * 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 @@ main(int ac, char **av) { 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 @@ main(int ac, char **av) { */ 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 @@ importStandardModules(asn1p_t *asn, const char *skeletons_dir) { 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 e67590a4..0b502b62 100644 --- a/libasn1compiler/asn1c_constraint.c +++ b/libasn1compiler/asn1c_constraint.c @@ -267,6 +267,7 @@ asn1c_emit_constraint_tables(arg_t *arg, int got_size) { */ 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 e486a332..04063ce8 100644 --- a/libasn1fix/asn1fix_constr.c +++ b/libasn1fix/asn1fix_constr.c @@ -60,7 +60,7 @@ asn1f_pull_components_of(arg_t *arg) { 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 aefb15cc..312a65b0 100644 --- a/libasn1fix/asn1fix_cws.c +++ b/libasn1fix/asn1fix_cws.c @@ -206,12 +206,14 @@ _asn1f_assign_cell_value(arg_t *arg, struct asn1p_ioc_row_s *row, struct asn1p_i 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 23005b95..88e8d18a 100644 --- a/libasn1fix/asn1fix_misc.c +++ b/libasn1fix/asn1fix_misc.c @@ -26,7 +26,7 @@ asn1f_printable_value(asn1p_value_t *v) { 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 43400662..6065a7ac 100644 --- a/libasn1parser/asn1p_expr.c +++ b/libasn1parser/asn1p_expr.c @@ -222,8 +222,8 @@ void 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_expr_free(asn1p_expr_t *expr) { 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 6deeca76..f2213270 100644 --- a/libasn1parser/asn1p_l.l +++ b/libasn1parser/asn1p_l.l @@ -209,7 +209,7 @@ WSP [\t\r\v\f\n ] '[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 95ac50de..10aa94c1 100644 --- a/libasn1parser/asn1p_module.c +++ b/libasn1parser/asn1p_module.c @@ -26,12 +26,19 @@ void 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 35104df2..8f46ac12 100644 --- a/libasn1parser/asn1p_xports.c +++ b/libasn1parser/asn1p_xports.c @@ -25,8 +25,14 @@ asn1p_xports_new() { 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 9d355b76..11acfae5 100644 --- a/libasn1parser/asn1p_y.c +++ b/libasn1parser/asn1p_y.c @@ -2449,6 +2449,10 @@ yyreduce: 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 @@ yyreduce: 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 @@ yyreduce: { (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 @@ yyreduce: { (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 @@ yyreduce: } 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 @@ yyreduce: (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 910989a7..b8406b63 100644 --- a/libasn1parser/asn1p_y.y +++ b/libasn1parser/asn1p_y.y @@ -529,6 +529,10 @@ ModuleBody: 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 @@ AssignmentList: break; } AL_IMPORT($$, members, $2, next); + asn1p_module_free($2); } ; @@ -874,6 +879,7 @@ ParameterArgumentName: ret = asn1p_ref_add_component($$.governor, $1, 0); checkmem(ret == 0); $$.argument = $3; + free($1); } | TypeRefName ':' TypeRefName { int ret; @@ -881,6 +887,7 @@ ParameterArgumentName: ret = asn1p_ref_add_component($$.governor, $1, 0); checkmem(ret == 0); $$.argument = $3; + free($1); } | BasicTypeId ':' Identifier { int ret; @@ -919,7 +926,7 @@ ActualParameter: | SimpleValue { $$ = NEW_EXPR(); checkmem($$); - $$->Identifier = "?"; + $$->Identifier = strdup("?"); $$->expr_type = A1TC_REFERENCE; $$->meta_type = AMT_VALUE; $$->value = $1; @@ -972,8 +979,9 @@ ComponentTypeLists: 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 @@ Type: } else { if($$->constraints) { assert(!$2); + /* Check this : optConstraints is not used ?! */ + asn1p_constraint_free($3); } else { $$->constraints = $3; } @@ -1316,6 +1326,7 @@ TypeDeclarationSet: 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 @@ ComplexTypeReference: ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN); checkmem(ret == 0); free($1); + free($3); } | ObjectClassReference '.' TypeRefName { int ret; @@ -1359,6 +1371,7 @@ ComplexTypeReference: ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN); checkmem(ret == 0); free($1); + free($3); } | TOK_typereference '.' Identifier { int ret; @@ -1369,6 +1382,7 @@ ComplexTypeReference: ret = asn1p_ref_add_component($$, $3, RLT_lowercase); checkmem(ret == 0); free($1); + free($3); } | ObjectClassReference { int ret; @@ -1438,14 +1452,17 @@ FieldName: 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 @@ DefinedObjectClass: 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 @@ SimpleValue: | TOK_bstring { $$ = _convert_bitstring2binary($1, 'B'); checkmem($$); + free($1); } | TOK_hstring { $$ = _convert_bitstring2binary($1, 'H'); checkmem($$); + free($1); } | RestrictedCharacterStringValue { $$ = $$; @@ -1849,6 +1871,7 @@ PatternConstraint: 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 @@ BitStringValue: TOK_bstring { $$ = _convert_bitstring2binary($1, 'B'); checkmem($$); + free($1); } | TOK_hstring { $$ = _convert_bitstring2binary($1, 'H'); checkmem($$); + free($1); } ; @@ -1993,6 +2018,7 @@ ContentsConstraint: $$ = asn1p_constraint_new(yylineno); $$->type = ACT_CT_CTNG; $$->value = asn1p_value_fromtype($2); + asn1p_expr_free($2); } ; @@ -2026,6 +2052,7 @@ SimpleTableConstraint: 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 @@ ComponentIdList: $$[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 2ade9e97..42982c6d 100644 --- a/libasn1parser/asn1parser.c +++ b/libasn1parser/asn1parser.c @@ -53,8 +53,10 @@ asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags fla 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 @@ asn1p_parse_file(const char *filename, enum asn1p_flags flags) { 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 e83b747f..4926c773 100644 --- a/libasn1parser/asn1parser.h +++ b/libasn1parser/asn1parser.h @@ -70,5 +70,6 @@ asn1p_t *asn1p_parse_buffer(const char *buffer, int size /* = -1 */, enum asn1p_flags); int asn1p_atoi(const char *ptr, asn1c_integer_t *r_value); +int asn1p_lex_destroy(); #endif /* ASN1PARSER_H */