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