xref: /netbsd-src/tests/bin/sh/t_input.sh (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
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