From 5740195cb3ce8bbfd2b0b48828888945de85b725 Mon Sep 17 00:00:00 2001 From: matteo Date: Fri, 30 Jan 2026 12:21:29 +0100 Subject: [PATCH] fix: heap-use-after-free and memory leaks on erorr cases --- src/main.c | 7 +++---- src/parser/grammar.c | 14 +++++++++----- src/parser/grammar_basic.c | 7 +++++-- src/utils/hash_map/hash_map.c | 1 + 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index c8988ca..6b0f59f 100644 --- a/src/main.c +++ b/src/main.c @@ -66,8 +66,11 @@ static int main_loop(struct lexer_context *ctx, struct args_options *options, if (command_ast == NULL) return err_input(&vars); + // === free + ast_free(&command_ast); parser_close(); + hash_map_free(&vars); return return_code; } @@ -120,9 +123,5 @@ int main(int argc, char **argv) return_code = main_loop(&ctx, &options, vars); - // === free - - hash_map_free(&vars); - return return_code; } diff --git a/src/parser/grammar.c b/src/parser/grammar.c index 57d7d20..73258ea 100644 --- a/src/parser/grammar.c +++ b/src/parser/grammar.c @@ -238,16 +238,20 @@ struct ast *parse_input(struct lexer_context *ctx) } struct ast *ast = parse_list(ctx); - if (ast == NULL) - return NULL; - token = PEEK_TOKEN(); - if (token->type == TOKEN_NEWLINE || token->type == TOKEN_EOF) + + if (ast == NULL) { - if (token->type == TOKEN_NEWLINE) + if (token != NULL && token->type == TOKEN_EOF) { POP_TOKEN(); } + return NULL; + } + + if (token->type == TOKEN_NEWLINE || token->type == TOKEN_EOF) + { + POP_TOKEN(); return ast; } diff --git a/src/parser/grammar_basic.c b/src/parser/grammar_basic.c index 9b4add2..6a6839b 100644 --- a/src/parser/grammar_basic.c +++ b/src/parser/grammar_basic.c @@ -329,12 +329,13 @@ struct ast *parse_if_rule(struct lexer_context *ctx) struct ast *condition_content = parse_compound_list(ctx); // Then keyword - token = POP_TOKEN(); + token = PEEK_TOKEN(); if (token->type != TOKEN_THEN) { perror("Expected the 'then' keyword but token has different type"); return err_if_rule(&condition_content, NULL, NULL); } + POP_TOKEN(); // Then content struct ast *then_content = parse_compound_list(ctx); @@ -344,6 +345,7 @@ struct ast *parse_if_rule(struct lexer_context *ctx) } struct ast *else_content = NULL; + token = PEEK_TOKEN(); // Eventual else/elif clause(s) if (is_first(*token, RULE_ELSE_CLAUSE)) { @@ -355,12 +357,13 @@ struct ast *parse_if_rule(struct lexer_context *ctx) } // Fi keyword - token = POP_TOKEN(); + token = PEEK_TOKEN(); if (token->type != TOKEN_FI) { perror("Expected the 'fi' keyword but token has different type"); return err_if_rule(&condition_content, &then_content, &else_content); } + POP_TOKEN(); // Result struct ast *result = diff --git a/src/utils/hash_map/hash_map.c b/src/utils/hash_map/hash_map.c index 3d77734..6f9a513 100644 --- a/src/utils/hash_map/hash_map.c +++ b/src/utils/hash_map/hash_map.c @@ -117,6 +117,7 @@ void hash_map_free(struct hash_map **hash_map) free((*hash_map)->data); free(*hash_map); } + *hash_map = NULL; } void hash_map_foreach(struct hash_map *hash_map,