1b2752497SKyle Evans# 24d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 3b2752497SKyle Evans# 4b2752497SKyle Evans# Copyright (c) 2019 Kyle Evans <kevans@FreeBSD.org> 5b2752497SKyle Evans# 6b2752497SKyle Evans# Redistribution and use in source and binary forms, with or without 7b2752497SKyle Evans# modification, are permitted provided that the following conditions 8b2752497SKyle Evans# are met: 9b2752497SKyle Evans# 1. Redistributions of source code must retain the above copyright 10b2752497SKyle Evans# notice, this list of conditions and the following disclaimer. 11b2752497SKyle Evans# 2. Redistributions in binary form must reproduce the above copyright 12b2752497SKyle Evans# notice, this list of conditions and the following disclaimer in the 13b2752497SKyle Evans# documentation and/or other materials provided with the distribution. 14b2752497SKyle Evans# 15b2752497SKyle Evans# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16b2752497SKyle Evans# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17b2752497SKyle Evans# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18b2752497SKyle Evans# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19b2752497SKyle Evans# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20b2752497SKyle Evans# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21b2752497SKyle Evans# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22b2752497SKyle Evans# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23b2752497SKyle Evans# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24b2752497SKyle Evans# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25b2752497SKyle Evans# SUCH DAMAGE. 26b2752497SKyle Evans# 27b2752497SKyle Evans 28b2752497SKyle Evansatf_test_case basic 29b2752497SKyle Evansbasic_body() 30b2752497SKyle Evans{ 31b2752497SKyle Evans printf "a\nb\nc\nd\ne\nf\ng\nh\ni\n" > foo_full 32b2752497SKyle Evans printf "a\nb\nc\n" > foo_start 33b2752497SKyle Evans printf "g\nh\ni\n" > foo_end 34b2752497SKyle Evans printf "d\ne\nf\n" > foo_middle 35b2752497SKyle Evans 36b2752497SKyle Evans diff -u foo_start foo_full > foo_start2full.diff 37b2752497SKyle Evans diff -u foo_end foo_full > foo_end2full.diff 38b2752497SKyle Evans diff -u foo_middle foo_full > foo_mid2full.diff 39b2752497SKyle Evans 40b2752497SKyle Evans # Check lengths... each should have all 9 lines + 3 line header 41b2752497SKyle Evans atf_check -o inline:"12" -x \ 42b2752497SKyle Evans "cat foo_start2full.diff | wc -l | tr -d '[:space:]'" 43b2752497SKyle Evans atf_check -o inline:"12" -x \ 44b2752497SKyle Evans "cat foo_end2full.diff | wc -l | tr -d '[:space:]'" 45b2752497SKyle Evans atf_check -o inline:"12" -x \ 46b2752497SKyle Evans "cat foo_mid2full.diff | wc -l | tr -d '[:space:]'" 47b2752497SKyle Evans 48b2752497SKyle Evans # Apply the patch! Should succeed 49b2752497SKyle Evans atf_check -o ignore patch foo_start foo_start2full.diff \ 50b2752497SKyle Evans -o foo_start2full 51b2752497SKyle Evans atf_check -o ignore patch foo_end foo_end2full.diff \ 52b2752497SKyle Evans -o foo_end2full 53b2752497SKyle Evans atf_check -o ignore patch foo_middle foo_mid2full.diff \ 54b2752497SKyle Evans -o foo_mid2full 55b2752497SKyle Evans 56b2752497SKyle Evans # And these should all produce equivalent to the original full 57b2752497SKyle Evans atf_check -o ignore diff foo_start2full foo_full 58b2752497SKyle Evans atf_check -o ignore diff foo_end2full foo_full 59b2752497SKyle Evans atf_check -o ignore diff foo_mid2full foo_full 60b2752497SKyle Evans} 61b2752497SKyle Evans 62b2752497SKyle Evansatf_test_case limited_ctx 63b2752497SKyle Evanslimited_ctx_head() 64b2752497SKyle Evans{ 65b2752497SKyle Evans atf_set "descr" "Verify correct behavior with limited context (PR 74127)" 66b2752497SKyle Evans} 67b2752497SKyle Evanslimited_ctx_body() 68b2752497SKyle Evans{ 69b2752497SKyle Evans 70b2752497SKyle Evans # First; PR74127-repro.diff should not have applied, but it instead 71b2752497SKyle Evans # assumed a match and added the modified line at the offset specified... 72b2752497SKyle Evans atf_check -s not-exit:0 -o ignore -e ignore patch -o _.out \ 73b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 74b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-repro.diff" 75b2752497SKyle Evans 76b2752497SKyle Evans # Let's extend that and make sure a similarly ill-contexted diff does 77b2752497SKyle Evans # not apply even with the correct line number 78b2752497SKyle Evans atf_check -s not-exit:0 -o ignore -e ignore patch -o _.out \ 79b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 80b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-line.diff" 81b2752497SKyle Evans 82b2752497SKyle Evans # Correct line number and correct old line should always work 83b2752497SKyle Evans atf_check -o ignore -e ignore patch -o _.out \ 84b2752497SKyle Evans "$(atf_get_srcdir)/PR74127.in" \ 85b2752497SKyle Evans "$(atf_get_srcdir)/PR74127-good.diff" 86b2752497SKyle Evans} 87b2752497SKyle Evans 88b2752497SKyle Evansatf_test_case file_creation 89b2752497SKyle Evansfile_creation_body() 90b2752497SKyle Evans{ 91b2752497SKyle Evans 92b2752497SKyle Evans echo "x" > foo 93b2752497SKyle Evans diff -u /dev/null foo > foo.diff 94b2752497SKyle Evans rm foo 95b2752497SKyle Evans 96b2752497SKyle Evans atf_check -x "patch -s < foo.diff" 97b2752497SKyle Evans atf_check -o ignore stat foo 98b2752497SKyle Evans} 99b2752497SKyle Evans 100b2752497SKyle Evans# This test is motivated by long-standing bugs that occasionally slip by in 101b2752497SKyle Evans# commits. If a file is created by a diff, patch(1) will happily duplicate the 102b2752497SKyle Evans# contents as many times as you apply the diff. It should instead detect that 103b2752497SKyle Evans# a source of /dev/null creates the file, so it shouldn't exist. Furthermore, 10489b5571eSKyle Evans# the reverse of creation is deletion -- hence the next test, which ensures that 10550dacbf6SKyle Evans# the file is removed if it's empty once the patch is reversed. The size checks 10650dacbf6SKyle Evans# are scattered throughout to make sure that we didn't get some kind of false 10750dacbf6SKyle Evans# error, and the first size check is merely a sanity check that should be 10850dacbf6SKyle Evans# trivially true as this is executed in a sandbox. 109b2752497SKyle Evansatf_test_case file_nodupe 110b2752497SKyle Evansfile_nodupe_body() 111b2752497SKyle Evans{ 112b2752497SKyle Evans 113b2752497SKyle Evans echo "x" > foo 114b2752497SKyle Evans diff -u /dev/null foo > foo.diff 115b2752497SKyle Evans 11650dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 11750dacbf6SKyle Evans atf_check -s not-exit:0 -o ignore -x "patch -Ns < foo.diff" 11850dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 11950dacbf6SKyle Evans atf_check -s not-exit:0 -o ignore -x "patch -fs < foo.diff" 12050dacbf6SKyle Evans atf_check -o inline:"2\n" stat -f "%z" foo 121b2752497SKyle Evans} 122b2752497SKyle Evans 123b2752497SKyle Evansatf_test_case file_removal 124b2752497SKyle Evansfile_removal_body() 125b2752497SKyle Evans{ 126b2752497SKyle Evans 127b2752497SKyle Evans echo "x" > foo 128b2752497SKyle Evans diff -u /dev/null foo > foo.diff 129b2752497SKyle Evans 13089b5571eSKyle Evans # Check that the file is removed completely if it was sourced from 13189b5571eSKyle Evans # /dev/null 132b2752497SKyle Evans atf_check -x "patch -Rs < foo.diff" 13389b5571eSKyle Evans atf_check -s not-exit:0 -e ignore stat foo 13489b5571eSKyle Evans 13589b5571eSKyle Evans # But if it had been modified, we'll only remove the portion that the 13689b5571eSKyle Evans # patch would have created. This makes us compatible with GNU patch's 13789b5571eSKyle Evans # behavior, at least. Whether that is the sane action or not is a 13889b5571eSKyle Evans # question for further study, and then this comment may be removed. 13989b5571eSKyle Evans printf "x\ny\n" > foo 14089b5571eSKyle Evans atf_check -x "patch -Rs < foo.diff" 14189b5571eSKyle Evans atf_check -o inline:"y\n" cat foo 142b2752497SKyle Evans} 143b2752497SKyle Evans 144*851a9da3SDag-Erling Smørgravatf_test_case plinelen 145*851a9da3SDag-Erling Smørgravplinelen_body() 146*851a9da3SDag-Erling Smørgrav{ 147*851a9da3SDag-Erling Smørgrav hello="$(jot -b hello -s, 20000 | tee foo.txt)" 148*851a9da3SDag-Erling Smørgrav cp foo.txt bar.txt 149*851a9da3SDag-Erling Smørgrav echo "world" >>bar.txt 150*851a9da3SDag-Erling Smørgrav cat >foo.diff <<EOF 151*851a9da3SDag-Erling Smørgrav--- foo.txt.orig 152*851a9da3SDag-Erling Smørgrav+++ foo.txt 153*851a9da3SDag-Erling Smørgrav@@ -1,1 +1,2 @@ 154*851a9da3SDag-Erling Smørgrav $hello 155*851a9da3SDag-Erling Smørgrav+world 156*851a9da3SDag-Erling SmørgravEOF 157*851a9da3SDag-Erling Smørgrav atf_check -o match:"Hunk #1 succeeded" \ 158*851a9da3SDag-Erling Smørgrav patch <foo.diff 159*851a9da3SDag-Erling Smørgrav atf_check -o file:bar.txt cat foo.txt 160*851a9da3SDag-Erling Smørgrav} 161*851a9da3SDag-Erling Smørgrav 162b2752497SKyle Evansatf_init_test_cases() 163b2752497SKyle Evans{ 164b2752497SKyle Evans atf_add_test_case basic 165b2752497SKyle Evans atf_add_test_case limited_ctx 166b2752497SKyle Evans atf_add_test_case file_creation 167b2752497SKyle Evans atf_add_test_case file_nodupe 168b2752497SKyle Evans atf_add_test_case file_removal 169*851a9da3SDag-Erling Smørgrav atf_add_test_case plinelen 170b2752497SKyle Evans} 171