Commit 0f4b2f02 by Edward Thomson

reader: optionally validate index matches workdir

When using a workdir reader, optionally validate that the index contents
match the working directory contents.
parent 3b674660
...@@ -661,7 +661,7 @@ int git_apply( ...@@ -661,7 +661,7 @@ int git_apply(
* in the index. * in the index.
*/ */
if (opts.location == GIT_APPLY_LOCATION_WORKDIR) 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 else
error = git_reader_for_index(&pre_reader, repo, NULL); error = git_reader_for_index(&pre_reader, repo, NULL);
......
...@@ -74,6 +74,7 @@ int git_reader_for_tree(git_reader **out, git_tree *tree) ...@@ -74,6 +74,7 @@ int git_reader_for_tree(git_reader **out, git_tree *tree)
typedef struct { typedef struct {
git_reader reader; git_reader reader;
git_repository *repo; git_repository *repo;
git_index *index;
} workdir_reader; } workdir_reader;
static int workdir_reader_read( static int workdir_reader_read(
...@@ -84,6 +85,8 @@ static int workdir_reader_read( ...@@ -84,6 +85,8 @@ static int workdir_reader_read(
{ {
workdir_reader *reader = (workdir_reader *)_reader; workdir_reader *reader = (workdir_reader *)_reader;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
const git_index_entry *idx_entry;
git_oid id;
int error; int error;
if ((error = git_buf_joinpath(&path, if ((error = git_buf_joinpath(&path,
...@@ -94,8 +97,21 @@ static int workdir_reader_read( ...@@ -94,8 +97,21 @@ static int workdir_reader_read(
if ((error = git_futils_readbuffer(out, path.ptr)) < 0) if ((error = git_futils_readbuffer(out, path.ptr)) < 0)
goto done; 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) if (out_id)
error = git_odb_hash(out_id, out->ptr, out->size, GIT_OBJ_BLOB); git_oid_cpy(out_id, &id);
done: done:
git_buf_dispose(&path); git_buf_dispose(&path);
...@@ -107,9 +123,13 @@ static void workdir_reader_free(git_reader *_reader) ...@@ -107,9 +123,13 @@ static void workdir_reader_free(git_reader *_reader)
GIT_UNUSED(_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; workdir_reader *reader;
int error;
assert(out && repo); assert(out && repo);
...@@ -120,6 +140,12 @@ int git_reader_for_workdir(git_reader **out, git_repository *repo) ...@@ -120,6 +140,12 @@ int git_reader_for_workdir(git_reader **out, git_repository *repo)
reader->reader.free = workdir_reader_free; reader->reader.free = workdir_reader_free;
reader->repo = repo; reader->repo = repo;
if (validate_index &&
(error = git_repository_index__weakptr(&reader->index, repo)) < 0) {
git__free(reader);
return error;
}
*out = (git_reader *)reader; *out = (git_reader *)reader;
return 0; return 0;
} }
...@@ -183,14 +209,10 @@ int git_reader_for_index( ...@@ -183,14 +209,10 @@ int git_reader_for_index(
if (index) { if (index) {
reader->index = index; reader->index = index;
} else { } else if ((error = git_repository_index__weakptr(&reader->index, repo)) < 0) {
error = git_repository_index__weakptr(&reader->index, repo);
if (error < 0) {
git__free(reader); git__free(reader);
return error; return error;
} }
}
*out = (git_reader *)reader; *out = (git_reader *)reader;
return 0; return 0;
......
...@@ -9,6 +9,9 @@ ...@@ -9,6 +9,9 @@
#include "common.h" #include "common.h"
/* Returned when the workdir does not match the index */
#define GIT_READER_MISMATCH 1
typedef struct git_reader git_reader; typedef struct git_reader git_reader;
/* /*
...@@ -76,7 +79,8 @@ extern int git_reader_for_index( ...@@ -76,7 +79,8 @@ extern int git_reader_for_index(
*/ */
extern int git_reader_for_workdir( extern int git_reader_for_workdir(
git_reader **out, git_reader **out,
git_repository *repo); git_repository *repo,
bool validate_index);
/** /**
* Read the given filename from the reader and populate the given buffer * Read the given filename from the reader and populate the given buffer
......
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