From a8a5408db47309d804db85ef61b5709c4a06a7dc Mon Sep 17 00:00:00 2001 From: lisk77 Date: Sat, 20 Sep 2025 05:39:28 +0200 Subject: [PATCH] fix(object): read_diff didnt read correctly --- include/object.h | 5 +- src/object.c | 125 +++++++++++------------------------------------ 2 files changed, 32 insertions(+), 98 deletions(-) diff --git a/include/object.h b/include/object.h index bfce57c..655d22d 100644 --- a/include/object.h +++ b/include/object.h @@ -27,9 +27,10 @@ #include "common.h" char* get_object(char*, size_t*); -void* parse_object(char*, ObjectType, size_t*); +void* parse_object(char*, ObjectType, size_t*, char*); int save_diff(ActionList*, char*, char*, size_t, char*, File*, int); int read_diff(char*, char*, ActionList*); -int save_file_diff(char*, char*, size_t, char*, Changes*); +int save_file_diff(char*, char*, size_t, char*, ActionList*); +File* apply_diff(File*, ActionList*); #endif // OBJECT_H \ No newline at end of file diff --git a/src/object.c b/src/object.c index e121b63..223f547 100644 --- a/src/object.c +++ b/src/object.c @@ -1,19 +1,23 @@ #include "object.h" char* get_object(char* hash, size_t* size_out) { - char dir_path[PATH_MAX]; - char repo_path[PATH_MAX]; - char file_path[PATH_MAX]; - snprintf(dir_path, sizeof(dir_path), ".merk/objects/%.2s", hash); - snprintf(repo_path, sizeof(repo_path), "%s/%s", dir_path, hash+2); - realpath(repo_path, file_path); + char* root = find_root(NULL); + if (!root) { + perror("ERROR: unable to find root directory of the repository!"); + return NULL; + } + char dir_path[PATH_MAX]; + char file_path[PATH_MAX]; + snprintf(dir_path, sizeof(dir_path), "%s/.merk/objects/%.2s", root, hash); + snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, hash+2); size_t compressed_size; unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(file_path, &compressed_size); if (!compressed_data || compressed_size == 0) { free(compressed_data); return NULL; } + size_t idx = 0; while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) { @@ -73,7 +77,7 @@ char* get_object(char* hash, size_t* size_out) { return decompressed; } -void* parse_object(char* hash, ObjectType type, size_t* size_out) { +void* parse_object(char* hash, ObjectType type, size_t* size_out, char* meta_hash) { size_t line_count; char* content = get_object(hash, &line_count); if (!content) return NULL; @@ -109,7 +113,12 @@ void* parse_object(char* hash, ObjectType type, size_t* size_out) { return buffer; } case FileDiffObject: { - + ActionList* diff = new_list(); + if (!read_diff(content, meta_hash, diff)) { + free(content); + return NULL; + } + return diff; } default: free(content); return NULL; @@ -163,8 +172,8 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba 6 + snprintf(NULL, 0, "%d", action.line_original) + snprintf(NULL, 0, "%d", action.line_changed) + - snprintf(NULL, 0, "%zu", strlen(modified_file->content[action.line_changed])) + - strlen(modified_file->content[action.line_changed]); + snprintf(NULL, 0, "%zu", strlen(action.content)) + + strlen(action.content); } char tmp[buffer_size]; @@ -190,8 +199,8 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba "1 %zu %zu %zu %s ", action.line_original, action.line_changed, - strlen(modified_file->content[action.line_changed]), - modified_file->content[action.line_changed] + strlen(action.content), + action.content ); } @@ -250,7 +259,7 @@ int save_diff(ActionList* diff, char* path, char* root, size_t diff_id, char* ba } int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { - if (!content || !basefile_hash || !diff_out) { + if (!content || !diff_out) { return 0; } @@ -278,18 +287,19 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { char* end; long actions = strtol(number_of_actions, &end, 10); - free(number_of_actions); if (end == number_of_actions || *end != '\0' || actions <= 0) { perror("ERROR: invalid number of actions in read_diff!"); return 0; } + free(number_of_actions); + size_t action_idx = 0; while (content[idx] && action_idx < (size_t)actions) { idx++; - Action action = {0}; + Action action; if (content[idx] == '0') { idx++; @@ -313,6 +323,8 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { return 0; } idx = endptr - content; + action.content = NULL; + action.type = DELETE; } else if (content[idx] == '1') { idx++; if (content[idx] != ' ') { @@ -349,6 +361,7 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { return 0; } idx += content_length; + action.type = INSERT; } else { perror("ERROR: unknown action type in read_diff!"); return 0; @@ -362,89 +375,9 @@ int read_diff(char* content, char* basefile_hash, ActionList* diff_out) { return 1; } -int save_file_diff(char* path, char* root, size_t diff_id, char* basefile_hash, Changes* changes) { - char basefile_location[2+strlen(root)+strlen("/.merk/objects/")+strlen(basefile_hash)]; - snprintf(basefile_location, sizeof(basefile_location), "%s/.merk/objects/%.2s/%s", root, basefile_hash, basefile_hash+2); - - size_t compressed_size; - unsigned char* compressed_data = (unsigned char*)get_file_content_with_size(basefile_location, &compressed_size); - if (!compressed_data) return 0; - - size_t idx = 0; - - while (idx < compressed_size && IS_DIGIT(compressed_data[idx])) { - idx++; - } - - if (idx == 0) { - perror("ERROR: no length found at start of save_file_diff!"); - free(compressed_data); - return 0; - } - - char* size_str = calloc(idx + 1, sizeof(char)); - if (!size_str) { - free(compressed_data); - return 0; - } - - memcpy(size_str, compressed_data, idx); - size_str[idx] = '\0'; - - char* end; - long size = strtol(size_str, &end, 10); - if (end == size_str || *end != '\0') { - perror("ERROR: invalid length in base_file_list"); - free(size_str); - free(compressed_data); - return 0; - } - - size_t offset = strlen(size_str) + 1; - free(size_str); - - char* basefile_content = calloc(size+1, sizeof(char)); - if (!basefile_content) { - free(compressed_data); - return 0; - } - - uLongf dest_len = (uLongf)size; - - int result = uncompress((unsigned char*)basefile_content, &dest_len, compressed_data+offset, compressed_size); - free(compressed_data); - - if (result != Z_OK) { - perror("ERROR: decompression of the base file list failed!"); - free(basefile_content); - return 0; - } - - basefile_content[dest_len] = '\0'; - - File* basefile = from_string(basefile_content); - char* modified_file_path = realpath(path, NULL); - File* modified_file = new_file(modified_file_path); - - ActionList* diff = myers_diff(basefile, modified_file, 0, 0); - if (diff->len == 0) { - free(basefile_content); - return 1; - } - +int save_file_diff(char* path, char* root, size_t diff_id, char* basefile_hash, ActionList* diff) { - for (size_t idx = 0; idx < diff->len; idx++) { - Action action = diff->actions[idx]; - if (action.type == INSERT) { - changes->insertions += 1; - } else if (action.type == DELETE) { - changes->deletions += 1; - } - } - save_diff(diff, path, root, diff_id, basefile_hash, modified_file, 0); - - free(basefile_content); return 1; }