diff --git a/librz/analysis/fcn.c b/librz/analysis/fcn.c index 372ba4202c..bf5f288ffe 100644 --- a/librz/analysis/fcn.c +++ b/librz/analysis/fcn.c @@ -2495,6 +2495,7 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis, if (!shortname) { shortname = strdup(f->name); } + // At this point the `callable` pointer is *borrowed* RzCallable *callable = rz_type_func_get(analysis->typedb, shortname); free(shortname); if (callable) { @@ -2505,6 +2506,8 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis, } // If there is no match - create a new one. // TODO: Figure out if we should use shortname or a fullname here + // At this point the `callable` pointer is *owned* + // This means we have to free it after callable = rz_type_func_new(analysis->typedb, f->name, NULL); if (!callable) { return NULL; @@ -2528,11 +2531,13 @@ RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis, RzType *cloned_type = rz_type_clone(var->type); if (!cloned_type) { rz_pvector_free(args); + rz_type_callable_free(callable); return NULL; } RzCallableArg *arg = rz_type_callable_arg_new(analysis->typedb, var->name, cloned_type); if (!arg) { rz_pvector_free(args); + rz_type_callable_free(callable); return NULL; } rz_type_callable_arg_add(callable, arg); diff --git a/librz/analysis/serialize_analysis.c b/librz/analysis/serialize_analysis.c index 7231e42298..7c049c2d85 100644 --- a/librz/analysis/serialize_analysis.c +++ b/librz/analysis/serialize_analysis.c @@ -840,6 +840,7 @@ RZ_API RZ_NULLABLE RzAnalysisVar *rz_serialize_analysis_var_load(RZ_NONNULL RzAn RzType *vartype = rz_type_parse_string_single(fcn->analysis->typedb->parser, type, &error_msg); if (error_msg) { eprintf("Fail to parse the function variable (\"%s\") type: %s\n", name, type); + RZ_FREE(error_msg); goto beach; } ret = rz_analysis_function_set_var(fcn, delta, kind, vartype, 0, arg, name); @@ -1011,9 +1012,9 @@ static bool global_var_load_cb(void *user, const char *k, const char *v) { RzType *vartype = rz_type_parse_string_single(ctx->analysis->typedb->parser, type, &error_msg); if (error_msg) { eprintf("Fail to parse the function variable (\"%s\") type: %s\n", name, type); + RZ_FREE(error_msg); goto beach; } - RZ_FREE(error_msg); RzCore *core = ctx->analysis->core; addr = rz_num_math(core->num, addr_s); glob = rz_analysis_var_global_new(name, addr); @@ -1548,11 +1549,12 @@ RZ_API bool rz_serialize_analysis_xrefs_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAn RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) { rz_serialize_spaces_save(sdb_ns(db, "spaces", true), &analysis->meta_spaces); - PJ *j = pj_new(); - if (!j) { + if (rz_interval_tree_empty(&analysis->meta)) { return; } - if (rz_interval_tree_empty(&analysis->meta)) { + + PJ *j = pj_new(); + if (!j) { return; } char key[0x20]; @@ -1560,11 +1562,13 @@ RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAna RzAnalysisMetaItem *meta; ut64 addr = 0; size_t count = 0; + #define FLUSH \ pj_end(j); \ if (snprintf(key, sizeof(key), "0x%" PFMT64x, addr) >= 0) { \ sdb_set(db, key, pj_string(j), 0); \ } + rz_interval_tree_foreach (&analysis->meta, it, meta) { RzIntervalNode *node = rz_interval_tree_iter_get(&it); if (count && node->start != addr) { diff --git a/librz/analysis/sign.c b/librz/analysis/sign.c index 0e95ea0e56..b01d6a64d7 100644 --- a/librz/analysis/sign.c +++ b/librz/analysis/sign.c @@ -94,6 +94,7 @@ RZ_API RzList *rz_sign_fcn_types(RzAnalysis *a, RzAnalysisFunction *fcn) { } if (!callable->args || rz_pvector_empty(callable->args)) { rz_list_append(ret, rz_str_newf("func.%s.args=0", fcn->name)); + rz_type_callable_free(callable); return ret; } int fcnargs = rz_pvector_len(callable->args); diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 4531c89809..59aeb1367a 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -148,6 +148,7 @@ static void var_type_set_str(RzAnalysis *analysis, RzAnalysisVar *var, const cha RzType *realtype = rz_type_parse_string_single(analysis->typedb->parser, type, &error_msg); if (!realtype && error_msg) { eprintf("Fail to parse type \"%s\":\n%s\n", type, error_msg); + free(error_msg); return; } var_type_set(analysis, var, realtype, ref); diff --git a/librz/core/cmd_analysis.c b/librz/core/cmd_analysis.c index ac3498c86f..e5c27bd728 100644 --- a/librz/core/cmd_analysis.c +++ b/librz/core/cmd_analysis.c @@ -1234,6 +1234,7 @@ static int var_cmd(RzCore *core, const char *str) { if (!ttype || error_msg) { eprintf("Can't parse type: \"%s\"\n%s\n", type, error_msg); free(ostr); + free(error_msg); return false; } rz_analysis_var_set_type(v1, ttype); @@ -9118,6 +9119,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_signature_type_handler(RzCore *core, int RzType *ret_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[1], &error_msg); if (!ret_type || error_msg) { eprintf("Cannot parse type \"%s\":\n%s\n", argv[1], error_msg); + free(error_msg); return RZ_CMD_STATUS_ERROR; } if (!rz_type_func_ret_set(core->analysis->typedb, fcn->name, ret_type)) { @@ -9446,6 +9448,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_type_handler(RzCore *core, int argc RzType *v_type = rz_type_parse_string_single(core->analysis->typedb->parser, argv[2], &error_msg); if (!v_type || error_msg) { eprintf("Cannot parse type \"%s\":\n%s\n", argv[2], error_msg); + free(error_msg); return RZ_CMD_STATUS_ERROR; } rz_analysis_var_set_type(v, v_type); @@ -9575,6 +9578,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_bp_handler(RzCore *core, int argc, RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg); if (!var_type || error_msg) { eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg); + free(error_msg); return RZ_CMD_STATUS_ERROR; } rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_BPV, var_type, 4, isarg, varname); @@ -9679,6 +9683,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_sp_handler(RzCore *core, int argc, RzType *var_type = rz_type_parse_string_single(core->analysis->typedb->parser, vartype, &error_msg); if (!var_type || error_msg) { eprintf("Cannot parse type \"%s\":\n%s\n", vartype, error_msg); + free(error_msg); return RZ_CMD_STATUS_ERROR; } rz_analysis_function_set_var(fcn, delta, RZ_ANALYSIS_VAR_KIND_SPV, var_type, 4, isarg, varname); diff --git a/librz/core/cmd_type.c b/librz/core/cmd_type.c index 85f34be402..5375fbd6bb 100644 --- a/librz/core/cmd_type.c +++ b/librz/core/cmd_type.c @@ -180,6 +180,7 @@ static void types_xrefs(RzCore *core, const char *typestr) { if (!type || error_msg) { if (error_msg) { eprintf("%s", error_msg); + free(error_msg); } return; } @@ -260,6 +261,7 @@ static void types_xrefs_all(RzCore *core) { rz_list_push(types_list, strdup(ident)); } } + rz_list_free(types); } RzList *uniq_types = rz_list_uniq(types_list, (RzListComparator)strcmp); rz_list_free(types_list); diff --git a/librz/core/ctypes.c b/librz/core/ctypes.c index 60aa434036..80370b1936 100644 --- a/librz/core/ctypes.c +++ b/librz/core/ctypes.c @@ -918,12 +918,13 @@ RZ_IPI void rz_core_types_link_print(RzCore *core, RzType *type, ut64 addr, RzOu rz_cons_printf("tl \"%s\" 0x%" PFMT64x "\n", typestr, addr); break; case RZ_OUTPUT_MODE_LONG: { - const char *fmt = rz_type_as_format(core->analysis->typedb, type); + char *fmt = rz_type_as_format(core->analysis->typedb, type); if (!fmt) { eprintf("Can't fint type %s", typestr); } rz_cons_printf("(%s)\n", typestr); rz_core_cmdf(core, "pf %s @ 0x%" PFMT64x "\n", fmt, addr); + free(fmt); break; } default: @@ -961,12 +962,13 @@ RZ_IPI void rz_core_types_link_print_all(RzCore *core, RzOutputMode mode) { } RZ_IPI void rz_core_types_link(RzCore *core, const char *typestr, ut64 addr) { - char *error_msg; + char *error_msg = NULL; RzType *type = rz_type_parse_string_single(core->analysis->typedb->parser, typestr, &error_msg); if (!type || error_msg) { if (error_msg) { eprintf("%s", error_msg); } + free(error_msg); return; } rz_analysis_type_set_link(core->analysis, type, addr); diff --git a/librz/type/format.c b/librz/type/format.c index 7dabd2b6b0..8f3f59ab51 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -1791,7 +1791,7 @@ static int rz_type_format_struct(const RzTypeDB *typedb, RzPrint *p, RzStrBuf *o fmt = rz_type_format(typedb, name); } } - if (!fmt || !*fmt) { + if (RZ_STR_ISEMPTY(fmt)) { eprintf("Undefined struct '%s'.\n", name); return 0; } @@ -2857,13 +2857,14 @@ static void base_type_to_format_unfold(const RzTypeDB *typedb, RZ_NONNULL RzBase base_type_to_format_no_unfold(typedb, btyp, memb->name, format, fields); } } else { - const char *membfmt = rz_type_as_format(typedb, memb->type); + char *membfmt = rz_type_as_format(typedb, memb->type); rz_strbuf_append(format, membfmt); if (!rz_type_is_atomic(typedb, memb->type)) { rz_strbuf_appendf(fields, "(%s)%s ", membtype, memb->name); } else { rz_strbuf_appendf(fields, "%s ", memb->name); } + free(membfmt); } } } @@ -2989,15 +2990,15 @@ RZ_API RZ_OWN char *rz_type_as_format(const RzTypeDB *typedb, RZ_NONNULL RzType if (type->kind == RZ_TYPE_KIND_CALLABLE) { // We can't print anything useful for function type // Thus we consider this is just a `void *` pointer - return "p"; + return strdup("p"); } // Special case of callable ptr or `void *` if (rz_type_is_void_ptr(type) || rz_type_is_callable_ptr(type)) { - return "p"; + return strdup("p"); } // Special case of `char *` if (rz_type_is_char_ptr(type)) { - return "z"; + return strdup("z"); } RzStrBuf *buf = rz_strbuf_new(NULL); type_to_format(typedb, buf, type); diff --git a/librz/type/parser/c_cpp_parser.c b/librz/type/parser/c_cpp_parser.c index a0fa7decf3..2515ae0d7a 100644 --- a/librz/type/parser/c_cpp_parser.c +++ b/librz/type/parser/c_cpp_parser.c @@ -178,19 +178,22 @@ static int type_parse_string(CParserState *state, const char *code, char **error // If there were errors during the parser then the result is different from 0 if (result) { - const char *error_msgs = rz_strbuf_drain_nofree(state->errors); + char *error_msgs = rz_strbuf_drain_nofree(state->errors); RZ_LOG_DEBUG("Errors:\n"); RZ_LOG_DEBUG("%s", error_msgs); - const char *warning_msgs = rz_strbuf_drain_nofree(state->warnings); + char *warning_msgs = rz_strbuf_drain_nofree(state->warnings); RZ_LOG_DEBUG("Warnings:\n"); RZ_LOG_DEBUG("%s", warning_msgs); if (error_msg) { *error_msg = strdup(error_msgs); } + free(error_msgs); + free(warning_msgs); } if (state->verbose) { - const char *debug_msgs = rz_strbuf_drain_nofree(state->debug); + char *debug_msgs = rz_strbuf_drain_nofree(state->debug); RZ_LOG_DEBUG("%s", debug_msgs); + free(debug_msgs); } // After everything parsed, we should preserve the base type database @@ -221,13 +224,16 @@ RZ_API int rz_type_parse_string_stateless(RzTypeParser *parser, const char *code */ RZ_API int rz_type_parse_file_stateless(RzTypeParser *parser, const char *path, const char *dir, char **error_msg) { size_t read_bytes = 0; - const char *source_code = rz_file_slurp(path, &read_bytes); + char *source_code = rz_file_slurp(path, &read_bytes); if (!source_code || !read_bytes) { + free(source_code); return -1; } ut64 file_size = rz_file_size(path); RZ_LOG_DEBUG("File size is %" PFMT64d " bytes, read %zu bytes\n", file_size, read_bytes); - return rz_type_parse_string_stateless(parser, source_code, error_msg); + int result = rz_type_parse_string_stateless(parser, source_code, error_msg); + free(source_code); + return result; } /** @@ -240,13 +246,16 @@ RZ_API int rz_type_parse_file_stateless(RzTypeParser *parser, const char *path, */ RZ_API int rz_type_parse_file(RzTypeDB *typedb, const char *path, const char *dir, char **error_msg) { size_t read_bytes = 0; - const char *source_code = rz_file_slurp(path, &read_bytes); + char *source_code = rz_file_slurp(path, &read_bytes); if (!source_code || !read_bytes) { + free(source_code); return -1; } ut64 file_size = rz_file_size(path); RZ_LOG_DEBUG("File size is %" PFMT64d " bytes, read %zu bytes\n", file_size, read_bytes); - return rz_type_parse_string(typedb, source_code, error_msg); + int result = rz_type_parse_string(typedb, source_code, error_msg); + free(source_code); + return result; } /** @@ -351,15 +360,17 @@ RZ_API RZ_OWN RzType *rz_type_parse_string_single(RzTypeParser *parser, const ch // If there were errors during the parser then the result is different from 0 if (result || !tpair) { - const char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors); + char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors); RZ_LOG_DEBUG("Errors:\n"); RZ_LOG_DEBUG("%s", error_msgs); - const char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings); + char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings); RZ_LOG_DEBUG("Warnings:\n"); RZ_LOG_DEBUG("%s", warning_msgs); if (error_msg) { *error_msg = strdup(error_msgs); } + free(error_msgs); + free(warning_msgs); } if (parser->state->verbose) { char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug); @@ -439,19 +450,22 @@ RZ_API RZ_OWN RzType *rz_type_parse_string_declaration_single(RzTypeParser *pars // If there were errors during the parser then the result is different from 0 if (result || !tpair) { - const char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors); + char *error_msgs = rz_strbuf_drain_nofree(parser->state->errors); RZ_LOG_DEBUG("Errors:\n"); RZ_LOG_DEBUG("%s", error_msgs); - const char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings); + char *warning_msgs = rz_strbuf_drain_nofree(parser->state->warnings); RZ_LOG_DEBUG("Warnings:\n"); RZ_LOG_DEBUG("%s", warning_msgs); if (error_msg) { *error_msg = strdup(error_msgs); } + free(error_msgs); + free(warning_msgs); } if (parser->state->verbose) { - const char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug); + char *debug_msgs = rz_strbuf_drain_nofree(parser->state->debug); RZ_LOG_DEBUG("%s", debug_msgs); + free(debug_msgs); } // After everything parsed, we should preserve the base type database diff --git a/librz/type/parser/types_parser.c b/librz/type/parser/types_parser.c index f4b8a58f25..49b4d15d95 100644 --- a/librz/type/parser/types_parser.c +++ b/librz/type/parser/types_parser.c @@ -347,20 +347,20 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser if (!(*tpair = c_parser_new_structure_naked_type(state, name))) { parser_error(state, "Cannot create \"%s\" naked structure type in the context\n", name); result = -1; - goto rexit; + goto snexit; } - goto rexit; + goto snexit; } // We still could create the "forward looking struct declaration" // The parser then can augment the definition if (!(*tpair = c_parser_new_structure_forward_definition(state, name))) { parser_error(state, "Cannot create \"%s\" forward structure definition in the context\n", name); result = -1; - goto rexit; + goto snexit; } - goto rexit; + goto snexit; } else { - goto rexit; + goto snexit; } } @@ -377,8 +377,11 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser if (!struct_pair) { parser_error(state, "Error forming RzType and RzBaseType pair out of struct: \"%s\"\n", name); result = -1; - goto rexit; + goto snexit; } + + char *real_type = NULL; + char *real_identifier = NULL; int i; for (i = 0; i < body_child_count; i++) { parser_debug(state, "struct: processing %d field...\n", i); @@ -392,7 +395,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser if (ts_node_is_null(first_leaf)) { node_malformed_error(state, child, text, "field_declaration"); result = -1; - goto rexit; + goto snexit; } const char *leaf_type = ts_node_type(first_leaf); // If we have type qualifier in this position it is related to @@ -412,7 +415,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser parser_error(state, "ERROR: Struct field AST should contain (field_declaration) node!\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto snexit; } // Every field node should have at least type and declarator: @@ -422,8 +425,9 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser parser_error(state, "ERROR: Struct field AST shoudl contain type and declarator items"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto snexit; } + // Every field can be: // - atomic: "int a;" or "char b[20]" // - bitfield: int a:7;" @@ -449,33 +453,34 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser parser_error(state, "ERROR: Struct bitfield cannot contain non-primitive bitfield!\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto snexit; } - const char *real_type = ts_node_sub_string(field_type, text); + real_type = ts_node_sub_string(field_type, text); if (!real_type) { parser_error(state, "ERROR: Struct bitfield type should not be NULL!\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto snexit; } - const char *real_identifier = ts_node_sub_string(field_declarator, text); + real_identifier = ts_node_sub_string(field_declarator, text); if (!real_identifier) { parser_error(state, "ERROR: Struct bitfield identifier should not be NULL!\n"); node_malformed_error(state, child, text, "struct field"); + free(real_type); result = -1; - goto rexit; + goto snexit; } if (ts_node_named_child_count(bitfield_clause) != 1) { node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto srnexit; } TSNode field_bits = ts_node_named_child(bitfield_clause, 0); if (ts_node_is_null(field_bits)) { parser_error(state, "ERROR: Struct bitfield bits AST node should not be NULL!\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto srnexit; } const char *bits_str = ts_node_sub_string(field_bits, text); int bits = rz_num_get(NULL, bits_str); @@ -485,7 +490,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser parser_error(state, "ERROR: parsing bitfield struct member identifier\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto srnexit; } // Then we augment resulting type field with the data from parsed declarator char *membname = NULL; @@ -493,7 +498,7 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser parser_error(state, "ERROR: parsing bitfield struct member declarator\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto srnexit; } // Add a struct member RzVector *members = &struct_pair->btype->struct_data.members; @@ -507,25 +512,26 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser if (!element) { parser_error(state, "Error appending bitfield struct member to the base type\n"); result = -1; - goto rexit; + goto srnexit; } } else { // 2nd case, normal structure // AST looks like // type: (primitive_type) declarator: (field_identifier) - char *real_type = ts_node_sub_string(field_type, text); + real_type = ts_node_sub_string(field_type, text); if (!real_type) { parser_error(state, "ERROR: Struct field type should not be NULL!\n"); node_malformed_error(state, child, text, "struct field"); result = -1; - goto rexit; + goto snexit; } - char *real_identifier = ts_node_sub_string(field_declarator, text); + real_identifier = ts_node_sub_string(field_declarator, text); if (!real_identifier) { parser_error(state, "ERROR: Struct declarator should not be NULL!\n"); node_malformed_error(state, child, text, "struct field"); + free(real_type); result = -1; - goto rexit; + goto snexit; } parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier); ParserTypePair *membtpair = NULL; @@ -533,20 +539,16 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) { parser_error(state, "ERROR: parsing struct member type\n"); node_malformed_error(state, child, text, "struct field"); - free(real_identifier); - free(real_type); result = -1; - goto rexit; + goto srnexit; } // Then we augment resulting type field with the data from parsed declarator char *membname = NULL; if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) { parser_error(state, "ERROR: parsing struct member declarator\n"); node_malformed_error(state, child, text, "struct field"); - free(real_identifier); - free(real_type); result = -1; - goto rexit; + goto srnexit; } // Add a struct member RzVector *members = &struct_pair->btype->struct_data.members; @@ -559,14 +561,10 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser void *element = rz_vector_push(members, &memb); // returns null if no space available if (!element) { parser_error(state, "Error appending struct member to the base type\n"); - free(real_identifier); - free(real_type); result = -1; - goto rexit; + goto srnexit; } parser_debug(state, "Appended member \"%s\" into struct \"%s\"\n", membname, name); - free(real_identifier); - free(real_type); } } // If parsing successfull completed - we store the state @@ -578,7 +576,10 @@ int parse_struct_node(CParserState *state, TSNode node, const char *text, Parser } } *tpair = struct_pair; -rexit: +srnexit: + free(real_type); + free(real_identifier); +snexit: free(name); return result; } @@ -597,8 +598,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT node_malformed_error(state, node, text, "union"); return -1; } + int result = 0; // Name is optional, in abstract definitions or as the member of nested types - const char *name = NULL; + char *name = NULL; TSNode union_name = ts_node_child_by_field_name(node, "name", 4); if (ts_node_is_null(union_name)) { parser_debug(state, "Anonymous union\n"); @@ -657,6 +659,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT parser_error(state, "Error forming RzType and RzBaseType pair out of union\n"); return -1; } + + char *real_type = NULL; + char *real_identifier = NULL; int i; for (i = 0; i < body_child_count; i++) { parser_debug(state, "union: processing %d field...\n", i); @@ -723,52 +728,53 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT if (strcmp(ts_node_type(field_type), "primitive_type")) { parser_error(state, "ERROR: Union bitfield cannot contain non-primitive bitfield!\n"); node_malformed_error(state, child, text, "union field"); - return -1; + result = -1; + goto unexit; } - char *real_type = ts_node_sub_string(field_type, text); + real_type = ts_node_sub_string(field_type, text); if (!real_type) { parser_error(state, "ERROR: Union bitfield type should not be NULL!\n"); node_malformed_error(state, child, text, "union field"); - return -1; + result = -1; + goto unexit; } - char *real_identifier = ts_node_sub_string(field_declarator, text); + real_identifier = ts_node_sub_string(field_declarator, text); if (!real_identifier) { parser_error(state, "ERROR: Union bitfield identifier should not be NULL!\n"); node_malformed_error(state, child, text, "union field"); free(real_type); - return -1; + result = -1; + goto unexit; } if (ts_node_named_child_count(bitfield_clause) != 1) { node_malformed_error(state, child, text, "union field"); - free(real_type); - free(real_identifier); - return -1; + result = -1; + goto urnexit; } TSNode field_bits = ts_node_named_child(bitfield_clause, 0); if (ts_node_is_null(field_bits)) { parser_error(state, "ERROR: Union bitfield bits AST node should not be NULL!\n"); node_malformed_error(state, child, text, "union field"); - free(real_type); - free(real_identifier); - return -1; + result = -1; + goto urnexit; } const char *bits_str = ts_node_sub_string(field_bits, text); int bits = rz_num_get(NULL, bits_str); parser_debug(state, "field type: %s field_identifier: %s bits: %d\n", real_type, real_identifier, bits); - free(real_type); - free(real_identifier); ParserTypePair *membtpair = NULL; if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) { parser_error(state, "ERROR: parsing union member identifier\n"); node_malformed_error(state, child, text, "union field"); - return -1; + result = -1; + goto urnexit; } // Then we augment resulting type field with the data from parsed declarator char *membname = NULL; if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) { parser_error(state, "ERROR: parsing union member declarator\n"); node_malformed_error(state, child, text, "union field"); - return -1; + result = -1; + goto urnexit; } // Add a union member RzVector *members = &union_pair->btype->union_data.members; @@ -781,24 +787,27 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT void *element = rz_vector_push(members, &memb); // returns null if no space available if (!element) { parser_error(state, "Error appending union member to the base type\n"); - return -1; + result = -1; + goto urnexit; } } else { // 2nd case, normal union // AST looks like // type: (primitive_type) declarator: (field_identifier) - char *real_type = ts_node_sub_string(field_type, text); + real_type = ts_node_sub_string(field_type, text); if (!real_type) { parser_error(state, "ERROR: Union field type should not be NULL!\n"); node_malformed_error(state, child, text, "union field"); - return -1; + result = -1; + goto unexit; } - char *real_identifier = ts_node_sub_string(field_declarator, text); + real_identifier = ts_node_sub_string(field_declarator, text); if (!real_identifier) { parser_error(state, "ERROR: Union declarator should not be NULL!\n"); node_malformed_error(state, child, text, "union field"); free(real_type); - return -1; + result = -1; + goto unexit; } parser_debug(state, "field type: %s field_declarator: %s\n", real_type, real_identifier); ParserTypePair *membtpair = NULL; @@ -806,18 +815,16 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT if (parse_type_node_single(state, field_type, text, &membtpair, is_const)) { parser_error(state, "ERROR: parsing union member type\n"); node_malformed_error(state, child, text, "union field"); - free(real_identifier); - free(real_type); - return -1; + result = -1; + goto urnexit; } // Then we augment resulting type field with the data from parsed declarator char *membname = NULL; if (parse_type_declarator_node(state, field_declarator, text, &membtpair, &membname)) { parser_error(state, "ERROR: parsing union member declarator\n"); node_malformed_error(state, child, text, "union field"); - free(real_identifier); - free(real_type); - return -1; + result = -1; + goto urnexit; } // Add a union member RzVector *members = &union_pair->btype->union_data.members; @@ -830,12 +837,9 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT void *element = rz_vector_push(members, &memb); // returns null if no space available if (!element) { parser_error(state, "Error appending union member to the base type\n"); - free(real_identifier); - free(real_type); - return -1; + result = -1; + goto urnexit; } - free(real_identifier); - free(real_type); } } // If parsing successfull completed - we store the state @@ -847,7 +851,12 @@ int parse_union_node(CParserState *state, TSNode node, const char *text, ParserT } } *tpair = union_pair; - return 0; +urnexit: + free(real_type); + free(real_identifier); +unexit: + free(name); + return result; } // Parsing enum definitions - concrete and abstract ones @@ -1225,6 +1234,7 @@ int parse_parameter_list(CParserState *state, TSNode paramlist, const char *text free(identifier); return -1; } + free(identifier); } return 0; }