Fix some of the Coverity issues in types and analysis code (#1474)

* Fix CID 354663
* Fix CID 352572
* Fix CID 352560
* Fix CID 352557
* Fix CID 352537
* Fix CID 352536
* Fix CID 352490
* Fix CID 352488
* Fix CID 352486
* Fix CID 352484
* Fix CID 352480
* Fix CID 352475
* Fix CID 352471
* Fix CID 352464
* Fix CID 352461
* Fix CID 352455
* Fix CID 352452
* Fix CID 352448
This commit is contained in:
Anton Kochkov 2021-08-18 15:19:08 +08:00 committed by GitHub
parent 92b7e9321a
commit 3d9baa149d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 136 additions and 91 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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;
}