OILS / spec / bugs.test.sh View on Github | oilshell.org

496 lines, 198 significant
1## compare_shells: bash dash mksh zsh ash
2## oils_failures_allowed: 0
3
4# TODO: case #25 need this locally, but not in CI?
5# oils_cpp_failures_allowed: 1
6
7#### echo keyword
8echo done
9## stdout: done
10
11#### if/else
12if false; then
13 echo THEN
14else
15 echo ELSE
16fi
17## stdout: ELSE
18
19#### Turn an array into an integer.
20a=(1 2 3)
21(( a = 42 ))
22echo $a
23## stdout: 42
24## N-I dash/ash stdout-json: ""
25## N-I dash/ash status: 2
26
27
28#### assign readonly -- one line
29readonly x=1; x=2; echo hi
30## status: 1
31## OK dash/mksh/ash status: 2
32## STDOUT:
33## END
34
35#### assign readonly -- multiple lines
36readonly x=1
37x=2
38echo hi
39## status: 1
40## OK dash/mksh/ash status: 2
41## STDOUT:
42## END
43## BUG bash status: 0
44## BUG bash STDOUT:
45hi
46## END
47
48#### assign readonly -- multiple lines -- set -o posix
49set -o posix
50readonly x=1
51x=2
52echo hi
53## status: 1
54## OK dash/mksh/ash status: 2
55## STDOUT:
56## END
57
58#### unset readonly -- one line
59readonly x=1; unset x; echo hi
60## STDOUT:
61hi
62## END
63## OK dash/ash status: 2
64## OK zsh status: 1
65## OK dash/ash stdout-json: ""
66## OK zsh stdout-json: ""
67
68#### unset readonly -- multiple lines
69readonly x=1
70unset x
71echo hi
72## OK dash/ash status: 2
73## OK zsh status: 1
74## OK dash/ash stdout-json: ""
75## OK zsh stdout-json: ""
76
77#### First word like foo$x() and foo$[1+2] (regression)
78
79# Problem: $x() func call broke this error message
80foo$identity('z')
81
82foo$[1+2]
83
84echo DONE
85
86## status: 2
87## OK mksh/zsh status: 1
88## STDOUT:
89## END
90
91#### Function names
92foo$x() {
93 echo hi
94}
95
96foo $x() {
97 echo hi
98}
99
100## status: 2
101## OK mksh/zsh status: 1
102## BUG zsh status: 0
103## STDOUT:
104## END
105
106
107#### file with NUL byte
108echo -e 'echo one \0 echo two' > tmp.sh
109$SH tmp.sh
110## STDOUT:
111one echo two
112## END
113## OK osh STDOUT:
114one
115## END
116## N-I dash stdout-json: ""
117## N-I dash status: 127
118## OK bash stdout-json: ""
119## OK bash status: 126
120## OK zsh stdout-json: "one \u0000echo two\n"
121
122#### fastlex: PS1 format string that's incomplete / with NUL byte
123case $SH in bash) exit ;; esac
124
125x=$'\\D{%H:%M' # leave off trailing }
126echo x=${x@P}
127
128## STDOUT:
129x=\D{%H:%M
130## END
131
132# bash just ignores the missing }
133## BUG bash stdout-json: ""
134
135# These shells don't understand @P
136
137## N-I dash/ash stdout-json: ""
138## N-I dash/ash status: 2
139
140## N-I zsh stdout-json: ""
141## N-I zsh status: 1
142
143
144#### 'echo' and printf fail on writing to full disk
145
146# Inspired by https://blog.sunfishcode.online/bugs-in-hello-world/
147
148echo hi > /dev/full
149echo status=$?
150
151printf '%s\n' hi > /dev/full
152echo status=$?
153
154## STDOUT:
155status=1
156status=1
157## END
158
159#### other builtins fail on writing to full disk
160
161type echo > /dev/full
162echo status=$?
163
164# other random builtin
165ulimit -a > /dev/full
166echo status=$?
167
168## STDOUT:
169status=1
170status=1
171## END
172
173## BUG mksh/zsh STDOUT:
174status=0
175status=0
176## END
177
178#### subshell while running a script (regression)
179# Ensures that spawning a subshell doesn't cause a seek on the file input stream
180# representing the current script (issue #1233).
181cat >tmp.sh <<'EOF'
182echo start
183(:)
184echo end
185EOF
186$SH tmp.sh
187## STDOUT:
188start
189end
190## END
191
192#### for loop (issue #1446)
193case $SH in (dash|mksh|ash) exit ;; esac
194
195for (( n=0; n<(3-(1)); n++ )) ; do echo $n; done
196
197## STDOUT:
1980
1991
200## END
201## N-I dash/mksh/ash STDOUT:
202## END
203
204
205
206#### for loop 2 (issue #1446)
207case $SH in (dash|mksh|ash) exit ;; esac
208
209
210for (( n=0; n<(3- (1)); n++ )) ; do echo $n; done
211
212## STDOUT:
2130
2141
215## END
216## N-I dash/mksh/ash STDOUT:
217## END
218
219#### autoconf word split (#1449)
220
221mysed() {
222 for line in "$@"; do
223 echo "[$line]"
224 done
225}
226
227sedinputs="f1 f2"
228sedscript='my sed command'
229
230# Parsed and evaluated correctly: with word_part.EscapedLiteral \"
231
232x=$(eval "mysed -n \"\$sedscript\" $sedinputs")
233echo '--- $()'
234echo "$x"
235
236# With backticks, the \" gets lost somehow
237
238x=`eval "mysed -n \"\$sedscript\" $sedinputs"`
239echo '--- backticks'
240echo "$x"
241
242
243# Test it in a case statement
244
245case `eval "mysed -n \"\$sedscript\" $sedinputs"` in
246 (*'[my sed command]'*)
247 echo 'NOT SPLIT'
248 ;;
249esac
250
251## STDOUT:
252--- $()
253[-n]
254[my sed command]
255[f1]
256[f2]
257--- backticks
258[-n]
259[my sed command]
260[f1]
261[f2]
262NOT SPLIT
263## END
264
265#### autoconf arithmetic - relaxed eval_unsafe_arith (#1450)
266
267as_fn_arith ()
268{
269 as_val=$(( $* ))
270}
271as_fn_arith 1 + 1
272echo $as_val
273
274## STDOUT:
2752
276## END
277
278#### command execution $(echo 42 | tee PWNED) not allowed
279
280rm -f PWNED
281
282x='a[$(echo 42 | tee PWNED)]=1'
283echo $(( x ))
284
285if test -f PWNED; then
286 cat PWNED
287else
288 echo NOPE
289fi
290
291## status: 1
292## OK dash/ash status: 2
293## stdout-json: ""
294## BUG bash/mksh/zsh status: 0
295## BUG bash/mksh/zsh STDOUT:
2961
29742
298## END
299
300#### process sub <(echo 42 | tee PWNED) not allowed
301
302rm -f PWNED
303
304x='a[<(echo 42 | tee PWNED)]=1'
305echo $(( x ))
306
307if test -f PWNED; then
308 cat PWNED
309else
310 echo NOPE
311fi
312
313## status: 1
314## stdout-json: ""
315
316## OK dash/ash status: 2
317
318# bash keeps going
319## BUG bash status: 0
320## BUG bash STDOUT:
321NOPE
322## END
323
324
325#### unset doesn't allow command execution
326
327typeset -a a # for mksh
328a=(42)
329echo len=${#a[@]}
330
331unset -v 'a[$(echo 0 | tee PWNED)]'
332echo len=${#a[@]}
333
334if test -f PWNED; then
335 echo PWNED
336 cat PWNED
337else
338 echo NOPE
339fi
340
341## status: 1
342## STDOUT:
343len=1
344## END
345
346## N-I dash/ash status: 2
347## N-I dash/ash stdout-json: ""
348
349## BUG bash/mksh status: 0
350## BUG bash/mksh STDOUT:
351len=1
352len=0
353PWNED
3540
355## END
356
357## BUG zsh status: 0
358## BUG zsh STDOUT:
359len=1
360len=1
361PWNED
3620
363## END
364
365#### printf integer size bug
366
367# from Koiche on Zulip
368
369printf '%x\n' 2147483648
370printf '%u\n' 2147483648
371## STDOUT:
37280000000
3732147483648
374## END
375
376#### (( status bug
377
378# from Koiche on Zulip
379
380case $SH in dash|ash) exit ;; esac
381
382(( 1 << 32 ))
383echo status=$?
384
385(( 1 << 32 )) && echo yes
386
387## STDOUT:
388status=0
389yes
390## END
391
392## N-I dash/ash STDOUT:
393## END
394
395#### autotools as_fn_arith bug in configure
396
397# Causes 'grep -e' check to infinite loop.
398# Reduced from a configure script.
399
400as_fn_arith() {
401 as_val=$(( $* ))
402}
403
404as_fn_arith 0 + 1
405echo as_val=$as_val
406## STDOUT:
407as_val=1
408## END
409
410#### osh-native duplicates stdin - is this a test harness issue?
411
412echo $0 | grep -o sh
413
414## STDOUT:
415sh
416## END
417
418#### bug from pnut: negative number $((-1))
419
420# https://lobste.rs/s/lplim1/design_self_compiling_c_transpiler#c_km2ywc
421
422[ $((-42)) -le 0 ]
423echo status=$?
424
425[ $((-1)) -le 0 ]
426echo status=$?
427
428echo
429
430[ -1 -le 0 ]
431echo status=$?
432
433[ -42 -le 0 ]
434echo status=$?
435
436echo
437
438test -1 -le 0
439echo status=$?
440
441test -42 -le 0
442echo status=$?
443
444## STDOUT:
445status=0
446status=0
447
448status=0
449status=0
450
451status=0
452status=0
453## END
454
455#### negative octal numbers, etc.
456
457# zero
458[ -0 -eq 0 ]
459echo zero=$?
460
461# octal numbers can be negative
462[ -0123 -eq -83 ]
463echo octal=$?
464
465# hex doesn't have negative numbers?
466[ -0xff -eq -255 ]
467echo hex=$?
468
469# base N doesn't either
470[ -64#a -eq -10 ]
471echo baseN=$?
472
473## STDOUT:
474zero=0
475octal=1
476hex=2
477baseN=2
478## END
479
480#### More negative numbers
481case $SH in dash) exit ;; esac
482
483[[ -1 -le 0 ]]
484echo status=$?
485
486[[ $((-1)) -le 0 ]]
487echo status=$?
488
489## STDOUT:
490status=0
491status=0
492## END
493
494## N-I dash STDOUT:
495## END
496