T.misc revision 1.1.1.1.12.1 1 #!/bin/sh
2
3 echo T.misc: miscellaneous buglets now watched for
4
5 awk=${awk-../a.out}
6
7 rm -f core
8
9 echo 'The big brown over the lazy doe
10 The big brown over the lazy dog
11 x
12 The big brown over the lazy dog' >foo
13 echo 'failed
14 succeeded
15 failed
16 succeeded' >foo1
17 $awk '{ if (match($0, /^The big brown over the lazy dog/) == 0) {
18 printf("failed\n")
19 } else {
20 printf("succeeded\n")
21 }
22 } ' foo >foo2
23 cmp -s foo1 foo2 || echo 'BAD: T.misc ghosh RE bug'
24
25 echo '123
26 1234567890
27 12345678901' >foo
28 echo '12345678901' >foo1
29 $awk 'length($0) > 10' foo >foo2
30 cmp -s foo1 foo2 || echo 'BAD: T.misc last number bug'
31
32 # check some \ sequences in strings (ascii)
33 echo HIJKL >foo1
34 echo foo | $awk '{ print "H\x49\x4a\x4BL" }' >foo2
35 cmp -s foo1 foo2 || echo 'BAD: T.misc hex string cvt'
36
37 echo 012x45 >foo1
38 $awk 'BEGIN { print "0\061\62x\0645" }' >foo2
39 cmp -s foo1 foo2 || echo 'BAD: T.misc oct string cvt'
40
41 # $i++ means ($i)++
42 echo 3 5 | $awk '{ i = 1; print $i++ ; print $1, i }' >foo1
43 echo '3
44 4 1' >foo2
45 cmp -s foo1 foo2 || echo 'BAD: T.misc bad field increment'
46
47 # makes sure that fields are recomputed even if self-assignment
48 # take into account that subtracting from NF now rebuilds the record
49 echo 'a b c
50 s p q r
51 x y z' >foo
52 echo 'a
53 s p
54 x' >foo1
55 $awk '{ NF -= 2; $1 = $1; print }' <foo >foo2
56 diff foo1 foo2 || echo 1>&2 "BAD: T.misc bad field self-assignment"
57
58 echo '1
59 1' >foo1
60 $awk 'BEGIN {x = 1; print x; x = x; print x}' >foo2
61 diff foo1 foo2 || echo 1>&2 "BAD: T.misc bad self-assignment"
62
63 echo 573109312 | $awk '{print $1*4}' >foo1
64 echo 2292437248 >foo2
65 diff foo1 foo2 || echo 1>&2 "BAD: T.misc bad overflow"
66
67 # note that there are 8-bit characters in the echo
68 # some shells will probably screw this up.
69 echo '#
70 code 1
71 code 2' |
72 $awk '/^#/' >foo1
73 echo '#' >foo2
74 diff foo1 foo2 || echo 1>&2 "BAD: T.misc bad match of 8-bit char"
75
76 echo hello |
77 $awk 'BEGIN { FILENAME = "/etc/passwd" }
78 { print $0 }' >/dev/null
79 if test -r core; then echo 1>&2 "BAD: T.misc /etc/passwd dropped core"; fi
80
81 echo hello |
82 $awk ' function foo(foo) {
83 foo = 1
84 foo()
85 }
86 { foo(bar) }
87 ' >/dev/null 2>&1
88 if test -r core; then
89 echo 1>&2 "BAD: T.misc function foo(foo) dropped core"
90 rm -f core
91 fi
92
93 echo '2
94 10' |
95 $awk '{ x[NR] = $0 } # test whether $0 is NUM as well as STR
96 END { if (x[1] > x[2]) print "BAD: T.misc: $0 is not NUM" }'
97
98
99 $awk 'BEGIN {
100 npad = substr("alexander" " ",1,15)
101 print npad
102 }' >foo
103 grep '\\' foo && echo 1>&2 "BAD: T.misc alexander fails"
104
105 # This should give an error about function arguments
106 $awk '
107 function foo(x) { print "x is" x }
108 BEGIN { foo(foo) }
109 ' 2>foo
110 grep "can't use function foo" foo >/dev/null || echo 1>&2 "BAD: T.misc fcn args"
111
112
113 # gawk defref test; should give error about undefined function
114 $awk 'BEGIN { foo() }' 2>foo
115 grep "calling undefined function foo" foo >/dev/null || echo 1>&2 "BAD: T.misc undefined function"
116
117
118 # gawk arrayparm test; should give error about function
119 $awk '
120 BEGIN {
121 foo[1]=1;
122 foo[2]=2;
123 bug1(foo);
124 }
125 function bug1(i) {
126 for (i in foo) {
127 bug2(i);
128 delete foo[i];
129 print i,1,bot[1];
130 }
131 }
132 function bug2(arg) {
133 bot[arg]=arg;
134 }
135 ' 2>foo
136 grep "can.t assign to foo" foo >/dev/null || echo 1>&2 "BAD: T.misc foo bug"
137
138
139 # This should be a syntax error
140 $awk '
141 !x = y
142 ' 2>foo
143 grep "syntax error" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error !x=y fails"
144
145 # This should print bbb
146 $awk '
147 BEGIN { up[1] = "a"
148 for (i in up) gsub("a", "A", x)
149 print x x "bbb"
150 exit
151 }
152 ' >foo
153 grep bbb foo >/dev/null || echo 1>&2 "BAD: T.misc gsub failed"
154
155 echo yes |
156 $awk '
157 BEGIN {
158 printf "push return" >"/dev/null"
159 getline ans <"/dev/null"
160 } '
161 if test -r core; then echo 1>&2 "BAD: T.misc getline ans dropped core"; fi
162
163 $awk 'BEGIN { unireghf() }
164 function unireghf(hfeed) { hfeed[1] = 0 }'
165 if test -r core; then echo 1>&2 "BAD: T.misc unireghf dropped core"; fi
166
167 echo x | $awk '/[/]/' 2>foo
168 grep 'nonterminated character class' foo >/dev/null || error 'BAD: T.misc nonterminated fails'
169 if test -r core; then echo 1>&2 "BAD: T.misc nonterminated dropped core"; fi
170
171 $awk '
172 function f() { return 12345 }
173 BEGIN { printf "<%s>\n", f() }
174 ' >foo
175 grep '<12345>' foo >/dev/null || echo 'BAD: T.misc <12345> fails'
176
177 echo 'abc
178 def
179
180 ghi
181 jkl' >foo
182 $awk '
183 BEGIN { RS = ""
184 while (getline <"foo")
185 print
186 }' >foo1
187 $awk 'END {print NR}' foo1 | grep 4 >/dev/null || echo 'BAD: T.misc abcdef fails'
188
189 # Test for RS regex matching an empty record at EOF
190 echo a | $awk 1 RS='a\n' > foo1
191 cat << \EOF > foo2
192
193 EOF
194 diff foo1 foo2 || echo 'BAD: T.misc RS regex matching an empty record at EOF fails'
195
196 # Test for RS regex being reapplied
197 echo aaa1a2a | $awk 1 RS='^a' >foo1
198 cat << \EOF > foo2
199
200 aa1a2a
201
202 EOF
203 diff foo1 foo2 || echo 'BAD: T.misc ^regex reapplied fails'
204
205 # ^-anchored RS matching should be active at the start of each input file
206 tee foo1 foo2 >foo3 << \EOF
207 aaa
208 EOF
209 $awk 1 RS='^a' foo1 foo2 foo3 >foo4
210 cat << \EOF > foo5
211
212 aa
213
214
215 aa
216
217
218 aa
219
220 EOF
221 diff foo4 foo5 || echo 'BAD: T.misc ^RS matches the start of every input file fails'
222
223 # The following should not produce a warning about changing a constant
224 # nor about a curdled tempcell list
225 $awk 'function f(x) { x = 2 }
226 BEGIN { f(1) }' >foo
227 grep '^' foo && echo 'BAD: test constant change fails'
228
229 # The following should not produce a warning about a curdled tempcell list
230 $awk 'function f(x) { x }
231 BEGIN { f(1) }' >foo
232 grep '^' foo && echo 'BAD: test tempcell list fails'
233
234 $awk 'BEGIN { print 9, a=10, 11; print a; exit }' >foo1
235 echo '9 10 11
236 10' >foo2
237 diff foo1 foo2 || echo 'BAD: T.misc (embedded expression)'
238
239 echo "abc defgh ijkl" | $awk '
240 { $1 = ""; line = $0; print line; print $0; $0 = line; print $0 }' >foo1
241 echo " defgh ijkl
242 defgh ijkl
243 defgh ijkl" >foo2
244 diff foo1 foo2 || echo 'BAD: T.misc (assignment to $0)'
245
246 $awk '
247 function min(a, b)
248 {
249 if (a < b)
250 return a
251 else
252 return b
253 }
254 BEGIN { exit }
255 '
256 if test -r core; then echo 1>&2 "BAD: T.misc function min dropped core"; fi
257
258 # The following should not give a syntax error message:
259 $awk '
260 function expand(chart) {
261 getline chart < "CHAR.ticks"
262 }
263 ' >foo
264 grep '^' foo >/dev/null && echo 'BAD: T.misc expand error'
265
266 $awk 'BEGIN { print 1e40 }' >/dev/null
267 if test -r core; then echo 1>&2 "BAD: T.misc 1E40 dropped core"; fi
268
269 # The following syntax error should not dump core:
270 $awk '
271 $NF==3 {first=1}
272 $NF==2 && first==0 && (abs($1-o1)>120||abs($2-o2)>120) {print $0}
273 $NF==2 {o1=%1; o2=$2; first=0}
274 ' 2>/dev/null
275 if test -r core; then echo 1>&2 "BAD: T.misc first/abs dropped core"; fi
276
277 # The following syntax error should not dump core:
278 $awk '{ n = split($1, address, !); print address[1] }' 2>foo
279 grep 'illegal statement' foo >/dev/null || echo 'BAD: T.misc split error'
280 if test -r core; then echo 1>&2 "BAD: T.misc split! dropped core"; fi
281
282 # The following should cause a syntax error message
283 $awk 'BEGIN {"hello"}' 2>foo
284 grep 'illegal statement' foo >/dev/null || echo 'BAD: T.misc hello error'
285
286 # The following should give a syntax error message:
287 $awk '
288 function pile(c, r) {
289 r = ++pile[c]
290 }
291
292 { pile($1) }
293 ' 2>foo
294 grep 'context is' foo >/dev/null || echo 'BAD: T.misc pile error'
295
296 # This should complain about missing atan2 argument:
297 $awk 'BEGIN { atan2(1) }' 2>foo
298 grep 'requires two arg' foo >/dev/null || echo 'BAD: T.misc atan2 error'
299
300 # This should not core dump:
301 $awk 'BEGIN { f() }
302 function f(A) { delete A[1] }
303 '
304 if test -r core; then echo 1>&2 "BAD: T.misc delete dropped core"; fi
305
306 # nasty one: should not be able to overwrite constants
307 $awk 'BEGIN { gsub(/ana/,"anda","banana")
308 printf "the monkey ate a %s\n", "banana" }
309 ' >/dev/null 2>foo
310 grep 'syntax error' foo >/dev/null || echo 'BAD: T.misc gsub banana error'
311
312 # nasty one: should not be able to overwrite constants
313 $awk 'BEGIN { sub(/ana/,"anda","banana")
314 printf "the monkey ate a %s\n", "banana" }
315 ' >/dev/null 2>foo
316 grep 'syntax error' foo >/dev/null || echo 'BAD: T.misc sub banana error'
317
318 # line numbers used to double-count comments
319 $awk '#
320 #
321 #
322 /x
323 ' >/dev/null 2>foo
324 grep 'line [45]' foo >/dev/null || echo 'BAD: T.misc lineno'
325
326 echo 'x
\y' >foo1
330 $awk 'BEGIN { print "x\f\r\b\v\a\\y" }' >foo2
331 cmp -s foo1 foo2 || echo 'BAD: T.misc weird chars'
332
333 echo 0 >foo1
334 $awk ' BEGIN { exit }
335 { print }
336 END { print NR }' >foo2
337 cmp -s foo1 foo2 || echo 'BAD: T.misc BEGIN exit'
338
339 echo 1 >foo1
340 $awk ' { exit }
341 END { print NR }' /etc/passwd >foo2
342 cmp -s foo1 foo2 || echo 'BAD: T.misc immmediate exit'
343
344 echo 1 >foo1
345 $awk ' {i = 1; while (i <= NF) {if (i == NF) exit; i++ } }
346 END { print NR }' /etc/passwd >foo2
347 cmp -s foo1 foo2 || echo 'BAD: T.misc immmediate exit 2'
348
349 echo 1 >foo1
350 $awk ' function f() {
351 i = 1; while (i <= NF) {if (i == NF) return NR; i++ }
352 }
353 { if (f() == 1) exit }
354 END { print NR }' /etc/passwd >foo2
355 cmp -s foo1 foo2 || echo 'BAD: T.misc while return'
356
357 echo 1 >foo1
358 $awk ' function f() {
359 split("a b c", arr)
360 for (i in arr) {if (i == 3) return NR; i++ }
361 }
362 { if (f() == 1) exit }
363 END { print NR }' /etc/passwd >foo2
364 cmp -s foo1 foo2 || echo 'BAD: T.misc while return'
365
366 echo 1 >foo1
367 $awk ' {i = 1; do { if (i == NF) exit; i++ } while (i <= NF) }
368 END { print NR }' /etc/passwd >foo2
369 cmp -s foo1 foo2 || echo 'BAD: T.misc immmediate exit 3'
370
371 echo 1 >foo1
372 $awk ' function f() {
373 i = 1; do { if (i == NF) return NR; i++ } while (i <= NF)
374 }
375 { if (f() == 1) exit }
376 END { print NR }' /etc/passwd >foo2
377 cmp -s foo1 foo2 || echo 'BAD: T.misc do return'
378
379 echo 1 >foo1
380 $awk ' {i = 1; do { if (i == NF) break; i++ } while (i <= NF); exit }
381 END { print NR }' /etc/passwd >foo2
382 cmp -s foo1 foo2 || echo 'BAD: T.misc immmediate exit 4'
383
384 echo 1 >foo1
385 $awk ' { n = split($0, x)
386 for (i in x) {
387 if (i == 1)
388 exit } }
389 END { print NR }' /etc/passwd >foo2
390 cmp -s foo1 foo2 || echo 'BAD: T.misc immmediate exit 5'
391
392 echo XXXXXXXX >foo1
393 $awk 'BEGIN { s = "ab\fc\rd\be"
394 t = s; gsub("[" s "]", "X", t); print t }' >foo2
395 cmp -s foo1 foo2 || echo 'BAD: T.misc weird escapes in char class'
396
397 $awk '{}' /etc/passwd glop/glop >foo 2>foo2
398 grep "can't open.*glop" foo2 >/dev/null || echo "BAD: T.misc can't open"
399
400 echo '
401
402
403 a
404 aa
405
406 b
407
408
409 c
410
411 ' >foo
412 echo 3 >foo1
413 $awk 'BEGIN { RS = "" }; END { print NR }' foo >foo2
414 cmp -s foo1 foo2 || echo 'BAD: T.misc RS botch'
415
416 $awk 'BEGIN \
417 {
418 print "hello, world"
419 }
420 }}}' >foo1 2>foo2
421 grep 'source line 4' foo2 >/dev/null 2>&1 || echo 'BAD: T.misc continuation line number'
422
423
424 echo 111 222 333 >foo
425 $awk '{ f[1]=1; f[2]=2; print $f[1], $f[1]++, $f[2], f[1], f[2] }' foo >foo2
426 echo 111 111 222 2 2 >foo1
427 cmp -s foo1 foo2 || echo 'BAD: T.misc $f[1]++'
428
429
430 # These should be syntax errors
431 $awk . 2>foo
432 grep "syntax error" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error . fails"
433
434 $awk .. 2>foo
435 grep "syntax error" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error .. fails"
436
437 $awk .E. 2>foo
438 grep "syntax error" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error .E. fails"
439
440 $awk .++. 2>foo
441 grep "syntax error" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error .++. fails"
442
443
444
445 # These should be syntax errors
446 $awk '$' 2>foo
447 grep "unexpected" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error $ fails"
448
449 $awk '{print $' 2>foo
450 grep "unexpected" foo >/dev/null || echo 1>&2 "BAD: T.misc syntax error $2 fails"
451
452 $awk '"' 2>foo
453 grep "non-terminated" foo >/dev/null || echo 1>&2 "BAD: T.misc bare quote fails"
454
455
456 # %c of 0 is explicit null byte
457
458 ./echo '3' >foo1
459 $awk 'BEGIN {printf("%c%c\n", 0, 0) }' | wc | $awk '{print $3}' >foo2
460 cmp -s foo1 foo2 || echo 'BAD: T.misc null byte'
461
462 # non-terminated RE
463
464 $awk /xyz >foo 2>&1
465 grep "non-terminated" foo >/dev/null || echo 1>&2 "BAD: T.misc non-terminated RE"
466
467 # next several were infinite loops, found by brian tsang.
468 # this is his example:
469
470 $awk 'BEGIN {
471 switch (substr("x",1,1)) {
472 case /ask.com/:
473 break
474 case "google":
475 break
476 }
477 }' >foo 2>&1
478 grep "illegal statement" foo >/dev/null || echo 1>&2 "BAD: T.misc looping syntax error 1"
479
480 $awk 'BEGIN { s { c /./ } }' >foo 2>&1
481 grep "illegal statement" foo >/dev/null || echo 1>&2 "BAD: T.misc looping syntax error 2"
482
483 $awk 'BEGIN { s { c /../ } }' >foo 2>&1
484 grep "illegal statement" foo >/dev/null || echo 1>&2 "BAD: T.misc looping syntax error 3"
485
486 $awk 'BEGIN {printf "%2$s %1$s\n", "a", "b"}' >foo 2>&1
487 grep "'$' not permitted in awk formats" foo >/dev/null || echo 1>&2 "BAD: T.misc '$' not permitted in formats"
488
489 echo 'a
490 b c
491 de fg hi' >foo0
492 $awk 'END { print NF, $0 }' foo0 >foo1
493 awk '{ print NF, $0 }' foo0| tail -1 >foo2
494 cmp -s foo1 foo2 || echo 'BAD: T.misc END must preserve $0'
495
496 echo 'fg hi' >foo0
497 $awk 'END { print NF, $0 }' foo0 >foo1
498 awk '{ print NF, $0 }' foo0| tail -1 >foo2
499 cmp -s foo1 foo2 || echo 'BAD: T.misc END must preserve $0'
500
501 echo '' >foo0
502 $awk 'END { print NF, $0 }' foo0 >foo1
503 awk '{ print NF, $0 }' foo0| tail -1 >foo2
504 cmp -s foo1 foo2 || echo 'BAD: T.misc END must preserve $0'
505
506 # Check for nonzero exit status on I/O error.
507 echo 'E 2' >foo1
508 (trap '' PIPE; "$awk" 'BEGIN { print "hi"; }' 2>/dev/null; echo "E $?" >foo2) | :
509 cmp -s foo1 foo2 || echo 'BAD: T.misc exit status on I/O error'
510
511 # Check for clobbering of the lexer's regular expression buffer.
512 # If the output is "a1" instead of "1b", /b/ clobbered /a/.
513 echo 1b >foo1
514 echo ab | $awk '{ sub(/a/, "b" ~ /b/); print }' >foo2
515 cmp -s foo1 foo2 || echo 'BAD: T.misc lexer regex buffer clobbered'
516
517 # Check handling of octal \OOO and hex \xHH esc. seqs. in strings.
518 echo 'hello888
519 hello
520 hello
521 helloxGOO
522 hello
523 0A' > foo1
524 $awk 'BEGIN { print "hello\888" }' > foo2
525 $awk 'BEGIN { print "hello\x000A" }' >> foo2
526 $awk 'BEGIN { printf "hello\x0A" }' >> foo2
527 $awk 'BEGIN { print "hello\xGOO" }' >> foo2
528 $awk 'BEGIN { print "hello\x0A0A" }' >> foo2
529 cmp -s foo1 foo2 || echo 'BAD: T.misc escape sequences in strings mishandled'
530