mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 23:44:06 +00:00
Fix possible segfaults in src/tree.c (issue 1)
git_tree_entry_byname was dereferencing a NULL pointer when the searched file couldn't be found on the tree. New test cases have been added to check for entry access methods. Signed-off-by: Vicent Marti <tanoku@gmail.com>
This commit is contained in:
parent
2a884588b4
commit
c4b5bedc97
21
src/tree.c
21
src/tree.c
@ -124,26 +124,36 @@ unsigned int git_tree_entry_attributes(git_tree_entry *entry)
|
|||||||
|
|
||||||
const char *git_tree_entry_name(git_tree_entry *entry)
|
const char *git_tree_entry_name(git_tree_entry *entry)
|
||||||
{
|
{
|
||||||
|
assert(entry);
|
||||||
return entry->filename;
|
return entry->filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
const git_oid *git_tree_entry_id(git_tree_entry *entry)
|
const git_oid *git_tree_entry_id(git_tree_entry *entry)
|
||||||
{
|
{
|
||||||
|
assert(entry);
|
||||||
return &entry->oid;
|
return &entry->oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_object *git_tree_entry_2object(git_tree_entry *entry)
|
git_object *git_tree_entry_2object(git_tree_entry *entry)
|
||||||
{
|
{
|
||||||
|
assert(entry);
|
||||||
return git_repository_lookup(entry->owner->object.repo, &entry->oid, GIT_OBJ_ANY);
|
return git_repository_lookup(entry->owner->object.repo, &entry->oid, GIT_OBJ_ANY);
|
||||||
}
|
}
|
||||||
|
|
||||||
git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
|
git_tree_entry *git_tree_entry_byname(git_tree *tree, const char *filename)
|
||||||
{
|
{
|
||||||
return *(git_tree_entry **)bsearch(filename, tree->entries, tree->entry_count, sizeof(git_tree_entry *), entry_cmp);
|
git_tree_entry **found;
|
||||||
|
|
||||||
|
assert(tree && filename);
|
||||||
|
|
||||||
|
found = bsearch(filename, tree->entries, tree->entry_count, sizeof(git_tree_entry *), entry_cmp);
|
||||||
|
return found ? *found : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_tree_entry *git_tree_entry_byindex(git_tree *tree, int idx)
|
git_tree_entry *git_tree_entry_byindex(git_tree *tree, int idx)
|
||||||
{
|
{
|
||||||
|
assert(tree);
|
||||||
|
|
||||||
if (tree->entries == NULL)
|
if (tree->entries == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -152,6 +162,7 @@ git_tree_entry *git_tree_entry_byindex(git_tree *tree, int idx)
|
|||||||
|
|
||||||
size_t git_tree_entrycount(git_tree *tree)
|
size_t git_tree_entrycount(git_tree *tree)
|
||||||
{
|
{
|
||||||
|
assert(tree);
|
||||||
return tree->entry_count;
|
return tree->entry_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +170,8 @@ void git_tree_add_entry(git_tree *tree, const git_oid *id, const char *filename,
|
|||||||
{
|
{
|
||||||
git_tree_entry *entry;
|
git_tree_entry *entry;
|
||||||
|
|
||||||
|
assert(tree && id && filename);
|
||||||
|
|
||||||
if (tree->entry_count >= tree->array_size)
|
if (tree->entry_count >= tree->array_size)
|
||||||
resize_tree_array(tree);
|
resize_tree_array(tree);
|
||||||
|
|
||||||
@ -182,6 +195,8 @@ int git_tree_remove_entry_byindex(git_tree *tree, int idx)
|
|||||||
{
|
{
|
||||||
git_tree_entry *remove_ptr;
|
git_tree_entry *remove_ptr;
|
||||||
|
|
||||||
|
assert(tree);
|
||||||
|
|
||||||
if (idx < 0 || idx >= (int)tree->entry_count)
|
if (idx < 0 || idx >= (int)tree->entry_count)
|
||||||
return GIT_ENOTFOUND;
|
return GIT_ENOTFOUND;
|
||||||
|
|
||||||
@ -200,6 +215,8 @@ int git_tree_remove_entry_byname(git_tree *tree, const char *filename)
|
|||||||
git_tree_entry **entry_ptr;
|
git_tree_entry **entry_ptr;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
|
assert(tree && filename);
|
||||||
|
|
||||||
entry_ptr = bsearch(filename, tree->entries, tree->entry_count, sizeof(git_tree_entry *), entry_cmp);
|
entry_ptr = bsearch(filename, tree->entries, tree->entry_count, sizeof(git_tree_entry *), entry_cmp);
|
||||||
if (entry_ptr == NULL)
|
if (entry_ptr == NULL)
|
||||||
return GIT_ENOTFOUND;
|
return GIT_ENOTFOUND;
|
||||||
@ -212,6 +229,8 @@ int git_tree__writeback(git_tree *tree, git_odb_source *src)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
assert(tree && src);
|
||||||
|
|
||||||
if (tree->entries == NULL)
|
if (tree->entries == NULL)
|
||||||
return GIT_ERROR;
|
return GIT_ERROR;
|
||||||
|
|
||||||
|
@ -9,6 +9,34 @@
|
|||||||
static const char *odb_dir = "../resources/sample-odb";
|
static const char *odb_dir = "../resources/sample-odb";
|
||||||
static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
|
static const char *tree_oid = "1810dff58d8a660512d4832e740f692884338ccd";
|
||||||
|
|
||||||
|
BEGIN_TEST(tree_entry_access_test)
|
||||||
|
git_odb *db;
|
||||||
|
git_oid id;
|
||||||
|
git_repository *repo;
|
||||||
|
git_tree *tree;
|
||||||
|
|
||||||
|
must_pass(git_odb_open(&db, odb_dir));
|
||||||
|
|
||||||
|
repo = git_repository_alloc(db);
|
||||||
|
must_be_true(repo != NULL);
|
||||||
|
|
||||||
|
git_oid_mkstr(&id, tree_oid);
|
||||||
|
|
||||||
|
tree = git_tree_lookup(repo, &id);
|
||||||
|
must_be_true(tree != NULL);
|
||||||
|
|
||||||
|
must_be_true(git_tree_entry_byname(tree, "README") != NULL);
|
||||||
|
must_be_true(git_tree_entry_byname(tree, "NOTEXISTS") == NULL);
|
||||||
|
must_be_true(git_tree_entry_byname(tree, "") == NULL);
|
||||||
|
must_be_true(git_tree_entry_byindex(tree, 0) != NULL);
|
||||||
|
must_be_true(git_tree_entry_byindex(tree, 2) != NULL);
|
||||||
|
must_be_true(git_tree_entry_byindex(tree, 3) == NULL);
|
||||||
|
must_be_true(git_tree_entry_byindex(tree, -1) == NULL);
|
||||||
|
|
||||||
|
git_repository_free(repo);
|
||||||
|
git_odb_close(db);
|
||||||
|
END_TEST
|
||||||
|
|
||||||
BEGIN_TEST(tree_read_test)
|
BEGIN_TEST(tree_read_test)
|
||||||
git_odb *db;
|
git_odb *db;
|
||||||
git_oid id;
|
git_oid id;
|
||||||
@ -26,8 +54,6 @@ BEGIN_TEST(tree_read_test)
|
|||||||
tree = git_tree_lookup(repo, &id);
|
tree = git_tree_lookup(repo, &id);
|
||||||
must_be_true(tree != NULL);
|
must_be_true(tree != NULL);
|
||||||
|
|
||||||
must_pass(git_tree__parse(tree));
|
|
||||||
|
|
||||||
must_be_true(git_tree_entrycount(tree) == 3);
|
must_be_true(git_tree_entrycount(tree) == 3);
|
||||||
|
|
||||||
entry = git_tree_entry_byname(tree, "README");
|
entry = git_tree_entry_byname(tree, "README");
|
||||||
|
Loading…
Reference in New Issue
Block a user