Skip to content

Commit 92cdfd2

Browse files
committed
Merge branch 'jk/xdiff-memory-limits' into maint-2.3
2 parents f2df310 + 83c4d38 commit 92cdfd2

File tree

11 files changed

+57
-26
lines changed

11 files changed

+57
-26
lines changed

builtin/blame.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -972,7 +972,10 @@ static void pass_blame_to_parent(struct scoreboard *sb,
972972
fill_origin_blob(&sb->revs->diffopt, target, &file_o);
973973
num_get_patch++;
974974

975-
diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d);
975+
if (diff_hunks(&file_p, &file_o, 0, blame_chunk_cb, &d))
976+
die("unable to generate diff (%s -> %s)",
977+
sha1_to_hex(parent->commit->object.sha1),
978+
sha1_to_hex(target->commit->object.sha1));
976979
/* The rest are the same as the parent */
977980
blame_chunk(&d.dstq, &d.srcq, INT_MAX, d.offset, INT_MAX, parent);
978981
*d.dstq = NULL;
@@ -1118,7 +1121,9 @@ static void find_copy_in_blob(struct scoreboard *sb,
11181121
* file_p partially may match that image.
11191122
*/
11201123
memset(split, 0, sizeof(struct blame_entry [3]));
1121-
diff_hunks(file_p, &file_o, 1, handle_split_cb, &d);
1124+
if (diff_hunks(file_p, &file_o, 1, handle_split_cb, &d))
1125+
die("unable to generate diff (%s)",
1126+
sha1_to_hex(parent->commit->object.sha1));
11221127
/* remainder, if any, all match the preimage */
11231128
handle_split(sb, ent, d.tlno, d.plno, ent->num_lines, parent, split);
11241129
}

builtin/merge-file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix)
7575
names[i] = argv[i];
7676
if (read_mmfile(mmfs + i, fname))
7777
return -1;
78-
if (buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
78+
if (mmfs[i].size > MAX_XDIFF_SIZE ||
79+
buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
7980
return error("Cannot merge binary files: %s",
8081
argv[i]);
8182
}

builtin/merge-tree.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ static void show_diff(struct merge_list *entry)
118118
if (!dst.ptr)
119119
size = 0;
120120
dst.size = size;
121-
xdi_diff(&src, &dst, &xpp, &xecfg, &ecb);
121+
if (xdi_diff(&src, &dst, &xpp, &xecfg, &ecb))
122+
die("unable to generate diff");
122123
free(src.ptr);
123124
free(dst.ptr);
124125
}

builtin/rerere.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ static int diff_two(const char *file1, const char *label1,
2929
xdemitconf_t xecfg;
3030
xdemitcb_t ecb;
3131
mmfile_t minus, plus;
32+
int ret;
3233

3334
if (read_mmfile(&minus, file1) || read_mmfile(&plus, file2))
34-
return 1;
35+
return -1;
3536

3637
printf("--- a/%s\n+++ b/%s\n", label1, label2);
3738
fflush(stdout);
@@ -40,11 +41,11 @@ static int diff_two(const char *file1, const char *label1,
4041
memset(&xecfg, 0, sizeof(xecfg));
4142
xecfg.ctxlen = 3;
4243
ecb.outf = outf;
43-
xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
44+
ret = xdi_diff(&minus, &plus, &xpp, &xecfg, &ecb);
4445

4546
free(minus.ptr);
4647
free(plus.ptr);
47-
return 0;
48+
return ret;
4849
}
4950

5051
int cmd_rerere(int argc, const char **argv, const char *prefix)
@@ -104,7 +105,8 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
104105
for (i = 0; i < merge_rr.nr; i++) {
105106
const char *path = merge_rr.items[i].string;
106107
const char *name = (const char *)merge_rr.items[i].util;
107-
diff_two(rerere_path(name, "preimage"), path, path, path);
108+
if (diff_two(rerere_path(name, "preimage"), path, path, path))
109+
die("unable to generate diff for %s", name);
108110
}
109111
else
110112
usage_with_options(rerere_usage, options);

combine-diff.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,10 @@ static void combine_diff(const unsigned char *parent, unsigned int mode,
419419
state.num_parent = num_parent;
420420
state.n = n;
421421

422-
xdi_diff_outf(&parent_file, result_file, consume_line, &state,
423-
&xpp, &xecfg);
422+
if (xdi_diff_outf(&parent_file, result_file, consume_line, &state,
423+
&xpp, &xecfg))
424+
die("unable to generate combined diff for %s",
425+
sha1_to_hex(parent));
424426
free(parent_file.ptr);
425427

426428
/* Assign line numbers for this parent.

diff.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,8 +1002,9 @@ static void diff_words_show(struct diff_words_data *diff_words)
10021002
xpp.flags = 0;
10031003
/* as only the hunk header will be parsed, we need a 0-context */
10041004
xecfg.ctxlen = 0;
1005-
xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
1006-
&xpp, &xecfg);
1005+
if (xdi_diff_outf(&minus, &plus, fn_out_diff_words_aux, diff_words,
1006+
&xpp, &xecfg))
1007+
die("unable to generate word diff");
10071008
free(minus.ptr);
10081009
free(plus.ptr);
10091010
if (diff_words->current_plus != diff_words->plus.text.ptr +
@@ -2400,8 +2401,9 @@ static void builtin_diff(const char *name_a,
24002401
xecfg.ctxlen = strtoul(v, NULL, 10);
24012402
if (o->word_diff)
24022403
init_diff_words_data(&ecbdata, o, one, two);
2403-
xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
2404-
&xpp, &xecfg);
2404+
if (xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
2405+
&xpp, &xecfg))
2406+
die("unable to generate diff for %s", one->path);
24052407
if (o->word_diff)
24062408
free_diff_words_data(&ecbdata);
24072409
if (textconv_one)
@@ -2478,8 +2480,9 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
24782480
xpp.flags = o->xdl_opts;
24792481
xecfg.ctxlen = o->context;
24802482
xecfg.interhunkctxlen = o->interhunkcontext;
2481-
xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
2482-
&xpp, &xecfg);
2483+
if (xdi_diff_outf(&mf1, &mf2, diffstat_consume, diffstat,
2484+
&xpp, &xecfg))
2485+
die("unable to generate diffstat for %s", one->path);
24832486
}
24842487

24852488
diff_free_filespec_data(one);
@@ -2525,8 +2528,9 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
25252528
memset(&xecfg, 0, sizeof(xecfg));
25262529
xecfg.ctxlen = 1; /* at least one context line */
25272530
xpp.flags = 0;
2528-
xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
2529-
&xpp, &xecfg);
2531+
if (xdi_diff_outf(&mf1, &mf2, checkdiff_consume, &data,
2532+
&xpp, &xecfg))
2533+
die("unable to generate checkdiff for %s", one->path);
25302534

25312535
if (data.ws_rule & WS_BLANK_AT_EOF) {
25322536
struct emit_callback ecbdata;
@@ -4425,8 +4429,10 @@ static int diff_get_patch_id(struct diff_options *options, unsigned char *sha1)
44254429
xpp.flags = 0;
44264430
xecfg.ctxlen = 3;
44274431
xecfg.flags = 0;
4428-
xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
4429-
&xpp, &xecfg);
4432+
if (xdi_diff_outf(&mf1, &mf2, patch_id_consume, &data,
4433+
&xpp, &xecfg))
4434+
return error("unable to generate patch-id diff for %s",
4435+
p->one->path);
44304436
}
44314437

44324438
git_SHA1_Final(sha1, &ctx);

diffcore-pickaxe.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ static int diff_grep(mmfile_t *one, mmfile_t *two,
6262
ecbdata.hit = 0;
6363
xecfg.ctxlen = o->context;
6464
xecfg.interhunkctxlen = o->interhunkcontext;
65-
xdi_diff_outf(one, two, diffgrep_consume, &ecbdata,
66-
&xpp, &xecfg);
65+
if (xdi_diff_outf(one, two, diffgrep_consume, &ecbdata, &xpp, &xecfg))
66+
return 0;
6767
return ecbdata.hit;
6868
}
6969

line-log.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ static int collect_diff_cb(long start_a, long count_a,
325325
return 0;
326326
}
327327

328-
static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
328+
static int collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges *out)
329329
{
330330
struct collect_diff_cbdata cbdata = {NULL};
331331
xpparam_t xpp;
@@ -340,7 +340,7 @@ static void collect_diff(mmfile_t *parent, mmfile_t *target, struct diff_ranges
340340
xecfg.hunk_func = collect_diff_cb;
341341
memset(&ecb, 0, sizeof(ecb));
342342
ecb.priv = &cbdata;
343-
xdi_diff(parent, target, &xpp, &xecfg, &ecb);
343+
return xdi_diff(parent, target, &xpp, &xecfg, &ecb);
344344
}
345345

346346
/*
@@ -1030,7 +1030,8 @@ static int process_diff_filepair(struct rev_info *rev,
10301030
}
10311031

10321032
diff_ranges_init(&diff);
1033-
collect_diff(&file_parent, &file_target, &diff);
1033+
if (collect_diff(&file_parent, &file_target, &diff))
1034+
die("unable to generate diff for %s", pair->one->path);
10341035

10351036
/* NEEDSWORK should apply some heuristics to prevent mismatches */
10361037
free(rg->path);

ll-merge.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ static int ll_xdl_merge(const struct ll_merge_driver *drv_unused,
8888
xmparam_t xmp;
8989
assert(opts);
9090

91-
if (buffer_is_binary(orig->ptr, orig->size) ||
91+
if (orig->size > MAX_XDIFF_SIZE ||
92+
src1->size > MAX_XDIFF_SIZE ||
93+
src2->size > MAX_XDIFF_SIZE ||
94+
buffer_is_binary(orig->ptr, orig->size) ||
9295
buffer_is_binary(src1->ptr, src1->size) ||
9396
buffer_is_binary(src2->ptr, src2->size)) {
9497
return ll_binary_merge(drv_unused, result,

xdiff-interface.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t co
131131
mmfile_t a = *mf1;
132132
mmfile_t b = *mf2;
133133

134+
if (mf1->size > MAX_XDIFF_SIZE || mf2->size > MAX_XDIFF_SIZE)
135+
return -1;
136+
134137
trim_common_tail(&a, &b, xecfg->ctxlen);
135138

136139
return xdl_diff(&a, &b, xpp, xecfg, xecb);

xdiff-interface.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33

44
#include "xdiff/xdiff.h"
55

6+
/*
7+
* xdiff isn't equipped to handle content over a gigabyte;
8+
* we make the cutoff 1GB - 1MB to give some breathing
9+
* room for constant-sized additions (e.g., merge markers)
10+
*/
11+
#define MAX_XDIFF_SIZE (1024UL * 1024 * 1023)
12+
613
typedef void (*xdiff_emit_consume_fn)(void *, char *, unsigned long);
714

815
int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *ecb);

0 commit comments

Comments
 (0)