Skip to content

Commit b777f3f

Browse files
peffgitster
authored andcommitted
xdiff: clamp function context indices in post-image
After finding a function line for --function-context in the pre-image, xdl_emit_diff() calculates the equivalent line in the post-image. It assumes that the lines between changes are the same on both sides. If the option --ignore-blank-lines was also given then this is not necessarily true. Clamp the calculation results for start and end of the function context to prevent out-of-bounds array accesses. Note that this _just_ fixes the case where our mismatch sends us off the beginning of the file. There are likely other cases where our assumption causes us to go to the wrong line within the file. Nobody has developed a test case yet, and the ultimate fix is likely more complicated than this patch. But this at least prevents a segfault in the meantime. Credit for finding the bug goes to "Liu Wei of Tencent Security Xuanwu Lab". Reported-by: 刘炜 <[email protected]> Helped-by: René Scharfe <[email protected]> Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0d0ac38 commit b777f3f

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

t/t4015-diff-whitespace.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,4 +1897,26 @@ test_expect_success 'compare whitespace delta incompatible with other space opti
18971897
test_i18ngrep allow-indentation-change err
18981898
'
18991899

1900+
# Note that the "6" in the expected hunk header below is funny, since we only
1901+
# show 5 lines (the missing one was blank and thus ignored). This is how
1902+
# --ignore-blank-lines behaves even without --function-context, and this test
1903+
# is just checking the interaction of the two features. Don't take it as an
1904+
# endorsement of that output.
1905+
test_expect_success 'combine --ignore-blank-lines with --function-context' '
1906+
test_write_lines 1 "" 2 3 4 5 >a &&
1907+
test_write_lines 1 2 3 4 >b &&
1908+
test_must_fail git diff --no-index \
1909+
--ignore-blank-lines --function-context a b >actual.raw &&
1910+
sed -n "/@@/,\$p" <actual.raw >actual &&
1911+
cat <<-\EOF >expect &&
1912+
@@ -1,6 +1,4 @@
1913+
1
1914+
2
1915+
3
1916+
4
1917+
-5
1918+
EOF
1919+
test_cmp expect actual
1920+
'
1921+
19001922
test_done

xdiff/xemit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
210210
if (fs1 < 0)
211211
fs1 = 0;
212212
if (fs1 < s1) {
213-
s2 -= s1 - fs1;
213+
s2 = XDL_MAX(s2 - (s1 - fs1), 0);
214214
s1 = fs1;
215215
}
216216
}
@@ -232,7 +232,7 @@ int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
232232
if (fe1 < 0)
233233
fe1 = xe->xdf1.nrec;
234234
if (fe1 > e1) {
235-
e2 += fe1 - e1;
235+
e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec);
236236
e1 = fe1;
237237
}
238238

0 commit comments

Comments
 (0)