Commit fd490d3e by Carlos Martín Nieto

tree: unify the entry validity checks

We have two similar functions, `git_treebuilder_insert` and `append_entry` which
are used in different codepaths as part of creating a new tree. The former
learnt to check for object existence under strict object creation, but the
latter did not.

This allowed the creation of a tree from an unowned index to bypass some of the
checks and create a tree pointing to a nonexistent object.

Extract a single function which performs these checks and call it from both
codepaths. In `append_entry` we still do not validate when asked not to, as this
is data which is already in the tree and we want to allow users to deal with
repositories which already have some invalid data.
parent fbc0dcda
...@@ -456,6 +456,36 @@ static size_t find_next_dir(const char *dirname, git_index *index, size_t start) ...@@ -456,6 +456,36 @@ static size_t find_next_dir(const char *dirname, git_index *index, size_t start)
return i; return i;
} }
static git_otype otype_from_mode(git_filemode_t filemode)
{
switch (filemode) {
case GIT_FILEMODE_TREE:
return GIT_OBJ_TREE;
case GIT_FILEMODE_COMMIT:
return GIT_OBJ_COMMIT;
default:
return GIT_OBJ_BLOB;
}
}
static int check_entry(git_repository *repo, const char *filename, const git_oid *id, git_filemode_t filemode)
{
if (!valid_filemode(filemode))
return tree_error("failed to insert entry: invalid filemode for file", filename);
if (!valid_entry_name(repo, filename))
return tree_error("failed to insert entry: invalid name for a tree entry", filename);
if (git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID", filename);
if (filemode != GIT_FILEMODE_COMMIT &&
!git_object__is_valid(repo, id, otype_from_mode(filemode)))
return tree_error("failed to insert entry: invalid object specified", filename);
return 0;
}
static int append_entry( static int append_entry(
git_treebuilder *bld, git_treebuilder *bld,
const char *filename, const char *filename,
...@@ -466,11 +496,8 @@ static int append_entry( ...@@ -466,11 +496,8 @@ static int append_entry(
git_tree_entry *entry; git_tree_entry *entry;
int error = 0; int error = 0;
if (validate && !valid_entry_name(bld->repo, filename)) if (validate && ((error = check_entry(bld->repo, filename, id, filemode)) < 0))
return tree_error("failed to insert entry: invalid name for a tree entry", filename); return error;
if (validate && git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID for a tree entry", filename);
entry = alloc_entry(filename, strlen(filename), id); entry = alloc_entry(filename, strlen(filename), id);
GITERR_CHECK_ALLOC(entry); GITERR_CHECK_ALLOC(entry);
...@@ -684,18 +711,6 @@ on_error: ...@@ -684,18 +711,6 @@ on_error:
return -1; return -1;
} }
static git_otype otype_from_mode(git_filemode_t filemode)
{
switch (filemode) {
case GIT_FILEMODE_TREE:
return GIT_OBJ_TREE;
case GIT_FILEMODE_COMMIT:
return GIT_OBJ_COMMIT;
default:
return GIT_OBJ_BLOB;
}
}
int git_treebuilder_insert( int git_treebuilder_insert(
const git_tree_entry **entry_out, const git_tree_entry **entry_out,
git_treebuilder *bld, git_treebuilder *bld,
...@@ -709,18 +724,8 @@ int git_treebuilder_insert( ...@@ -709,18 +724,8 @@ int git_treebuilder_insert(
assert(bld && id && filename); assert(bld && id && filename);
if (!valid_filemode(filemode)) if ((error = check_entry(bld->repo, filename, id, filemode)) < 0)
return tree_error("failed to insert entry: invalid filemode for file", filename); return error;
if (!valid_entry_name(bld->repo, filename))
return tree_error("failed to insert entry: invalid name for a tree entry", filename);
if (git_oid_iszero(id))
return tree_error("failed to insert entry: invalid null OID", filename);
if (filemode != GIT_FILEMODE_COMMIT &&
!git_object__is_valid(bld->repo, id, otype_from_mode(filemode)))
return tree_error("failed to insert entry: invalid object specified", filename);
pos = git_strmap_lookup_index(bld->map, filename); pos = git_strmap_lookup_index(bld->map, filename);
if (git_strmap_valid_index(bld->map, pos)) { if (git_strmap_valid_index(bld->map, pos)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment