t_errors.sh revision 1.4 1 #! /bin/sh
2 # $NetBSD: t_errors.sh,v 1.4 2021/10/17 18:13:00 rillig Exp $
3 #
4 # Copyright (c) 2021 The NetBSD Foundation, Inc.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 # POSSIBILITY OF SUCH DAMAGE.
27 #
28 # $FreeBSD$
29
30 # Tests for error handling in indent.
31
32 indent=$(atf_config_get usr.bin.indent.test_indent /usr/bin/indent)
33 nl='
34 '
35
36 expect_error()
37 {
38 local msg
39
40 msg="$1"
41 shift
42
43 atf_check -s 'exit:1' \
44 -e "inline:$msg$nl" \
45 "$indent" "$@"
46 }
47
48 atf_test_case 'option_unknown'
49 option_unknown_body()
50 {
51 expect_error \
52 'indent: Command line: unknown option "-Z-unknown"' \
53 -Z-unknown
54 }
55
56 atf_test_case 'option_bool_trailing_garbage'
57 option_bool_trailing_garbage_body()
58 {
59 expect_error \
60 'indent: Command line: unknown option "-bacchus"' \
61 -bacchus
62 }
63
64 atf_test_case 'option_int_missing_parameter'
65 option_int_missing_parameter_body()
66 {
67 expect_error \
68 'indent: Command line: option "-ts" requires an integer parameter' \
69 -tsx
70 }
71
72 atf_test_case 'option_profile_not_found'
73 option_profile_not_found_body()
74 {
75 expect_error \
76 'indent: profile ./nonexistent: No such file or directory' \
77 -P./nonexistent
78 }
79
80 atf_test_case 'option_typedefs_not_found'
81 option_typedefs_not_found_body()
82 {
83 expect_error \
84 'indent: cannot open file ./nonexistent' \
85 -U./nonexistent
86 }
87
88 atf_test_case 'option_tabsize_negative'
89 option_tabsize_negative_body()
90 {
91 expect_error \
92 'indent: Command line: option "-ts" requires an integer parameter' \
93 -ts-1
94 }
95
96 atf_test_case 'option_tabsize_zero'
97 option_tabsize_zero_body()
98 {
99 expect_error \
100 'indent: Command line: invalid argument "0" for option "-ts"' \
101 -ts0
102 }
103
104 atf_test_case 'option_tabsize_large'
105 option_tabsize_large_body()
106 {
107 # Integer overflow, on both ILP32 and LP64 platforms.
108 expect_error \
109 'indent: Command line: invalid argument "81" for option "-ts"' \
110 -ts81
111 }
112
113 atf_test_case 'option_tabsize_very_large'
114 option_tabsize_very_large_body()
115 {
116 # Integer overflow, on both ILP32 and LP64 platforms.
117 expect_error \
118 'indent: Command line: invalid argument "3000000000" for option "-ts"' \
119 -ts3000000000
120 }
121
122 atf_test_case 'option_indent_size_zero'
123 option_indent_size_zero_body()
124 {
125 expect_error \
126 'indent: Command line: invalid argument "0" for option "-i"' \
127 -i0
128 }
129
130 atf_test_case 'option_int_trailing_garbage'
131 option_int_trailing_garbage_body()
132 {
133 expect_error \
134 'indent: Command line: invalid argument "3garbage" for option "-i"' \
135 -i3garbage
136 }
137
138 atf_test_case 'option_buffer_overflow'
139 option_buffer_overflow_body()
140 {
141 opt='12345678123456781234567812345678' # 32
142 opt="$opt$opt$opt$opt$opt$opt$opt$opt" # 256
143 opt="$opt$opt$opt$opt$opt$opt$opt$opt" # 2048
144 opt="$opt$opt$opt$opt$opt$opt$opt$opt" # 16384
145 printf '%s\n' "-$opt" > indent.pro
146
147 # TODO: The call to 'diag' should be replaced with 'errx'.
148 expect_error \
149 'Error@1: buffer overflow in indent.pro, starting with '\''-123456781'\''' \
150 -Pindent.pro
151 }
152
153 atf_test_case 'option_special_missing_param'
154 option_special_missing_param_body()
155 {
156 # TODO: Write '-cli' instead of only 'cli'.
157 expect_error \
158 'indent: Command line: ``cli'\'\'' requires a parameter' \
159 -cli
160
161 expect_error \
162 'indent: Command line: ``T'\'\'' requires a parameter' \
163 -T
164
165 expect_error \
166 'indent: Command line: ``U'\'\'' requires a parameter' \
167 -U
168 }
169
170 atf_test_case 'unterminated_comment'
171 unterminated_comment_body()
172 {
173 echo '/*' > comment.c
174
175 atf_check -s 'exit:1' \
176 -o 'inline:/*'"$nl"' *'"$nl" \
177 -e 'inline:/**INDENT** Error@2: Unterminated comment */'"$nl" \
178 "$indent" -st < comment.c
179 }
180
181 atf_test_case 'in_place_wrong_backup'
182 in_place_wrong_backup_body()
183 {
184 cat <<-\EOF > code.c
185 int decl;
186 EOF
187 cp code.c code.c.orig
188
189 # Due to the strange backup suffix '/subdir', indent tries to create
190 # a file named 'code.c/subdir', but 'code.c' is already a regular
191 # file, not a directory.
192 atf_check -s 'exit:1' \
193 -e 'inline:indent: code.c/subdir: Not a directory'"$nl" \
194 env SIMPLE_BACKUP_SUFFIX="/subdir" "$indent" code.c
195
196 # Since there was an early error, the original file is kept as is.
197 atf_check -o 'file:code.c.orig' \
198 cat code.c
199 }
200
201 atf_test_case 'argument_input_enoent'
202 argument_input_enoent_body()
203 {
204 atf_check -s 'exit:1' \
205 -e 'inline:indent: ./nonexistent.c: No such file or directory'"$nl" \
206 "$indent" ./nonexistent.c
207 }
208
209 atf_test_case 'argument_output_equals_input_name'
210 argument_output_equals_input_name_body()
211 {
212 echo '/* comment */' > code.c
213
214 atf_check -s 'exit:1' \
215 -e 'inline:indent: input and output files must be different'"$nl" \
216 "$indent" code.c code.c
217 }
218
219 atf_test_case 'argument_output_equals_input_file'
220 argument_output_equals_input_file_body()
221 {
222 echo '/* comment */' > code.c
223
224 atf_check \
225 "$indent" code.c ./code.c
226
227 # Oops, the file has become empty since the output is first emptied,
228 # before reading any of the input.
229 atf_check \
230 cat code.c
231 }
232
233 atf_test_case 'argument_output_enoent'
234 argument_output_enoent_body()
235 {
236 expect_error \
237 'indent: subdir/nonexistent.c: No such file or directory' \
238 /dev/null subdir/nonexistent.c
239 }
240
241 atf_test_case 'argument_too_many'
242 argument_too_many_body()
243 {
244 echo '/* comment */' > arg1.c
245
246 expect_error \
247 'indent: unknown parameter: arg3.c' \
248 arg1.c arg2.c arg3.c arg4.c
249 }
250
251 atf_test_case 'unexpected_end_of_file'
252 unexpected_end_of_file_body()
253 {
254 echo 'struct{' > code.c
255
256 expect_error \
257 'Error@1: Stuff missing from end of file' \
258 code.c
259
260 atf_check \
261 -o 'inline:struct {'"$nl" \
262 cat code.c
263 }
264
265 atf_test_case 'unexpected_closing_brace_top_level'
266 unexpected_closing_brace_top_level_body()
267 {
268 echo '}' > code.c
269
270 expect_error \
271 'Error@1: Statement nesting error' \
272 code.c
273 atf_check \
274 -o 'inline:}'"$nl" \
275 cat code.c
276 }
277
278 atf_test_case 'unexpected_closing_brace_decl'
279 unexpected_closing_brace_decl_body()
280 {
281 echo 'int i = 3};' > code.c
282
283 expect_error \
284 'Error@1: Statement nesting error' \
285 code.c
286 # Despite the error message, the original file got overwritten with a
287 # best-effort rewrite of the code.
288 atf_check \
289 -o 'inline:int i = 3};'"$nl" \
290 cat code.c
291 }
292
293 atf_test_case 'preprocessing_overflow'
294 preprocessing_overflow_body()
295 {
296 cat <<-\EOF > code.c
297 #if 1
298 #if 2
299 #if 3
300 #if 4
301 #if 5
302 #if 6
303 #endif 6
304 #endif 5
305 #endif 4
306 #endif 3
307 #endif 2
308 #endif 1
309 #endif too much
310 EOF
311 cat <<-\EOF > stderr.exp
312 Error@6: #if stack overflow
313 Error@12: Unmatched #endif
314 Error@13: Unmatched #endif
315 EOF
316
317 atf_check -s 'exit:1' \
318 -e 'file:stderr.exp' \
319 "$indent" code.c
320 }
321
322 atf_test_case 'preprocessing_unrecognized'
323 preprocessing_unrecognized_body()
324 {
325 cat <<-\EOF > code.c
326 #unknown
327 # 3 "file.c"
328 #elif 3
329 #else
330 EOF
331 cat <<-\EOF > stderr.exp
332 Error@1: Unrecognized cpp directive
333 Error@2: Unrecognized cpp directive
334 Error@3: Unmatched #elif
335 Error@4: Unmatched #else
336 EOF
337
338 atf_check -s 'exit:1' \
339 -e 'file:stderr.exp' \
340 "$indent" code.c
341 }
342
343 atf_init_test_cases()
344 {
345 atf_add_test_case 'option_unknown'
346 atf_add_test_case 'option_bool_trailing_garbage'
347 atf_add_test_case 'option_int_missing_parameter'
348 atf_add_test_case 'option_profile_not_found'
349 atf_add_test_case 'option_buffer_overflow'
350 atf_add_test_case 'option_typedefs_not_found'
351 atf_add_test_case 'option_special_missing_param'
352 atf_add_test_case 'option_tabsize_negative'
353 atf_add_test_case 'option_tabsize_zero'
354 atf_add_test_case 'option_tabsize_large'
355 atf_add_test_case 'option_tabsize_very_large'
356 atf_add_test_case 'option_int_trailing_garbage'
357 atf_add_test_case 'option_indent_size_zero'
358 atf_add_test_case 'unterminated_comment'
359 atf_add_test_case 'in_place_wrong_backup'
360 atf_add_test_case 'argument_input_enoent'
361 atf_add_test_case 'argument_output_equals_input_name'
362 atf_add_test_case 'argument_output_equals_input_file'
363 atf_add_test_case 'argument_output_enoent'
364 atf_add_test_case 'argument_too_many'
365 atf_add_test_case 'unexpected_end_of_file'
366 atf_add_test_case 'unexpected_closing_brace_top_level'
367 atf_add_test_case 'unexpected_closing_brace_decl'
368 atf_add_test_case 'preprocessing_overflow'
369 atf_add_test_case 'preprocessing_unrecognized'
370 }
371