summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2012-11-29 15:05:04 -0800
committerBen Straub <bs@github.com>2012-11-30 13:12:14 -0800
commit2f8d30becb4801d869188d2d46ca1512843e8698 (patch)
tree603ee4d64529de316e1c83914705e83d46b38cad
parent691776213947e59a3928aab09e97a64b65e990ab (diff)
downloadlibgit2-2f8d30becb4801d869188d2d46ca1512843e8698.tar.gz
Deploy GIT_DIFF_OPTIONS_INIT
-rw-r--r--examples/diff.c2
-rw-r--r--include/git2/diff.h2
-rw-r--r--src/checkout.c2
-rw-r--r--src/diff.c7
-rw-r--r--src/diff.h14
-rw-r--r--src/diff_output.c3
-rw-r--r--src/stash.c4
-rw-r--r--src/status.c3
-rw-r--r--src/submodule.c3
-rw-r--r--tests-clar/diff/blob.c24
-rw-r--r--tests-clar/diff/diff_helpers.h7
-rw-r--r--tests-clar/diff/diffiter.c30
-rw-r--r--tests-clar/diff/index.c25
-rw-r--r--tests-clar/diff/rename.c3
-rw-r--r--tests-clar/diff/tree.c34
-rw-r--r--tests-clar/diff/workdir.c38
16 files changed, 168 insertions, 33 deletions
diff --git a/examples/diff.c b/examples/diff.c
index a465182ba..b81a8682a 100644
--- a/examples/diff.c
+++ b/examples/diff.c
@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
{
git_repository *repo = NULL;
git_tree *t1 = NULL, *t2 = NULL;
- git_diff_options opts;
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
int i, color = -1, compact = 0, cached = 0;
char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 855e4beed..16a24b5f6 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -117,7 +117,7 @@ typedef struct {
} git_diff_options;
#define GIT_DIFF_OPTIONS_VERSION 1
-#define GIT_DIFF_OPTIONS_INIT = {GIT_DIFF_OPTIONS_VERSION, 0}
+#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION, 0}
/**
* The diff list object that contains all individual file deltas.
diff --git a/src/checkout.c b/src/checkout.c
index 2a7ad70be..06407bb30 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -622,7 +622,7 @@ int git_checkout_index(
git_checkout_opts *opts)
{
git_diff_list *diff = NULL;
- git_diff_options diff_opts = {0};
+ git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
git_checkout_opts checkout_opts;
checkout_diff_data data;
git_buf workdir = GIT_BUF_INIT;
diff --git a/src/diff.c b/src/diff.c
index 86f76f9c0..722acbead 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -755,14 +755,15 @@ fail:
return error;
}
-
#define DIFF_FROM_ITERATORS(MAKE_FIRST, MAKE_SECOND) do { \
git_iterator *a = NULL, *b = NULL; \
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
- if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
+ if (!git_diff__opts_has_valid_version(opts)) \
+ error = -1; \
+ else if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
error = diff_from_iterators(diff, repo, a, b, opts); \
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
- } while (0)
+} while (0)
int git_diff_tree_to_tree(
git_diff_list **diff,
diff --git a/src/diff.h b/src/diff.h
index 1e3be7593..1f45af1cd 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -61,5 +61,19 @@ extern bool git_diff_delta__should_skip(
extern int git_diff__oid_for_file(
git_repository *, const char *, uint16_t, git_off_t, git_oid *);
+
+GIT_INLINE(bool) git_diff__opts_has_valid_version(const git_diff_options *opts)
+{
+ if (!opts)
+ return true;
+
+ if (opts->version > 0 && opts->version <= GIT_DIFF_OPTIONS_VERSION)
+ return true;
+
+ giterr_set(GITERR_INVALID, "Invalid version %d in git_diff_options", opts->version);
+ return false;
+}
+
+
#endif
diff --git a/src/diff_output.c b/src/diff_output.c
index e137fd0f2..6316bfa1e 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -1266,6 +1266,9 @@ int git_diff_blobs(
git_diff_delta delta;
git_diff_patch patch;
+ if (!git_diff__opts_has_valid_version(options))
+ return -1;
+
if (options && (options->flags & GIT_DIFF_REVERSE)) {
git_blob *swap = old_blob;
old_blob = new_blob;
diff --git a/src/stash.c b/src/stash.c
index edd8c55db..261d3b199 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -229,7 +229,7 @@ static int build_untracked_tree(
{
git_tree *i_tree = NULL;
git_diff_list *diff = NULL;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
struct cb_data data = {0};
int error = -1;
@@ -315,7 +315,7 @@ static int build_workdir_tree(
git_repository *repo = git_index_owner(index);
git_tree *b_tree = NULL;
git_diff_list *diff = NULL, *diff2 = NULL;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
struct cb_data data = {0};
int error = -1;
diff --git a/src/status.c b/src/status.c
index c7dea2c71..ca500c5cb 100644
--- a/src/status.c
+++ b/src/status.c
@@ -108,7 +108,7 @@ int git_status_foreach_ext(
void *payload)
{
int err = 0;
- git_diff_options diffopt;
+ git_diff_options diffopt = GIT_DIFF_OPTIONS_INIT;
git_diff_list *idx2head = NULL, *wd2idx = NULL;
git_tree *head = NULL;
git_status_show_t show =
@@ -126,7 +126,6 @@ int git_status_foreach_ext(
!(err == GIT_ENOTFOUND || err == GIT_EORPHANEDHEAD))
return err;
- memset(&diffopt, 0, sizeof(diffopt));
memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
diffopt.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
diff --git a/src/submodule.c b/src/submodule.c
index c117255d4..7ac666c73 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1439,7 +1439,7 @@ static int submodule_wd_status(unsigned int *status, git_submodule *sm)
if (sm_repo != NULL) {
git_tree *sm_head;
- git_diff_options opt;
+ git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
/* the diffs below could be optimized with an early termination
@@ -1452,7 +1452,6 @@ static int submodule_wd_status(unsigned int *status, git_submodule *sm)
if ((error = git_repository_head_tree(&sm_head, sm_repo)) < 0)
return error;
- memset(&opt, 0, sizeof(opt));
if (sm->ignore == GIT_SUBMODULE_IGNORE_NONE)
opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
diff --git a/tests-clar/diff/blob.c b/tests-clar/diff/blob.c
index 6a5645d4b..ae3129c9f 100644
--- a/tests-clar/diff/blob.c
+++ b/tests-clar/diff/blob.c
@@ -12,7 +12,7 @@ void test_diff_blob__initialize(void)
g_repo = cl_git_sandbox_init("attr");
- memset(&opts, 0, sizeof(opts));
+ reset_diff_opts(&opts);
opts.context_lines = 1;
opts.interhunk_lines = 0;
@@ -313,3 +313,25 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
git_blob_free(old_d);
}
+
+void test_diff_blob__checks_options_version_too_low(void)
+{
+ const git_error *err;
+
+ opts.version = 0;
+ cl_git_fail(git_diff_blobs(
+ d, alien, &opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
+void test_diff_blob__checks_options_version_too_high(void)
+{
+ const git_error *err;
+
+ opts.version = 1024;
+ cl_git_fail(git_diff_blobs(
+ d, alien, &opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
diff --git a/tests-clar/diff/diff_helpers.h b/tests-clar/diff/diff_helpers.h
index 12591f63e..0f7c0e4f8 100644
--- a/tests-clar/diff/diff_helpers.h
+++ b/tests-clar/diff/diff_helpers.h
@@ -48,3 +48,10 @@ extern int diff_foreach_via_iterator(
void *data);
extern void diff_print(FILE *fp, git_diff_list *diff);
+
+
+GIT_INLINE(void) reset_diff_opts(git_diff_options *opts)
+{
+ git_diff_options init = GIT_DIFF_OPTIONS_INIT;
+ memmove(opts, &init, sizeof(init));
+}
diff --git a/tests-clar/diff/diffiter.c b/tests-clar/diff/diffiter.c
index 133392c21..306a13eb9 100644
--- a/tests-clar/diff/diffiter.c
+++ b/tests-clar/diff/diffiter.c
@@ -76,7 +76,7 @@ void test_diff_diffiter__iterate_files_2(void)
void test_diff_diffiter__iterate_files_and_hunks(void)
{
git_repository *repo = cl_git_sandbox_init("status");
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
size_t d, num_d;
int file_count = 0, hunk_count = 0;
@@ -129,7 +129,7 @@ void test_diff_diffiter__iterate_files_and_hunks(void)
void test_diff_diffiter__max_size_threshold(void)
{
git_repository *repo = cl_git_sandbox_init("status");
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
int file_count = 0, binary_count = 0, hunk_count = 0;
size_t d, num_d;
@@ -207,7 +207,7 @@ void test_diff_diffiter__max_size_threshold(void)
void test_diff_diffiter__iterate_all(void)
{
git_repository *repo = cl_git_sandbox_init("status");
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp = {0};
size_t d, num_d;
@@ -280,7 +280,7 @@ static void iterate_over_patch(git_diff_patch *patch, diff_expects *exp)
void test_diff_diffiter__iterate_randomly_while_saving_state(void)
{
git_repository *repo = cl_git_sandbox_init("status");
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp = {0};
git_diff_patch *patches[PATCH_CACHE];
@@ -441,3 +441,25 @@ void test_diff_diffiter__iterate_and_generate_patch_text(void)
git_diff_list_free(diff);
}
+
+void test_diff_diffiter__checks_options_version(void)
+{
+ git_repository *repo = cl_git_sandbox_init("status");
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+ const git_error *err;
+
+ opts.version = 0;
+ opts.flags |= GIT_DIFF_INCLUDE_IGNORED | GIT_DIFF_INCLUDE_UNTRACKED;
+
+ cl_git_fail(git_diff_workdir_to_index(&diff, repo, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ giterr_clear();
+ opts.version = 1024;
+ cl_git_fail(git_diff_workdir_to_index(&diff, repo, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
diff --git a/tests-clar/diff/index.c b/tests-clar/diff/index.c
index 9591e3457..267b3291c 100644
--- a/tests-clar/diff/index.c
+++ b/tests-clar/diff/index.c
@@ -20,7 +20,7 @@ void test_diff_index__0(void)
const char *b_commit = "0017bd4ab1ec3"; /* the start */
git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
@@ -113,7 +113,7 @@ void test_diff_index__1(void)
const char *b_commit = "0017bd4ab1ec3"; /* the start */
git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
git_tree *b = resolve_commit_oid_to_tree(g_repo, b_commit);
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
@@ -140,3 +140,24 @@ void test_diff_index__1(void)
git_tree_free(a);
git_tree_free(b);
}
+
+void test_diff_index__checks_options_version(void)
+{
+ const char *a_commit = "26a125ee1bf";
+ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit);
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff;
+ const git_error *err;
+
+ opts.version = 0;
+ cl_git_fail(git_diff_index_to_tree(&diff, g_repo, a, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ giterr_clear();
+ opts.version = 1024;
+ cl_git_fail(git_diff_index_to_tree(&diff, g_repo, a, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+}
+
diff --git a/tests-clar/diff/rename.c b/tests-clar/diff/rename.c
index 0d57f8ff0..18b7f7719 100644
--- a/tests-clar/diff/rename.c
+++ b/tests-clar/diff/rename.c
@@ -33,7 +33,7 @@ void test_diff_rename__match_oid(void)
const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
git_tree *old_tree, *new_tree;
git_diff_list *diff;
- git_diff_options diffopts = {0};
+ git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
git_diff_find_options opts;
diff_expects exp;
@@ -43,7 +43,6 @@ void test_diff_rename__match_oid(void)
/* Must pass GIT_DIFF_INCLUDE_UNMODIFIED if you expect to emulate
* --find-copies-harder during rename transformion...
*/
- memset(&diffopts, 0, sizeof(diffopts));
diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
cl_git_pass(git_diff_tree_to_tree(
diff --git a/tests-clar/diff/tree.c b/tests-clar/diff/tree.c
index 58dc4e6fa..442e53b25 100644
--- a/tests-clar/diff/tree.c
+++ b/tests-clar/diff/tree.c
@@ -19,7 +19,7 @@ void test_diff_tree__0(void)
const char *b_commit = "370fe9ec22";
const char *c_commit = "f5b0af1fb4f5c";
git_tree *a, *b, *c;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
@@ -175,7 +175,7 @@ void test_diff_tree__bare(void)
const char *a_commit = "8496071c1b46c85";
const char *b_commit = "be3563ae3f79";
git_tree *a, *b;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
@@ -264,7 +264,7 @@ void test_diff_tree__larger_hunks(void)
const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
git_tree *a, *b;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
size_t d, num_d, h, num_h, l, num_l, header_len, line_len;
const git_diff_delta *delta;
@@ -319,3 +319,31 @@ void test_diff_tree__larger_hunks(void)
git_tree_free(a);
git_tree_free(b);
}
+
+void test_diff_tree__checks_options_version(void)
+{
+ const char *a_commit = "8496071c1b46c85";
+ const char *b_commit = "be3563ae3f79";
+ git_tree *a, *b;
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_list *diff = NULL;
+ const git_error *err;
+
+ g_repo = cl_git_sandbox_init("testrepo.git");
+
+ cl_assert((a = resolve_commit_oid_to_tree(g_repo, a_commit)) != NULL);
+ cl_assert((b = resolve_commit_oid_to_tree(g_repo, b_commit)) != NULL);
+
+ opts.version = 0;
+ cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ giterr_clear();
+ opts.version = 1024;
+ cl_git_fail(git_diff_tree_to_tree(&diff, g_repo, a, b, &opts));
+ err = giterr_last();
+
+ git_tree_free(a);
+ git_tree_free(b);
+}
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 57c88c3e5..10d58b118 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -15,7 +15,7 @@ void test_diff_workdir__cleanup(void)
void test_diff_workdir__to_index(void)
{
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
int use_iterator;
@@ -69,7 +69,7 @@ void test_diff_workdir__to_tree(void)
const char *a_commit = "26a125ee1bf"; /* the current HEAD */
const char *b_commit = "0017bd4ab1ec3"; /* the start */
git_tree *a, *b;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
git_diff_list *diff2 = NULL;
diff_expects exp;
@@ -202,7 +202,7 @@ void test_diff_workdir__to_tree(void)
void test_diff_workdir__to_index_with_pathspec(void)
{
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
char *pathspec = NULL;
@@ -420,7 +420,7 @@ void test_diff_workdir__filemode_changes_with_filemode_false(void)
void test_diff_workdir__head_index_and_workdir_all_differ(void)
{
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff_i2t = NULL, *diff_w2i = NULL;
diff_expects exp;
char *pathspec = "staged_changes_modified_file";
@@ -518,7 +518,7 @@ void test_diff_workdir__head_index_and_workdir_all_differ(void)
void test_diff_workdir__eof_newline_changes(void)
{
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
char *pathspec = "current_file";
@@ -678,7 +678,7 @@ void test_diff_workdir__larger_hunks(void)
const char *a_commit = "d70d245ed97ed2aa596dd1af6536e4bfdb047b69";
const char *b_commit = "7a9e0b02e63179929fed24f0a3e0f19168114d10";
git_tree *a, *b;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
size_t i, d, num_d, h, num_h, l, num_l, header_len, line_len;
g_repo = cl_git_sandbox_init("diff");
@@ -763,7 +763,7 @@ void test_diff_workdir__submodules(void)
{
const char *a_commit = "873585b94bdeabccea991ea5e3ec1a277895b698";
git_tree *a;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
diff_expects exp;
@@ -822,7 +822,7 @@ void test_diff_workdir__submodules(void)
void test_diff_workdir__cannot_diff_against_a_bare_repository(void)
{
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff = NULL;
git_tree *tree;
@@ -843,7 +843,7 @@ void test_diff_workdir__to_null_tree(void)
{
git_diff_list *diff;
diff_expects exp;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
opts.flags = GIT_DIFF_INCLUDE_UNTRACKED |
GIT_DIFF_RECURSE_UNTRACKED_DIRS;
@@ -861,3 +861,23 @@ void test_diff_workdir__to_null_tree(void)
git_diff_list_free(diff);
}
+
+void test_diff_workdir__checks_options_version(void)
+{
+ git_diff_list *diff;
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
+ const git_error *err;
+
+ g_repo = cl_git_sandbox_init("status");
+
+ opts.version = 0;
+ cl_git_fail(git_diff_workdir_to_tree(&diff, g_repo, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ giterr_clear();
+ opts.version = 1024;
+ cl_git_fail(git_diff_workdir_to_tree(&diff, g_repo, NULL, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+}