mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 17:20:22 +00:00
Fix initialization of in-memory trees
In-memory tree objects were not being properly initialized, because the internal entries vector was created on the 'parse' method. Signed-off-by: Vicent Marti <tanoku@gmail.com>
This commit is contained in:
parent
e16c2f6a4c
commit
c8f5ff8f65
@ -379,31 +379,48 @@ git_odb *git_repository_database(git_repository *repo)
|
||||
return repo->db;
|
||||
}
|
||||
|
||||
int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type)
|
||||
static int create_object(git_object **object_out, git_otype type)
|
||||
{
|
||||
git_object *object = NULL;
|
||||
|
||||
assert(object_out && repo);
|
||||
assert(object_out);
|
||||
|
||||
*object_out = NULL;
|
||||
|
||||
switch (type) {
|
||||
case GIT_OBJ_COMMIT:
|
||||
case GIT_OBJ_TAG:
|
||||
case GIT_OBJ_TREE:
|
||||
case GIT_OBJ_BLOB:
|
||||
object = git__malloc(git_object__size(type));
|
||||
if (object == NULL)
|
||||
return GIT_ENOMEM;
|
||||
memset(object, 0x0, git_object__size(type));
|
||||
break;
|
||||
|
||||
case GIT_OBJ_TREE:
|
||||
object = (git_object *)git_tree__new();
|
||||
if (object == NULL)
|
||||
return GIT_ENOMEM;
|
||||
break;
|
||||
|
||||
default:
|
||||
return GIT_EINVALIDTYPE;
|
||||
}
|
||||
|
||||
object = git__malloc(git_object__size(type));
|
||||
*object_out = object;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (object == NULL)
|
||||
return GIT_ENOMEM;
|
||||
int git_repository_newobject(git_object **object_out, git_repository *repo, git_otype type)
|
||||
{
|
||||
git_object *object = NULL;
|
||||
int error;
|
||||
|
||||
assert(object_out && repo);
|
||||
|
||||
if ((error = create_object(&object, type)) < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
memset(object, 0x0, git_object__size(type));
|
||||
object->repo = repo;
|
||||
object->in_memory = 1;
|
||||
object->modified = 1;
|
||||
@ -439,12 +456,8 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
|
||||
|
||||
type = obj_file.type;
|
||||
|
||||
object = git__malloc(git_object__size(type));
|
||||
|
||||
if (object == NULL)
|
||||
return GIT_ENOMEM;
|
||||
|
||||
memset(object, 0x0, git_object__size(type));
|
||||
if ((error = create_object(&object, type)) < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
/* Initialize parent object */
|
||||
git_oid_cpy(&object->id, id);
|
||||
@ -453,7 +466,6 @@ int git_repository_lookup(git_object **object_out, git_repository *repo, const g
|
||||
object->source.open = 1;
|
||||
|
||||
switch (type) {
|
||||
|
||||
case GIT_OBJ_COMMIT:
|
||||
error = git_commit__parse((git_commit *)object);
|
||||
break;
|
||||
|
33
src/tree.c
33
src/tree.c
@ -30,6 +30,8 @@
|
||||
#include "git2/repository.h"
|
||||
#include "git2/object.h"
|
||||
|
||||
#define DEFAULT_TREE_SIZE 16
|
||||
|
||||
int entry_search_cmp(const void *key, const void *array_member)
|
||||
{
|
||||
const char *filename = (const char *)key;
|
||||
@ -46,7 +48,7 @@ int entry_sort_cmp(const void *a, const void *b)
|
||||
return strcmp(entry_a->filename, entry_b->filename);
|
||||
}
|
||||
|
||||
static void free_tree_entries(git_tree *tree)
|
||||
static void clear_entries(git_tree *tree)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -61,14 +63,35 @@ static void free_tree_entries(git_tree *tree)
|
||||
free(e);
|
||||
}
|
||||
|
||||
git_vector_free(&tree->entries);
|
||||
git_vector_clear(&tree->entries);
|
||||
}
|
||||
|
||||
|
||||
git_tree *git_tree__new(void)
|
||||
{
|
||||
git_tree *tree;
|
||||
|
||||
tree = git__malloc(sizeof(struct git_tree));
|
||||
if (tree == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(tree, 0x0, sizeof(struct git_tree));
|
||||
|
||||
if (git_vector_init(&tree->entries,
|
||||
DEFAULT_TREE_SIZE,
|
||||
entry_sort_cmp,
|
||||
entry_search_cmp) < GIT_SUCCESS) {
|
||||
free(tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
void git_tree__free(git_tree *tree)
|
||||
{
|
||||
free_tree_entries(tree);
|
||||
clear_entries(tree);
|
||||
git_vector_free(&tree->entries);
|
||||
free(tree);
|
||||
}
|
||||
|
||||
@ -243,9 +266,7 @@ static int tree_parse_buffer(git_tree *tree, char *buffer, char *buffer_end)
|
||||
|
||||
expected_size = (tree->object.source.raw.len / avg_entry_size) + 1;
|
||||
|
||||
free_tree_entries(tree);
|
||||
if (git_vector_init(&tree->entries, expected_size, entry_sort_cmp, entry_search_cmp) < GIT_SUCCESS)
|
||||
return GIT_ENOMEM;
|
||||
clear_entries(tree);
|
||||
|
||||
while (buffer < buffer_end) {
|
||||
git_tree_entry *entry;
|
||||
|
@ -19,6 +19,7 @@ struct git_tree {
|
||||
};
|
||||
|
||||
void git_tree__free(git_tree *tree);
|
||||
git_tree *git_tree__new(void);
|
||||
int git_tree__parse(git_tree *tree);
|
||||
int git_tree__writeback(git_tree *tree, git_odb_source *src);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user