1# $NetBSD: t_input.sh,v 1.2 2024/10/14 12:26:28 kre Exp $ 2# 3# Copyright (c) 2021 The NetBSD Foundation, Inc. 4# All rights reserved. 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27# the implementation of "sh" to test 28: ${TEST_SH:="/bin/sh"} 29 30# This set of tests checks the low level shell (script) input 31# systrem (reading script files, nested files, fines read while 32# reading strings, ..) and correctly dropping nul bytes from file data 33 34# other shell input (the read builtin for example) is not covered here. 35 36atf_test_case nul_elimination 37 38nul_elimination_head() { 39 atf_set "descr" "verifies that \0 chars in input are properly ignored" 40} 41 42nul_elimination_body() { 43 atf_require_prog printf 44 atf_require_prog stat 45 46 # these really should always be present, but... 47 atf_require_prog dd 48 atf_require_prog cat 49 atf_require_prog rm 50 51 atf_expect_fail "nuls are now errors, not ignored, revisit later" 52 53 # please do not make even trivial changes (like correcting spelling) 54 # to the following script without taking care to fix the following 55 # tests, even minor changes can defeat the purpose of the test 56 cat > helper.sh <<- EOF 57 # a line of commentary that does nothing 58 # another line of comments (these just make the script bigger) 59 printf A 60 eval "printf B" 61 if printf C 62 then 63 printf D 64 fi 65 for x in E F G H 66 do 67 printf "\$x" 68 done 69 printf \\ 70 I 71 printf '\n' 72 exit 0 73 EOF 74 75 # this first test simply verifies that the script works as 76 # expected, should it fail, it is not a problem with \0 chars 77 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 78 ${TEST_SH} helper.sh 79 80 size=$(stat -f %z helper.sh) 81 82 # Now insert \0 chars at specifically chosen spots in script 83 for loc in 0 10 40 41 42 104 105 106 110 111 112 113 119 127 128 \ 84 144 150 162 165 168 187 202 203 204 205 214 215 216 224 225 85 do 86 # at each location try varying the number of \0's inserted 87 for N in 1 2 4 7 88 do 89 OF="helper-${N}@${loc}.sh" 90 91 test "${loc}" -gt 0 && 92 dd if=helper.sh bs=1 count="${loc}" \ 93 of="${OF}" >/dev/null 2>&1 94 dd if=helper.sh bs=1 skip="${loc}" \ 95 oseek="$(( loc + N ))" \ 96 of="${OF}" >/dev/null 2>&1 97 98 test "$(stat -f %z "${OF}")" -eq "$(( size + N ))" || 99 atf_fail "${N}@${loc}: build failure" 100 101 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 102 ${TEST_SH} "${OF}" 103 104 rm -f "${OF}" 105 done 106 107 done 108 109 # Next insert \0 chars at multiple chosen locations 110 # nb: offsets in each arg must be non-decreasing 111 for locs in '0 225' '0 224' '0 127 223' '0 10 15' '0 48 55' \ 112 '0 0 0 225 225 225' '0 0 127 128 224 224 225' \ 113 '104 106' '105 110' '113 119' '113 119 122' '113 127' \ 114 '129 130 131 132 133 136 139 140' '184 185 186 187' \ 115 '202 203 203 204 204 205 205 206 207' 116 do 117 set -- $locs 118 gaps=$# 119 120 IFS=- 121 OF="helper-${*}.sh" 122 unset IFS 123 124 loc=$1; shift 125 test "${loc}" -gt 0 && 126 dd if=helper.sh bs=1 count="${loc}" \ 127 of="${OF}" >/dev/null 2>&1 128 G=1 129 for N 130 do 131 count=$(( N - loc )) 132 if [ "${count}" -eq 0 ] 133 then 134 printf '\0' >> "${OF}" 135 else 136 dd if=helper.sh bs=1 skip="${loc}" \ 137 oseek="$(( loc + G ))" count="${count}" \ 138 of="${OF}" >/dev/null 2>&1 139 fi 140 loc=$N 141 G=$(( G + 1 )) 142 done 143 144 if [ "${loc}" -lt "${size}" ] 145 then 146 dd if=helper.sh bs=1 skip="${loc}" \ 147 oseek="$(( loc + G ))" of="${OF}" >/dev/null 2>&1 148 else 149 printf '\0' >> "${OF}" 150 fi 151 152 test "$(stat -f %z "${OF}")" -eq "$(( size + gaps ))" || 153 atf_fail "${locs}: build failure" 154 155 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 156 ${TEST_SH} "${OF}" 157 158 rm -f "${OF}" 159 done 160 161 # Now just insert \0's in random locations in the script, 162 # hoping that if the somewhat carefully selected insertions 163 # above fail to trigger a bug, then if any (bugs) remain, 164 # eventually Murphy will prevail, and one of these tests will catch it. 165 166 test "${RANDOM}" = "${RANDOM}" && 167 atf_skip 'ATF shell does not support $RANDOM' 168 169 # To be added later... 170 171 return 0 172} 173 174atf_init_test_cases() { 175 atf_add_test_case nul_elimination 176 # atf_add_test_case file_recursion 177 # atf_add_test_case file_string_recursion 178 # atf_add_test_case file_recursion_nul 179 # atf_add_test_case file_string_recursion_nul 180} 181