A patch produced with `diff -U0' or `-U1' may be misapplied if the file being patched changes (is of newer version) and the hunk is no longer applicable. patch(1) should fail loudly in this case, instead it sticks the new lines at the old location. Fix: Use larger context, which is not always convenient. How-To-Repeat: Try applying this patch: --- l Mon Apr 3 20:00:28 2000 +++ l Fri May 5 10:01:58 2000 @@ -5,1 +5,1 @@ - set Log(compressProg) /usr/local/bin/gzip + set Log(compressProg) /usr/bin/gzip to this file: # This program is used to compress log files if {![info exists Log(compressProg)]} { set Log(compressProg) gzip } # Flush interval if {![info exists Log(flushInterval)]} { set Log(flushInterval) [expr {60 * 1000}] } # This is used to turn on an alternate debug log file if {![info exist Log(debug_log)]} { set Log(debug_log) 0 } It should not apply at all. Instead, one gets the reassuring: ``Hunk #1 succeeded at 5 with fuzz 1.'' and a botched file.
See also bin/84816: patch(1) inserts a line in the wrong place
For the record ... This was very likely GNU patch (old version), we are currently using a fork of OpenBSD's patch(1). The bug may or may not exist.
(In reply to Pedro F. Giffuni from comment #2) I double-checked this one- for documentation sake, the example in this PR results in the following file: if {![info exists Log(compressProg)]} { set Log(compressProg) gzip } set Log(compressProg) /usr/bin/gzip if {![info exists Log(flushInterval)]} { set Log(flushInterval) [expr {60 * 1000}] } # This is used to turn on an alternate debug log file if {![info exist Log(debug_log)]} { set Log(debug_log) 0 } with the following output: > Patching file file.c using Plan A... > Hunk #1 succeeded at 5 with fuzz 1. > done patch -v: > patch 2.0-12u11 FreeBSD
A commit references this bug: Author: kevans Date: Fri Nov 3 17:04:31 UTC 2017 New revision: 325365 URL: https://svnweb.freebsd.org/changeset/base/325365 Log: patch(1): don't assume a match if we run out of context to check Patches with very little context (-U0 and -U1) could get misapplied if the file to be patched changes and a hunk is no longer applicable. Matching with fuzz would be attempted and default to a match when we unexpectedly ran out of context. PR: 74127 Reviewed by: emaste, pfg Approved by: emaste (mentor) Differential Revision: https://reviews.freebsd.org/D12631 Changes: head/usr.bin/patch/patch.c
A commit references this bug: Author: kevans Date: Wed Nov 22 03:44:19 UTC 2017 New revision: 326084 URL: https://svnweb.freebsd.org/changeset/base/326084 Log: patch(1): don't assume a match if we run out of context to check Patches with very little context (-U0 and -U1) could get misapplied if the file to be patched changes and a hunk is no longer applicable. Matching with fuzz would be attempted and default to a match when we unexpectedly ran out of context. This also affected patches with higher levels of context but had limited actual context due to the hunk being located near the beginning/end of file. PR: 74127, 223545 (exp-run) Reviewed by: emaste, pfg Approved by: emaste (mentor) Differential Revision: https://reviews.freebsd.org/D12631 Changes: head/usr.bin/patch/patch.c
A commit references this bug: Author: kevans Date: Thu Jan 18 21:53:07 UTC 2018 New revision: 328148 URL: https://svnweb.freebsd.org/changeset/base/328148 Log: MFC r326084: patch(1): don't assume match if we run out of context to check Patches with very little context (-U0 and -U1) could get misapplied if the file to be patched changes and a hunk is no longer applicable. Matching with fuzz would be attempted and default to a match when we unexpectedly ran out of context. This also affected patches with higher levels of context but had limited actual context due to the hunk being located near the beginning/end of file. PR: 74127 Changes: _U stable/11/ stable/11/usr.bin/patch/patch.c