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