Merge branch 'jk/xdiff-clamp-funcname-context-index' into maint

The internal diff machinery can be made to read out of bounds while
looking for --funcion-context line in a corner case, which has been
corrected.

* jk/xdiff-clamp-funcname-context-index:
  xdiff: clamp function context indices in post-image
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index ab4670d..6b087df 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -2008,4 +2008,26 @@
 	test_cmp expected actual
 '
 
+# Note that the "6" in the expected hunk header below is funny, since we only
+# show 5 lines (the missing one was blank and thus ignored). This is how
+# --ignore-blank-lines behaves even without --function-context, and this test
+# is just checking the interaction of the two features. Don't take it as an
+# endorsement of that output.
+test_expect_success 'combine --ignore-blank-lines with --function-context' '
+	test_write_lines 1 "" 2 3 4 5 >a &&
+	test_write_lines 1    2 3 4   >b &&
+	test_must_fail git diff --no-index \
+		--ignore-blank-lines --function-context a b >actual.raw &&
+	sed -n "/@@/,\$p" <actual.raw >actual &&
+	cat <<-\EOF >expect &&
+	@@ -1,6 +1,4 @@
+	 1
+	 2
+	 3
+	 4
+	-5
+	EOF
+	test_cmp expect actual
+'
+
 test_done
diff --git a/xdiff/xemit.c b/xdiff/xemit.c
index 7778dc2..30713ae 100644
--- a/xdiff/xemit.c
+++ b/xdiff/xemit.c
@@ -210,7 +210,7 @@
 			if (fs1 < 0)
 				fs1 = 0;
 			if (fs1 < s1) {
-				s2 -= s1 - fs1;
+				s2 = XDL_MAX(s2 - (s1 - fs1), 0);
 				s1 = fs1;
 			}
 		}
@@ -232,7 +232,7 @@
 			if (fe1 < 0)
 				fe1 = xe->xdf1.nrec;
 			if (fe1 > e1) {
-				e2 += fe1 - e1;
+				e2 = XDL_MIN(e2 + (fe1 - e1), xe->xdf2.nrec);
 				e1 = fe1;
 			}