fix(commit): leak proof now

This commit is contained in:
lisk77 2025-11-24 18:49:49 +01:00
parent fae8489871
commit bb1e99406f
2 changed files with 125 additions and 17 deletions

View file

@ -641,36 +641,141 @@ int commit(int argc, char** argv) {
char timestamp[20]; char timestamp[20];
snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL)); snprintf(timestamp, sizeof(timestamp), "%ld", time(NULL));
Author author = { Author* authors = calloc(1, sizeof(Author));
.name = strdup(config.user.name), if (!authors) {
.email = strdup(config.user.email), file_info_buffer_free(tree);
.timestamp = strdup(timestamp) free(commit_message);
}; list_free(files);
base_file_buffer_free(base_files);
free(branch);
free(root);
free_config(&config);
return 1;
}
if (log->len != 0) { authors[0].name = strdup(config.user.name);
char parent_hash[41]; authors[0].email = strdup(config.user.email);
snprintf(parent_hash, sizeof(parent_hash), "%s", ((Commit*)log->items + (log->len - 1))->hash); authors[0].timestamp = strdup(timestamp);
if (!authors[0].name || !authors[0].email || !authors[0].timestamp) {
free(authors[0].name);
free(authors[0].email);
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;
} }
char commit_hash_content[4096]; char commit_hash_content[4096];
int offset = 0; int offset = 0;
offset += snprintf(commit_hash_content + offset, sizeof(commit_hash_content) - offset, "tree %s\n", tree_hash); size_t remaining = sizeof(commit_hash_content);
if (log->len != 0) {
offset += snprintf(commit_hash_content + offset, sizeof(commit_hash_content) - offset, "parent %s\n", parent_hash); int written = snprintf(commit_hash_content + offset, remaining - offset, "tree %s\n", tree_hash);
if (written < 0 || (size_t)written >= remaining - offset) {
commit_log_free(log);
file_info_buffer_free(tree);
free(authors[0].name);
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;
} }
offset += snprintf(commit_hash_content + offset, sizeof(commit_hash_content) - offset, "author %s <%s> %s\n", author.name, author.email, author.timestamp); offset += written;
offset += snprintf(commit_hash_content + offset, sizeof(commit_hash_content) - offset, "committer %s <%s> %s\n", author.name, author.email, author.timestamp);
offset += snprintf(commit_hash_content + offset, sizeof(commit_hash_content) - offset, "message %s\n", commit_message); if (log->len != 0) {
written = snprintf(commit_hash_content + offset, remaining - offset, "parent %s\n", parent_hash);
if (written < 0 || (size_t)written >= remaining - offset) {
commit_log_free(log);
file_info_buffer_free(tree);
free(authors[0].name);
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;
}
offset += written;
}
written = snprintf(commit_hash_content + offset, remaining - offset, "author %s <%s> %s\n", authors[0].name, authors[0].email, authors[0].timestamp);
if (written < 0 || (size_t)written >= remaining - offset) {
commit_log_free(log);
file_info_buffer_free(tree);
free(authors[0].name);
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;
}
offset += written;
written = snprintf(commit_hash_content + offset, remaining - offset, "committer %s <%s> %s\n", authors[0].name, authors[0].email, authors[0].timestamp);
if (written < 0 || (size_t)written >= remaining - offset) {
commit_log_free(log);
file_info_buffer_free(tree);
free(authors[0].name);
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;
}
offset += written;
written = snprintf(commit_hash_content + offset, remaining - offset, "message %s\n", commit_message);
if (written < 0 || (size_t)written >= remaining - offset) {
commit_log_free(log);
file_info_buffer_free(tree);
free(authors[0].name);
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;
}
offset += written;
char commit_hash[41]; char commit_hash[41];
object_hash(LogObject, commit_hash_content, commit_hash); object_hash(LogObject, commit_hash_content, commit_hash);
Commit commit = { Commit commit = {
.hash = commit_hash, .hash = strdup(commit_hash),
.tree_hash = strdup(tree_hash), .tree_hash = strdup(tree_hash),
.authors = &author, .authors = authors,
.authors_count = 1, .authors_count = 1,
.committer = author, .committer = authors[0],
.message = strdup(commit_message) .message = strdup(commit_message)
}; };
@ -686,6 +791,7 @@ int commit(int argc, char** argv) {
free_config(&config); free_config(&config);
return 1; return 1;
} }
commit_log_free(log);
char ref_path[PATH_MAX]; char ref_path[PATH_MAX];
snprintf(ref_path, sizeof(ref_path), "%s/.merk/refs/branches/%s", root, branch); snprintf(ref_path, sizeof(ref_path), "%s/.merk/refs/branches/%s", root, branch);

View file

@ -19,11 +19,13 @@ void commit_log_free(CommitLog* log) {
for (size_t j = 0; j < commit->authors_count; j++) { for (size_t j = 0; j < commit->authors_count; j++) {
free(commit->authors[j].name); free(commit->authors[j].name);
free(commit->authors[j].email); free(commit->authors[j].email);
free(commit->authors[j].timestamp);
} }
free(commit->authors); free(commit->authors);
} }
free(commit->committer.name); free(commit->committer.name);
free(commit->committer.email); free(commit->committer.email);
free(commit->committer.timestamp);
free(commit->message); free(commit->message);
} }
free(log->items); free(log->items);