Skip to content

Commit 2f8d30b

Browse files
committed
Deploy GIT_DIFF_OPTIONS_INIT
1 parent 6917762 commit 2f8d30b

File tree

16 files changed

+168
-33
lines changed

16 files changed

+168
-33
lines changed

examples/diff.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ int main(int argc, char *argv[])
133133
{
134134
git_repository *repo = NULL;
135135
git_tree *t1 = NULL, *t2 = NULL;
136-
git_diff_options opts;
136+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
137137
git_diff_list *diff;
138138
int i, color = -1, compact = 0, cached = 0;
139139
char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;

include/git2/diff.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ typedef struct {
117117
} git_diff_options;
118118

119119
#define GIT_DIFF_OPTIONS_VERSION 1
120-
#define GIT_DIFF_OPTIONS_INIT = {GIT_DIFF_OPTIONS_VERSION, 0}
120+
#define GIT_DIFF_OPTIONS_INIT {GIT_DIFF_OPTIONS_VERSION, 0}
121121

122122
/**
123123
* The diff list object that contains all individual file deltas.

src/checkout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ int git_checkout_index(
622622
git_checkout_opts *opts)
623623
{
624624
git_diff_list *diff = NULL;
625-
git_diff_options diff_opts = {0};
625+
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
626626
git_checkout_opts checkout_opts;
627627
checkout_diff_data data;
628628
git_buf workdir = GIT_BUF_INIT;

src/diff.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,14 +755,15 @@ static int diff_from_iterators(
755755
return error;
756756
}
757757

758-
759758
#define DIFF_FROM_ITERATORS(MAKE_FIRST, MAKE_SECOND) do { \
760759
git_iterator *a = NULL, *b = NULL; \
761760
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
762-
if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
761+
if (!git_diff__opts_has_valid_version(opts)) \
762+
error = -1; \
763+
else if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
763764
error = diff_from_iterators(diff, repo, a, b, opts); \
764765
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
765-
} while (0)
766+
} while (0)
766767

767768
int git_diff_tree_to_tree(
768769
git_diff_list **diff,

src/diff.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,19 @@ extern bool git_diff_delta__should_skip(
6161
extern int git_diff__oid_for_file(
6262
git_repository *, const char *, uint16_t, git_off_t, git_oid *);
6363

64+
65+
GIT_INLINE(bool) git_diff__opts_has_valid_version(const git_diff_options *opts)
66+
{
67+
if (!opts)
68+
return true;
69+
70+
if (opts->version > 0 && opts->version <= GIT_DIFF_OPTIONS_VERSION)
71+
return true;
72+
73+
giterr_set(GITERR_INVALID, "Invalid version %d in git_diff_options", opts->version);
74+
return false;
75+
}
76+
77+
6478
#endif
6579

src/diff_output.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,6 +1266,9 @@ int git_diff_blobs(
12661266
git_diff_delta delta;
12671267
git_diff_patch patch;
12681268

1269+
if (!git_diff__opts_has_valid_version(options))
1270+
return -1;
1271+
12691272
if (options && (options->flags & GIT_DIFF_REVERSE)) {
12701273
git_blob *swap = old_blob;
12711274
old_blob = new_blob;

src/stash.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ static int build_untracked_tree(
229229
{
230230
git_tree *i_tree = NULL;
231231
git_diff_list *diff = NULL;
232-
git_diff_options opts = {0};
232+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
233233
struct cb_data data = {0};
234234
int error = -1;
235235

@@ -315,7 +315,7 @@ static int build_workdir_tree(
315315
git_repository *repo = git_index_owner(index);
316316
git_tree *b_tree = NULL;
317317
git_diff_list *diff = NULL, *diff2 = NULL;
318-
git_diff_options opts = {0};
318+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
319319
struct cb_data data = {0};
320320
int error = -1;
321321

src/status.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ int git_status_foreach_ext(
108108
void *payload)
109109
{
110110
int err = 0;
111-
git_diff_options diffopt;
111+
git_diff_options diffopt = GIT_DIFF_OPTIONS_INIT;
112112
git_diff_list *idx2head = NULL, *wd2idx = NULL;
113113
git_tree *head = NULL;
114114
git_status_show_t show =
@@ -126,7 +126,6 @@ int git_status_foreach_ext(
126126
!(err == GIT_ENOTFOUND || err == GIT_EORPHANEDHEAD))
127127
return err;
128128

129-
memset(&diffopt, 0, sizeof(diffopt));
130129
memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
131130

132131
diffopt.flags = GIT_DIFF_INCLUDE_TYPECHANGE;

src/submodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,7 @@ static int submodule_wd_status(unsigned int *status, git_submodule *sm)
14391439

14401440
if (sm_repo != NULL) {
14411441
git_tree *sm_head;
1442-
git_diff_options opt;
1442+
git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
14431443
git_diff_list *diff;
14441444

14451445
/* 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)
14521452
if ((error = git_repository_head_tree(&sm_head, sm_repo)) < 0)
14531453
return error;
14541454

1455-
memset(&opt, 0, sizeof(opt));
14561455
if (sm->ignore == GIT_SUBMODULE_IGNORE_NONE)
14571456
opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
14581457

tests-clar/diff/blob.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void test_diff_blob__initialize(void)
1212

1313
g_repo = cl_git_sandbox_init("attr");
1414

15-
memset(&opts, 0, sizeof(opts));
15+
reset_diff_opts(&opts);
1616
opts.context_lines = 1;
1717
opts.interhunk_lines = 0;
1818

@@ -313,3 +313,25 @@ void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
313313

314314
git_blob_free(old_d);
315315
}
316+
317+
void test_diff_blob__checks_options_version_too_low(void)
318+
{
319+
const git_error *err;
320+
321+
opts.version = 0;
322+
cl_git_fail(git_diff_blobs(
323+
d, alien, &opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
324+
err = giterr_last();
325+
cl_assert_equal_i(GITERR_INVALID, err->klass);
326+
}
327+
328+
void test_diff_blob__checks_options_version_too_high(void)
329+
{
330+
const git_error *err;
331+
332+
opts.version = 1024;
333+
cl_git_fail(git_diff_blobs(
334+
d, alien, &opts, diff_file_cb, diff_hunk_cb, diff_line_cb, &expected));
335+
err = giterr_last();
336+
cl_assert_equal_i(GITERR_INVALID, err->klass);
337+
}

0 commit comments

Comments
 (0)