From 136fac9243ff71f38d3ee39518df9a332509f573 Mon Sep 17 00:00:00 2001 From: lisk77 Date: Mon, 24 Nov 2025 23:52:51 +0100 Subject: [PATCH] fix: leaks shouldnt happen anymore --- src/commands.c | 254 ++++++++++++++++++++----------------------------- src/file.c | 5 + src/object.c | 7 ++ 3 files changed, 115 insertions(+), 151 deletions(-) diff --git a/src/commands.c b/src/commands.c index f07a439..8acb7f4 100644 --- a/src/commands.c +++ b/src/commands.c @@ -76,50 +76,70 @@ int diff(char* file1_path, char* file2_path) { if (!file2) exit(1); ActionList* actions = myers_diff(file1, file2, 0, 0); - if (!actions) printf("ERROR: something went wrong while taking the diff!"); - else visualize_diff(file1, file2, actions); + if (!actions) { + printf("ERROR: something went wrong while taking the diff!"); + free_file(file1); + free_file(file2); + return 1; + } else { + visualize_diff(file1, file2, actions); + } + + free_action_list(actions); + free_file(file1); + free_file(file2); return 1; } int status() { - FileInfoBuffer* files = file_info_buffer_new(); + int ret = 1; + FileInfoBuffer* files = NULL; + char* root = NULL; + char* branch = NULL; + CommitLog* log = NULL; + BaseFileBuffer* tracked_list = NULL; + StringBuffer* modified_files = NULL; + StringBuffer* deleted_files = NULL; + StringBuffer* untracked_files = NULL; + Changes* changes = NULL; + + files = file_info_buffer_new(); + if (!files) goto cleanup; + char relative[PATH_MAX] = ""; - char* root = find_root(relative); - if (!root) { - list_free(files); - return 1; - } + root = find_root(relative); + if (!root) goto cleanup; walk(root, relative, relative, files, 0, root); file_info_buffer_sort(files); char branch_path[PATH_MAX]; snprintf(branch_path, sizeof(branch_path), "%s/.merk/BRANCH", root); - char* branch = get_file_content(branch_path); + branch = get_file_content(branch_path); + if (!branch) goto cleanup; char info_path[PATH_MAX]; snprintf(info_path, sizeof(info_path), "%s/.merk/info/%s", root, branch); char log_path[PATH_MAX]; snprintf(log_path, sizeof(log_path), "%s/.merk/logs/branches/%s", root, branch); - CommitLog* log = commit_log_new(); + log = commit_log_new(); + if (!log) goto cleanup; read_commit_log(log, log_path); - char* last_tree_hash = NULL; - if (log->len != 0) { - last_tree_hash = ((Commit*)log->items + (log->len))->tree_hash; - } - BaseFileBuffer* tracked_list = base_file_buffer_new(); + tracked_list = base_file_buffer_new(); + if (!tracked_list) goto cleanup; read_base_file_list(tracked_list, info_path); - StringBuffer* modified_files = string_buffer_new(); - StringBuffer* deleted_files = string_buffer_new(); - StringBuffer* untracked_files = string_buffer_new(); + modified_files = string_buffer_new(); + deleted_files = string_buffer_new(); + untracked_files = string_buffer_new(); + if (!modified_files || !deleted_files || !untracked_files) goto cleanup; - Changes* changes = calloc(1, sizeof(Changes)); + changes = calloc(1, sizeof(Changes)); if (!changes) { printf("ERROR: unable to allocate memory for changes!\n"); - return 1; + goto cleanup; } changes->insertions = 0; @@ -142,13 +162,14 @@ int status() { File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL); if (!basefile) { printf("ERROR: unable to parse base file %s!\n", file_name); - return 1; + goto cleanup; } File* modified_file = new_file(file_name); if (!modified_file) { printf("ERROR: unable to read modified file %s!\n", file_name); - return 1; + free_file(basefile); + goto cleanup; } File* comparison_file = basefile; @@ -173,7 +194,10 @@ int status() { ActionList* diff = myers_diff(comparison_file, modified_file, 0, 0); if (!diff) { printf("ERROR: unable to compute diff for file %s!\n", file_name); - return 1; + free_file(modified_file); + if (comparison_file != basefile) free_file(comparison_file); + free_file(basefile); + goto cleanup; } if (diff->len != 0) { @@ -219,9 +243,19 @@ int status() { printf("\n\x1b[32;1m%d+\x1b[0m \x1b[31;1m%d-\x1b[0m on branch \x1b[39;1;4m%s\x1b[0m with %lu commits\n", changes->insertions, changes->deletions, branch, log->len); + ret = 1; + +cleanup: + if (modified_files) list_free(modified_files); + if (deleted_files) list_free(deleted_files); + if (untracked_files) list_free(untracked_files); + if (tracked_list) base_file_buffer_free(tracked_list); + if (log) commit_log_free(log); file_info_buffer_free(files); + free(branch); free(root); - return 1; + free(changes); + return ret; } int commit(int argc, char** argv) { @@ -385,6 +419,15 @@ int commit(int argc, char** argv) { } FlatMap* file_hash_map = flat_map_new(); + if (!file_hash_map) { + free(commit_message); + list_free(files); + base_file_buffer_free(base_files); + free(branch); + free(root); + free_config(&config); + return 1; + } Changes* changes = calloc(1, sizeof(Changes)); if (!changes) { free(commit_message); @@ -393,6 +436,7 @@ int commit(int argc, char** argv) { free(branch); free(root); free_config(&config); + flat_map_free(file_hash_map); return 1; } @@ -408,16 +452,10 @@ int commit(int argc, char** argv) { // Compress the files content and put it into the object database File* modified_file = new_file(files->items[idx]); if (!modified_file) { - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } changes->insertions += modified_file->lines; + free_file(modified_file); char file_hash[41]; snapshot_file(files->items[idx], root, 0, branch, file_hash); @@ -431,41 +469,20 @@ int commit(int argc, char** argv) { object_hash(BaseFileObject, id, base_file_hash); File* basefile = parse_object(base_file_hash, BaseFileObject, NULL, NULL); if (!basefile) { - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } File* modified_file = new_file(files->items[idx]); if (!modified_file) { free_file(basefile); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } ActionList* diff = myers_diff(basefile, modified_file, 0, 0); if (!diff) { free_file(basefile); free_file(modified_file); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } if (base_file->diff_num == 0) { @@ -491,14 +508,7 @@ int commit(int argc, char** argv) { free_action_list(diff); free_file(modified_file); free_file(basefile); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } File* last_version = apply_diff(basefile, last_diff); @@ -507,14 +517,7 @@ int commit(int argc, char** argv) { free_action_list(diff); free_file(modified_file); free_file(basefile); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } ActionList* modified_diff = myers_diff(last_version, modified_file, 0, 0); @@ -523,14 +526,7 @@ int commit(int argc, char** argv) { free_action_list(diff); free_file(modified_file); free_file(basefile); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } for (size_t idx = 0; idx < modified_diff->len; idx++) { @@ -568,14 +564,7 @@ int commit(int argc, char** argv) { free_action_list(diff); free_file(modified_file); free_file(basefile); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - free(changes); - return 1; + goto commit_cleanup; } snprintf(id, id_len, "%s %zu %s", (char*)files->items[idx], base_file->diff_num, branch); @@ -598,13 +587,7 @@ int commit(int argc, char** argv) { write_base_file_list(base_files, info_path); FileInfoBuffer* tree = basefilebuffer_to_fileinfobuffer(base_files); if (!tree) { - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } for (size_t idx = 0; idx < tree->len; idx++) { @@ -622,13 +605,7 @@ int commit(int argc, char** argv) { if (!log) { file_info_buffer_free(tree); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } read_commit_log(log, log_path); @@ -662,13 +639,7 @@ int commit(int argc, char** argv) { free(authors[0].timestamp); free(authors); file_info_buffer_free(tree); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } char commit_hash_content[4096]; @@ -683,13 +654,7 @@ int commit(int argc, char** argv) { free(authors[0].email); free(authors[0].timestamp); free(authors); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } offset += written; @@ -702,13 +667,7 @@ int commit(int argc, char** argv) { free(authors[0].email); free(authors[0].timestamp); free(authors); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } offset += written; } @@ -721,13 +680,7 @@ int commit(int argc, char** argv) { free(authors[0].email); free(authors[0].timestamp); free(authors); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } offset += written; @@ -739,13 +692,7 @@ int commit(int argc, char** argv) { free(authors[0].email); free(authors[0].timestamp); free(authors); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } offset += written; @@ -757,13 +704,7 @@ int commit(int argc, char** argv) { free(authors[0].email); free(authors[0].timestamp); free(authors); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + goto commit_cleanup; } offset += written; @@ -783,13 +724,11 @@ int commit(int argc, char** argv) { if (!write_commit_log(log, log_path)) { commit_log_free(log); file_info_buffer_free(tree); - free(commit_message); - list_free(files); - base_file_buffer_free(base_files); - free(branch); - free(root); - free_config(&config); - return 1; + free(authors[0].name); + free(authors[0].email); + free(authors[0].timestamp); + free(authors); + goto commit_cleanup; } commit_log_free(log); @@ -814,8 +753,21 @@ int commit(int argc, char** argv) { free(branch); free(root); free_config(&config); + flat_map_free(file_hash_map); free(commit_message); + free(changes); return 1; + +commit_cleanup: + free(commit_message); + list_free(files); + base_file_buffer_free(base_files); + free(branch); + free(root); + free_config(&config); + flat_map_free(file_hash_map); + free(changes); + return 1; } int commit_log() { diff --git a/src/file.c b/src/file.c index d41589e..63c0f2b 100644 --- a/src/file.c +++ b/src/file.c @@ -305,6 +305,11 @@ int file_info_buffer_push(FileInfoBuffer* buffer, FileInfo info) { void file_info_buffer_free(List* buffer) { if (buffer) { + for (size_t i = 0; i < buffer->len; i++) { + FileInfo* info = (FileInfo*)buffer->items + i; + free(info->name); + free(info->hash); + } free(buffer->items); free(buffer); } diff --git a/src/object.c b/src/object.c index 2284d4a..3e3469f 100644 --- a/src/object.c +++ b/src/object.c @@ -15,6 +15,7 @@ char* get_object(char* hash, size_t* size_out) { unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(file_path, &compressed_size); if (!compressed_data || compressed_size == 0) { free(compressed_data); + free(root); return NULL; } @@ -27,12 +28,14 @@ char* get_object(char* hash, size_t* size_out) { if (idx == 0) { perror("ERROR: no length found at start of object!"); free(compressed_data); + free(root); return NULL; } char* size_str = calloc(idx + 1, sizeof(char)); if (!size_str) { free(compressed_data); + free(root); return NULL; } @@ -45,6 +48,7 @@ char* get_object(char* hash, size_t* size_out) { perror("ERROR: invalid length in get_object!"); free(size_str); free(compressed_data); + free(root); return NULL; } free(size_str); @@ -56,6 +60,7 @@ char* get_object(char* hash, size_t* size_out) { char* decompressed = malloc(original_size + 1); if (!decompressed) { free(compressed_data); + free(root); return NULL; } uLongf decompressed_size = original_size; @@ -64,10 +69,12 @@ char* get_object(char* hash, size_t* size_out) { perror("ERROR: decompression failed in get_object!"); free(decompressed); free(compressed_data); + free(root); return NULL; } free(compressed_data); + free(root); decompressed[decompressed_size] = '\0'; if (size_out) {