Deploy GIT_DIFF_FIND_OPTIONS_INIT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 987d4b8..1df0410 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -168,6 +168,18 @@ int git_diff_merge(
return error;
}
+static bool find_opts_has_valid_version(const git_diff_find_options *opts)
+{
+ if (!opts)
+ return true;
+
+ if (opts->version > 0 && opts->version <= GIT_DIFF_FIND_OPTIONS_VERSION)
+ return true;
+
+ giterr_set(GITERR_INVALID, "Invalid version %d on git_diff_find_options", opts->version);
+ return false;
+}
+
#define DEFAULT_THRESHOLD 50
#define DEFAULT_BREAK_REWRITE_THRESHOLD 60
#define DEFAULT_TARGET_LIMIT 200
@@ -187,7 +199,8 @@ static int normalize_find_opts(
if (given != NULL)
memcpy(opts, given, sizeof(*opts));
else {
- memset(opts, 0, sizeof(*opts));
+ git_diff_find_options init = GIT_DIFF_FIND_OPTIONS_INIT;
+ memmove(opts, &init, sizeof(init));
opts->flags = GIT_DIFF_FIND_RENAMES;
@@ -198,6 +211,9 @@ static int normalize_find_opts(
opts->flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
}
+ if (!find_opts_has_valid_version(opts))
+ return -1;
+
/* some flags imply others */
if (opts->flags & GIT_DIFF_FIND_RENAMES_FROM_REWRITES)
diff --git a/tests-clar/diff/rename.c b/tests-clar/diff/rename.c
index 18b7f77..2995b4e 100644
--- a/tests-clar/diff/rename.c
+++ b/tests-clar/diff/rename.c
@@ -34,7 +34,7 @@ void test_diff_rename__match_oid(void)
git_tree *old_tree, *new_tree;
git_diff_list *diff;
git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
- git_diff_find_options opts;
+ git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
diff_expects exp;
old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
@@ -84,7 +84,6 @@ void test_diff_rename__match_oid(void)
* 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
* 2bc7f351d20b53f1c72c16c4b036e491c478c49a
*/
- memset(&opts, 0, sizeof(opts));
opts.flags = GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED;
cl_git_pass(git_diff_find_similar(diff, &opts));
@@ -102,3 +101,35 @@ void test_diff_rename__match_oid(void)
git_tree_free(old_tree);
git_tree_free(new_tree);
}
+
+void test_diff_rename__checks_options_version(void)
+{
+ const char *old_sha = "31e47d8c1fa36d7f8d537b96158e3f024de0a9f2";
+ const char *new_sha = "2bc7f351d20b53f1c72c16c4b036e491c478c49a";
+ git_tree *old_tree, *new_tree;
+ git_diff_list *diff;
+ git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
+ git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
+ const git_error *err;
+
+ old_tree = resolve_commit_oid_to_tree(g_repo, old_sha);
+ new_tree = resolve_commit_oid_to_tree(g_repo, new_sha);
+ diffopts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
+ cl_git_pass(git_diff_tree_to_tree(
+ &diff, g_repo, old_tree, new_tree, &diffopts));
+
+ opts.version = 0;
+ cl_git_fail(git_diff_find_similar(diff, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ giterr_clear();
+ opts.version = 1024;
+ cl_git_fail(git_diff_find_similar(diff, &opts));
+ err = giterr_last();
+ cl_assert_equal_i(GITERR_INVALID, err->klass);
+
+ git_diff_list_free(diff);
+ git_tree_free(old_tree);
+ git_tree_free(new_tree);
+}