1*00937795Skre# $NetBSD: t_input.sh,v 1.2 2024/10/14 12:26:28 kre Exp $ 26974a2b2Skre# 36974a2b2Skre# Copyright (c) 2021 The NetBSD Foundation, Inc. 46974a2b2Skre# All rights reserved. 56974a2b2Skre# 66974a2b2Skre# Redistribution and use in source and binary forms, with or without 76974a2b2Skre# modification, are permitted provided that the following conditions 86974a2b2Skre# are met: 96974a2b2Skre# 1. Redistributions of source code must retain the above copyright 106974a2b2Skre# notice, this list of conditions and the following disclaimer. 116974a2b2Skre# 2. Redistributions in binary form must reproduce the above copyright 126974a2b2Skre# notice, this list of conditions and the following disclaimer in the 136974a2b2Skre# documentation and/or other materials provided with the distribution. 146974a2b2Skre# 156974a2b2Skre# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 166974a2b2Skre# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 176974a2b2Skre# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 186974a2b2Skre# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 196974a2b2Skre# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 206974a2b2Skre# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 216974a2b2Skre# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 226974a2b2Skre# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 236974a2b2Skre# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 246974a2b2Skre# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 256974a2b2Skre# POSSIBILITY OF SUCH DAMAGE. 266974a2b2Skre# 276974a2b2Skre# the implementation of "sh" to test 286974a2b2Skre: ${TEST_SH:="/bin/sh"} 296974a2b2Skre 306974a2b2Skre# This set of tests checks the low level shell (script) input 316974a2b2Skre# systrem (reading script files, nested files, fines read while 326974a2b2Skre# reading strings, ..) and correctly dropping nul bytes from file data 336974a2b2Skre 346974a2b2Skre# other shell input (the read builtin for example) is not covered here. 356974a2b2Skre 366974a2b2Skreatf_test_case nul_elimination 376974a2b2Skre 386974a2b2Skrenul_elimination_head() { 396974a2b2Skre atf_set "descr" "verifies that \0 chars in input are properly ignored" 406974a2b2Skre} 416974a2b2Skre 426974a2b2Skrenul_elimination_body() { 436974a2b2Skre atf_require_prog printf 446974a2b2Skre atf_require_prog stat 456974a2b2Skre 466974a2b2Skre # these really should always be present, but... 476974a2b2Skre atf_require_prog dd 486974a2b2Skre atf_require_prog cat 496974a2b2Skre atf_require_prog rm 506974a2b2Skre 51*00937795Skre atf_expect_fail "nuls are now errors, not ignored, revisit later" 52*00937795Skre 536974a2b2Skre # please do not make even trivial changes (like correcting spelling) 546974a2b2Skre # to the following script without taking care to fix the following 556974a2b2Skre # tests, even minor changes can defeat the purpose of the test 566974a2b2Skre cat > helper.sh <<- EOF 576974a2b2Skre # a line of commentary that does nothing 586974a2b2Skre # another line of comments (these just make the script bigger) 596974a2b2Skre printf A 606974a2b2Skre eval "printf B" 616974a2b2Skre if printf C 626974a2b2Skre then 636974a2b2Skre printf D 646974a2b2Skre fi 656974a2b2Skre for x in E F G H 666974a2b2Skre do 676974a2b2Skre printf "\$x" 686974a2b2Skre done 696974a2b2Skre printf \\ 706974a2b2Skre I 716974a2b2Skre printf '\n' 726974a2b2Skre exit 0 736974a2b2Skre EOF 746974a2b2Skre 756974a2b2Skre # this first test simply verifies that the script works as 766974a2b2Skre # expected, should it fail, it is not a problem with \0 chars 776974a2b2Skre atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 786974a2b2Skre ${TEST_SH} helper.sh 796974a2b2Skre 806974a2b2Skre size=$(stat -f %z helper.sh) 816974a2b2Skre 826974a2b2Skre # Now insert \0 chars at specifically chosen spots in script 836974a2b2Skre for loc in 0 10 40 41 42 104 105 106 110 111 112 113 119 127 128 \ 846974a2b2Skre 144 150 162 165 168 187 202 203 204 205 214 215 216 224 225 856974a2b2Skre do 866974a2b2Skre # at each location try varying the number of \0's inserted 876974a2b2Skre for N in 1 2 4 7 886974a2b2Skre do 896974a2b2Skre OF="helper-${N}@${loc}.sh" 906974a2b2Skre 916974a2b2Skre test "${loc}" -gt 0 && 926974a2b2Skre dd if=helper.sh bs=1 count="${loc}" \ 936974a2b2Skre of="${OF}" >/dev/null 2>&1 946974a2b2Skre dd if=helper.sh bs=1 skip="${loc}" \ 956974a2b2Skre oseek="$(( loc + N ))" \ 966974a2b2Skre of="${OF}" >/dev/null 2>&1 976974a2b2Skre 986974a2b2Skre test "$(stat -f %z "${OF}")" -eq "$(( size + N ))" || 996974a2b2Skre atf_fail "${N}@${loc}: build failure" 1006974a2b2Skre 1016974a2b2Skre atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 1026974a2b2Skre ${TEST_SH} "${OF}" 1036974a2b2Skre 1046974a2b2Skre rm -f "${OF}" 1056974a2b2Skre done 1066974a2b2Skre 1076974a2b2Skre done 1086974a2b2Skre 1096974a2b2Skre # Next insert \0 chars at multiple chosen locations 1106974a2b2Skre # nb: offsets in each arg must be non-decreasing 1116974a2b2Skre for locs in '0 225' '0 224' '0 127 223' '0 10 15' '0 48 55' \ 1126974a2b2Skre '0 0 0 225 225 225' '0 0 127 128 224 224 225' \ 1136974a2b2Skre '104 106' '105 110' '113 119' '113 119 122' '113 127' \ 1146974a2b2Skre '129 130 131 132 133 136 139 140' '184 185 186 187' \ 1156974a2b2Skre '202 203 203 204 204 205 205 206 207' 1166974a2b2Skre do 1176974a2b2Skre set -- $locs 1186974a2b2Skre gaps=$# 1196974a2b2Skre 1206974a2b2Skre IFS=- 1216974a2b2Skre OF="helper-${*}.sh" 1226974a2b2Skre unset IFS 1236974a2b2Skre 1246974a2b2Skre loc=$1; shift 1256974a2b2Skre test "${loc}" -gt 0 && 1266974a2b2Skre dd if=helper.sh bs=1 count="${loc}" \ 1276974a2b2Skre of="${OF}" >/dev/null 2>&1 1286974a2b2Skre G=1 1296974a2b2Skre for N 1306974a2b2Skre do 1316974a2b2Skre count=$(( N - loc )) 1326974a2b2Skre if [ "${count}" -eq 0 ] 1336974a2b2Skre then 1346974a2b2Skre printf '\0' >> "${OF}" 1356974a2b2Skre else 1366974a2b2Skre dd if=helper.sh bs=1 skip="${loc}" \ 1376974a2b2Skre oseek="$(( loc + G ))" count="${count}" \ 1386974a2b2Skre of="${OF}" >/dev/null 2>&1 1396974a2b2Skre fi 1406974a2b2Skre loc=$N 1416974a2b2Skre G=$(( G + 1 )) 1426974a2b2Skre done 1436974a2b2Skre 1446974a2b2Skre if [ "${loc}" -lt "${size}" ] 1456974a2b2Skre then 1466974a2b2Skre dd if=helper.sh bs=1 skip="${loc}" \ 1476974a2b2Skre oseek="$(( loc + G ))" of="${OF}" >/dev/null 2>&1 1486974a2b2Skre else 1496974a2b2Skre printf '\0' >> "${OF}" 1506974a2b2Skre fi 1516974a2b2Skre 1526974a2b2Skre test "$(stat -f %z "${OF}")" -eq "$(( size + gaps ))" || 1536974a2b2Skre atf_fail "${locs}: build failure" 1546974a2b2Skre 1556974a2b2Skre atf_check -s exit:0 -o 'inline:ABCDEFGHI\n' -e empty \ 1566974a2b2Skre ${TEST_SH} "${OF}" 1576974a2b2Skre 1586974a2b2Skre rm -f "${OF}" 1596974a2b2Skre done 1606974a2b2Skre 1616974a2b2Skre # Now just insert \0's in random locations in the script, 1626974a2b2Skre # hoping that if the somewhat carefully selected insertions 1636974a2b2Skre # above fail to trigger a bug, then if any (bugs) remain, 1646974a2b2Skre # eventually Murphy will prevail, and one of these tests will catch it. 1656974a2b2Skre 1666974a2b2Skre test "${RANDOM}" = "${RANDOM}" && 1676974a2b2Skre atf_skip 'ATF shell does not support $RANDOM' 1686974a2b2Skre 1696974a2b2Skre # To be added later... 1706974a2b2Skre 1716974a2b2Skre return 0 1726974a2b2Skre} 1736974a2b2Skre 1746974a2b2Skreatf_init_test_cases() { 1756974a2b2Skre atf_add_test_case nul_elimination 1766974a2b2Skre # atf_add_test_case file_recursion 1776974a2b2Skre # atf_add_test_case file_string_recursion 1786974a2b2Skre # atf_add_test_case file_recursion_nul 1796974a2b2Skre # atf_add_test_case file_string_recursion_nul 1806974a2b2Skre} 181