diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-07-01 15:13:50 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-11-05 15:53:34 +0000 |
commit | 0f4b2f028ab3a70b76b9bd67f073747df7078559 (patch) | |
tree | 89098564ae5bac37226d8504932b059e374d49ef | |
parent | 3b674660fe3f7c05359110007099ddf051caca7d (diff) | |
download | libgit2-0f4b2f028ab3a70b76b9bd67f073747df7078559.tar.gz |
reader: optionally validate index matches workdir
When using a workdir reader, optionally validate that the index contents
match the working directory contents.
-rw-r--r-- | src/apply.c | 2 | ||||
-rw-r--r-- | src/reader.c | 40 | ||||
-rw-r--r-- | src/reader.h | 6 |
3 files changed, 37 insertions, 11 deletions
diff --git a/src/apply.c b/src/apply.c index 0810c021c..d4c7dd0db 100644 --- a/src/apply.c +++ b/src/apply.c @@ -661,7 +661,7 @@ int git_apply( * in the index. */ if (opts.location == GIT_APPLY_LOCATION_WORKDIR) - error = git_reader_for_workdir(&pre_reader, repo); + error = git_reader_for_workdir(&pre_reader, repo, false); else error = git_reader_for_index(&pre_reader, repo, NULL); diff --git a/src/reader.c b/src/reader.c index 32900dfab..94faff701 100644 --- a/src/reader.c +++ b/src/reader.c @@ -74,6 +74,7 @@ int git_reader_for_tree(git_reader **out, git_tree *tree) typedef struct { git_reader reader; git_repository *repo; + git_index *index; } workdir_reader; static int workdir_reader_read( @@ -84,6 +85,8 @@ static int workdir_reader_read( { workdir_reader *reader = (workdir_reader *)_reader; git_buf path = GIT_BUF_INIT; + const git_index_entry *idx_entry; + git_oid id; int error; if ((error = git_buf_joinpath(&path, @@ -94,8 +97,21 @@ static int workdir_reader_read( if ((error = git_futils_readbuffer(out, path.ptr)) < 0) goto done; + if (out_id || reader->index) { + if ((error = git_odb_hash(&id, out->ptr, out->size, GIT_OBJ_BLOB)) < 0) + goto done; + } + + if (reader->index) { + if (!(idx_entry = git_index_get_bypath(reader->index, filename, 0)) || + !git_oid_equal(&id, &idx_entry->id)) { + error = GIT_READER_MISMATCH; + goto done; + } + } + if (out_id) - error = git_odb_hash(out_id, out->ptr, out->size, GIT_OBJ_BLOB); + git_oid_cpy(out_id, &id); done: git_buf_dispose(&path); @@ -107,9 +123,13 @@ static void workdir_reader_free(git_reader *_reader) GIT_UNUSED(_reader); } -int git_reader_for_workdir(git_reader **out, git_repository *repo) +int git_reader_for_workdir( + git_reader **out, + git_repository *repo, + bool validate_index) { workdir_reader *reader; + int error; assert(out && repo); @@ -120,6 +140,12 @@ int git_reader_for_workdir(git_reader **out, git_repository *repo) reader->reader.free = workdir_reader_free; reader->repo = repo; + if (validate_index && + (error = git_repository_index__weakptr(&reader->index, repo)) < 0) { + git__free(reader); + return error; + } + *out = (git_reader *)reader; return 0; } @@ -183,13 +209,9 @@ int git_reader_for_index( if (index) { reader->index = index; - } else { - error = git_repository_index__weakptr(&reader->index, repo); - - if (error < 0) { - git__free(reader); - return error; - } + } else if ((error = git_repository_index__weakptr(&reader->index, repo)) < 0) { + git__free(reader); + return error; } *out = (git_reader *)reader; diff --git a/src/reader.h b/src/reader.h index 7bb60e144..e1d906807 100644 --- a/src/reader.h +++ b/src/reader.h @@ -9,6 +9,9 @@ #include "common.h" +/* Returned when the workdir does not match the index */ +#define GIT_READER_MISMATCH 1 + typedef struct git_reader git_reader; /* @@ -76,7 +79,8 @@ extern int git_reader_for_index( */ extern int git_reader_for_workdir( git_reader **out, - git_repository *repo); + git_repository *repo, + bool validate_index); /** * Read the given filename from the reader and populate the given buffer |