1# $NetBSD: t_input.sh,v 1.1 2021/02/16 09:46:24 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 # please do not make even trivial changes (like correcting spelling) 52 # to the following script without taking care to fix the following 53 # tests, even minor changes can defeat the purpose of the test 54 cat > helper.sh <<- EOF 55 # a line of commentary that does nothing 56 # another line of comments (these just make the script bigger) 57 printf A 58 eval "printf B" 59 if printf C 60 then 61 printf D 62 fi 63 for x in E F G H 64 do 65 printf "\$x" 66 done 67 printf \\ 68 I 69 printf '\n' 70 exit 0 71 EOF 72 73 # this first test simply verifies that the script works as 74 # expected, should it fail, it is not a problem with \0 chars 75 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 76 ${TEST_SH} helper.sh 77 78 size=$(stat -f %z helper.sh) 79 80 # Now insert \0 chars at specifically chosen spots in script 81 for loc in 0 10 40 41 42 104 105 106 110 111 112 113 119 127 128 \ 82 144 150 162 165 168 187 202 203 204 205 214 215 216 224 225 83 do 84 # at each location try varying the number of \0's inserted 85 for N in 1 2 4 7 86 do 87 OF="helper-${N}@${loc}.sh" 88 89 test "${loc}" -gt 0 && 90 dd if=helper.sh bs=1 count="${loc}" \ 91 of="${OF}" >/dev/null 2>&1 92 dd if=helper.sh bs=1 skip="${loc}" \ 93 oseek="$(( loc + N ))" \ 94 of="${OF}" >/dev/null 2>&1 95 96 test "$(stat -f %z "${OF}")" -eq "$(( size + N ))" || 97 atf_fail "${N}@${loc}: build failure" 98 99 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 100 ${TEST_SH} "${OF}" 101 102 rm -f "${OF}" 103 done 104 105 done 106 107 # Next insert \0 chars at multiple chosen locations 108 # nb: offsets in each arg must be non-decreasing 109 for locs in '0 225' '0 224' '0 127 223' '0 10 15' '0 48 55' \ 110 '0 0 0 225 225 225' '0 0 127 128 224 224 225' \ 111 '104 106' '105 110' '113 119' '113 119 122' '113 127' \ 112 '129 130 131 132 133 136 139 140' '184 185 186 187' \ 113 '202 203 203 204 204 205 205 206 207' 114 do 115 set -- $locs 116 gaps=$# 117 118 IFS=- 119 OF="helper-${*}.sh" 120 unset IFS 121 122 loc=$1; shift 123 test "${loc}" -gt 0 && 124 dd if=helper.sh bs=1 count="${loc}" \ 125 of="${OF}" >/dev/null 2>&1 126 G=1 127 for N 128 do 129 count=$(( N - loc )) 130 if [ "${count}" -eq 0 ] 131 then 132 printf '\0' >> "${OF}" 133 else 134 dd if=helper.sh bs=1 skip="${loc}" \ 135 oseek="$(( loc + G ))" count="${count}" \ 136 of="${OF}" >/dev/null 2>&1 137 fi 138 loc=$N 139 G=$(( G + 1 )) 140 done 141 142 if [ "${loc}" -lt "${size}" ] 143 then 144 dd if=helper.sh bs=1 skip="${loc}" \ 145 oseek="$(( loc + G ))" of="${OF}" >/dev/null 2>&1 146 else 147 printf '\0' >> "${OF}" 148 fi 149 150 test "$(stat -f %z "${OF}")" -eq "$(( size + gaps ))" || 151 atf_fail "${locs}: build failure" 152 153 atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 154 ${TEST_SH} "${OF}" 155 156 rm -f "${OF}" 157 done 158 159 # Now just insert \0's in random locations in the script, 160 # hoping that if the somewhat carefully selected insertions 161 # above fail to trigger a bug, then if any (bugs) remain, 162 # eventually Murphy will prevail, and one of these tests will catch it. 163 164 test "${RANDOM}" = "${RANDOM}" && 165 atf_skip 'ATF shell does not support $RANDOM' 166 167 # To be added later... 168 169 return 0 170} 171 172atf_init_test_cases() { 173 atf_add_test_case nul_elimination 174 # atf_add_test_case file_recursion 175 # atf_add_test_case file_string_recursion 176 # atf_add_test_case file_recursion_nul 177 # atf_add_test_case file_string_recursion_nul 178} 179