# $NetBSD: t_input.sh,v 1.1 2021/02/16 09:46:24 kre Exp $ # # Copyright (c) 2021 The NetBSD Foundation, Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # the implementation of "sh" to test : ${TEST_SH:="/bin/sh"} # This set of tests checks the low level shell (script) input # systrem (reading script files, nested files, fines read while # reading strings, ..) and correctly dropping nul bytes from file data # other shell input (the read builtin for example) is not covered here. atf_test_case nul_elimination nul_elimination_head() { atf_set "descr" "verifies that \0 chars in input are properly ignored" } nul_elimination_body() { atf_require_prog printf atf_require_prog stat # these really should always be present, but... atf_require_prog dd atf_require_prog cat atf_require_prog rm # please do not make even trivial changes (like correcting spelling) # to the following script without taking care to fix the following # tests, even minor changes can defeat the purpose of the test cat > helper.sh <<- EOF # a line of commentary that does nothing # another line of comments (these just make the script bigger) printf A eval "printf B" if printf C then printf D fi for x in E F G H do printf "\$x" done printf \\ I printf '\n' exit 0 EOF # this first test simply verifies that the script works as # expected, should it fail, it is not a problem with \0 chars atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ ${TEST_SH} helper.sh size=$(stat -f %z helper.sh) # Now insert \0 chars at specifically chosen spots in script for loc in 0 10 40 41 42 104 105 106 110 111 112 113 119 127 128 \ 144 150 162 165 168 187 202 203 204 205 214 215 216 224 225 do # at each location try varying the number of \0's inserted for N in 1 2 4 7 do OF="helper-${N}@${loc}.sh" test "${loc}" -gt 0 && dd if=helper.sh bs=1 count="${loc}" \ of="${OF}" >/dev/null 2>&1 dd if=helper.sh bs=1 skip="${loc}" \ oseek="$(( loc + N ))" \ of="${OF}" >/dev/null 2>&1 test "$(stat -f %z "${OF}")" -eq "$(( size + N ))" || atf_fail "${N}@${loc}: build failure" atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ ${TEST_SH} "${OF}" rm -f "${OF}" done done # Next insert \0 chars at multiple chosen locations # nb: offsets in each arg must be non-decreasing for locs in '0 225' '0 224' '0 127 223' '0 10 15' '0 48 55' \ '0 0 0 225 225 225' '0 0 127 128 224 224 225' \ '104 106' '105 110' '113 119' '113 119 122' '113 127' \ '129 130 131 132 133 136 139 140' '184 185 186 187' \ '202 203 203 204 204 205 205 206 207' do set -- $locs gaps=$# IFS=- OF="helper-${*}.sh" unset IFS loc=$1; shift test "${loc}" -gt 0 && dd if=helper.sh bs=1 count="${loc}" \ of="${OF}" >/dev/null 2>&1 G=1 for N do count=$(( N - loc )) if [ "${count}" -eq 0 ] then printf '\0' >> "${OF}" else dd if=helper.sh bs=1 skip="${loc}" \ oseek="$(( loc + G ))" count="${count}" \ of="${OF}" >/dev/null 2>&1 fi loc=$N G=$(( G + 1 )) done if [ "${loc}" -lt "${size}" ] then dd if=helper.sh bs=1 skip="${loc}" \ oseek="$(( loc + G ))" of="${OF}" >/dev/null 2>&1 else printf '\0' >> "${OF}" fi test "$(stat -f %z "${OF}")" -eq "$(( size + gaps ))" || atf_fail "${locs}: build failure" atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ ${TEST_SH} "${OF}" rm -f "${OF}" done # Now just insert \0's in random locations in the script, # hoping that if the somewhat carefully selected insertions # above fail to trigger a bug, then if any (bugs) remain, # eventually Murphy will prevail, and one of these tests will catch it. test "${RANDOM}" = "${RANDOM}" && atf_skip 'ATF shell does not support $RANDOM' # To be added later... return 0 } atf_init_test_cases() { atf_add_test_case nul_elimination # atf_add_test_case file_recursion # atf_add_test_case file_string_recursion # atf_add_test_case file_recursion_nul # atf_add_test_case file_string_recursion_nul }