diff options
author | Edward Thomson <ethomson@github.com> | 2016-02-23 18:29:16 -0500 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-02-28 18:54:39 -0500 |
commit | 6ddf533afca5e25b7c532b4c164ae66e06f9c1c2 (patch) | |
tree | 8b712ec3334211e5d391b3933ce5897ebd627695 /src/index.c | |
parent | 2bbc7d3e564ed262e9555ea4fd081ece5ceb3bff (diff) | |
download | libgit2-6ddf533afca5e25b7c532b4c164ae66e06f9c1c2.tar.gz |
git_index_add: validate objects in index entries (optionally)
When `GIT_OPT_ENABLE_STRICT_OBJECT_CREATION` is turned on, validate
the index entries given to `git_index_add`.
Diffstat (limited to 'src/index.c')
-rw-r--r-- | src/index.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/src/index.c b/src/index.c index 5704432ae..b97f8091d 100644 --- a/src/index.c +++ b/src/index.c @@ -1245,17 +1245,22 @@ static void index_existing_and_best( * it, then it will return an error **and also free the entry**. When * it replaces an existing entry, it will update the entry_ptr with the * actual entry in the index (and free the passed in one). + * * trust_path is whether we use the given path, or whether (on case * insensitive systems only) we try to canonicalize the given path to * be within an existing directory. + * * trust_mode is whether we trust the mode in entry_ptr. + * + * trust_id is whether we trust the id or it should be validated. */ static int index_insert( git_index *index, git_index_entry **entry_ptr, int replace, bool trust_path, - bool trust_mode) + bool trust_mode, + bool trust_id) { int error = 0; size_t path_length, position; @@ -1288,6 +1293,15 @@ static int index_insert( if (!trust_path) error = canonicalize_directory_path(index, entry, best); + /* ensure that the given id exists (unless it's a submodule) */ + if (!error && !trust_id && INDEX_OWNER(index) && + (entry->mode & GIT_FILEMODE_COMMIT) != GIT_FILEMODE_COMMIT) { + + if (!git_object__is_valid(INDEX_OWNER(index), &entry->id, + git_object__type_from_filemode(entry->mode))) + error = -1; + } + /* look for tree / blob name collisions, removing conflicts if requested */ if (!error) error = check_file_directory_collision(index, entry, position, replace); @@ -1395,7 +1409,7 @@ int git_index_add_frombuffer( git_oid_cpy(&entry->id, &id); entry->file_size = len; - if ((error = index_insert(index, &entry, 1, true, true)) < 0) + if ((error = index_insert(index, &entry, 1, true, true, true)) < 0) return error; /* Adding implies conflict was resolved, move conflict entries to REUC */ @@ -1454,7 +1468,7 @@ int git_index_add_bypath(git_index *index, const char *path) assert(index && path); if ((ret = index_entry_init(&entry, index, path)) == 0) - ret = index_insert(index, &entry, 1, false, false); + ret = index_insert(index, &entry, 1, false, false, true); /* If we were given a directory, let's see if it's a submodule */ if (ret < 0 && ret != GIT_EDIRECTORY) @@ -1480,7 +1494,7 @@ int git_index_add_bypath(git_index *index, const char *path) if ((ret = add_repo_as_submodule(&entry, index, path)) < 0) return ret; - if ((ret = index_insert(index, &entry, 1, false, false)) < 0) + if ((ret = index_insert(index, &entry, 1, false, false, true)) < 0) return ret; } else if (ret < 0) { return ret; @@ -1569,7 +1583,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry) } if ((ret = index_entry_dup(&entry, index, source_entry)) < 0 || - (ret = index_insert(index, &entry, 1, true, true)) < 0) + (ret = index_insert(index, &entry, 1, true, true, false)) < 0) return ret; git_tree_cache_invalidate_path(index->tree, entry->path); @@ -1731,7 +1745,7 @@ int git_index_conflict_add(git_index *index, /* Make sure stage is correct */ GIT_IDXENTRY_STAGE_SET(entries[i], i + 1); - if ((ret = index_insert(index, &entries[i], 1, true, true)) < 0) + if ((ret = index_insert(index, &entries[i], 1, true, true, false)) < 0) goto on_error; entries[i] = NULL; /* don't free if later entry fails */ |