patch: fix pch_context() for unified diffs with no leading context

When the first line of a file is a removal, we may not have any leading
context.  Only adjusting p_context if context > 0 means that we
incorrectly believe that we have 100 lines of context when the reality
is that we have none.

This fixes a bug with fuzz-checking, which ends up fuzzing away the line
we're trying to replace if it's the first line in the file.  We use
pch_context() to determine a reasonable max-fuzz.

PR:		250511
Reviewed by:	pfg
Differential Revision:	https://reviews.freebsd.org/D51837
This commit is contained in:
Kyle Evans
2025-08-29 14:24:35 -05:00
parent 343f8f71af
commit f97b6a8f84
2 changed files with 22 additions and 1 deletions
+1 -1
View File
@@ -1054,7 +1054,7 @@ another_hunk(void)
p_end = fillnew;
malformed();
}
if (ch != ' ' && context > 0) {
if (ch != ' ' && context >= 0) {
if (context < p_context)
p_context = context;
context = -1000;
+21
View File
@@ -25,6 +25,26 @@
# SUCH DAMAGE.
#
atf_test_case badfuzz
badfuzz_head()
{
atf_set "descr" "Test for patch(1) erroneously fuzzing away action lines"
}
badfuzz_body()
{
# PR 250511 demonstrates a scenario where patch(1) will happily apply a
# patch into the wrong location if we have some lines that are still
# similar in the trailing context. In the following example, it would
# actually replace the underscore before the second series of B\nC\nO
# with "Z", when the patch should have been rejected instead.
printf "A\nB\nC\nO\n_\nB\nC\nO\n" > file.orig
printf "Z\nB\nC\nO\n_\nB\nC\nO\n" > file
printf "OK\nDIFF1\nDIFF2\n\n_\nB\nC\nO\n" > file.newer
atf_check -s not-exit:0 -o save:file.patch diff -u3 file.orig file
atf_check -s not-exit:0 -o not-empty patch file.newer file.patch
}
atf_test_case basic
basic_body()
{
@@ -161,6 +181,7 @@ EOF
atf_init_test_cases()
{
atf_add_test_case badfuzz
atf_add_test_case basic
atf_add_test_case limited_ctx
atf_add_test_case file_creation