OILS / spec / strict-options.test.sh View on Github | oilshell.org

277 lines, 133 significant
1## compare_shells: dash bash-4.4 mksh
2
3
4# In this file:
5#
6# - strict_control-flow: break/continue at the top level should be fatal!
7#
8# Other tests:
9# - spec/errexit-strict: command subs inherit errexit
10# - TODO: does bash 4.4. use inherit_errexit?
11#
12# - spec/var-op-other tests strict_word-eval (negative indices and invalid
13# utf-8)
14# - hm I think these should be the default? compat-word-eval?
15#
16# - spec/arith tests strict_arith - invalid strings become 0
17# - OSH has a warning that can turn into an error. I think the error could
18# be the default (since this was a side effect of "ShellMathShock")
19
20# - strict_array: unimplemented.
21# - WAS undef[2]=x, but bash-completion relied on the associative array
22# version of that.
23# - TODO: It should disable decay_array EVERYWHERE except a specific case like:
24# - s="${a[*]}" # quoted, the unquoted ones glob in a command context
25# - spec/dbracket has array comparison relevant to the case below
26#
27# Most of those options could be compat-*.
28#
29# One that can't: strict_scope disables dynamic scope.
30
31
32#### strict_arith option
33shopt -s strict_arith
34## status: 0
35## N-I bash status: 1
36## N-I dash/mksh status: 127
37
38#### Sourcing a script that returns at the top level
39echo one
40. $REPO_ROOT/spec/testdata/return-helper.sh
41echo $?
42echo two
43## STDOUT:
44one
45return-helper.sh
4642
47two
48## END
49
50#### top level control flow
51$SH $REPO_ROOT/spec/testdata/top-level-control-flow.sh
52## status: 0
53## STDOUT:
54SUBSHELL
55BREAK
56CONTINUE
57RETURN
58## OK bash STDOUT:
59SUBSHELL
60BREAK
61CONTINUE
62RETURN
63DONE
64## END
65
66#### errexit and top-level control flow
67$SH -o errexit $REPO_ROOT/spec/testdata/top-level-control-flow.sh
68## status: 2
69## OK bash status: 1
70## STDOUT:
71SUBSHELL
72## END
73
74#### shopt -s strict_control_flow
75shopt -s strict_control_flow || true
76echo break
77break
78echo hi
79## STDOUT:
80break
81## END
82## status: 1
83## N-I dash/bash/mksh STDOUT:
84break
85hi
86# END
87## N-I dash/bash/mksh status: 0
88
89#### return at top level is an error
90return
91echo "status=$?"
92## stdout-json: ""
93## OK bash STDOUT:
94status=1
95## END
96
97#### continue at top level is NOT an error
98# NOTE: bash and mksh both print warnings, but don't exit with an error.
99continue
100echo status=$?
101## stdout: status=0
102
103#### break at top level is NOT an error
104break
105echo status=$?
106## stdout: status=0
107
108#### empty argv WITHOUT strict_argv
109x=''
110$x
111echo status=$?
112
113if $x; then
114 echo VarSub
115fi
116
117if $(echo foo >/dev/null); then
118 echo CommandSub
119fi
120
121if "$x"; then
122 echo VarSub
123else
124 echo VarSub FAILED
125fi
126
127if "$(echo foo >/dev/null)"; then
128 echo CommandSub
129else
130 echo CommandSub FAILED
131fi
132
133## STDOUT:
134status=0
135VarSub
136CommandSub
137VarSub FAILED
138CommandSub FAILED
139## END
140
141#### empty argv WITH strict_argv
142shopt -s strict_argv || true
143echo empty
144x=''
145$x
146echo status=$?
147## status: 1
148## STDOUT:
149empty
150## END
151## N-I dash/bash/mksh status: 0
152## N-I dash/bash/mksh STDOUT:
153empty
154status=0
155## END
156
157#### Arrays are incorrectly compared, but strict_array prevents it
158
159# NOTE: from spec/dbracket has a test case like this
160# sane-array should turn this ON.
161# bash and mksh allow this because of decay
162
163a=('a b' 'c d')
164b=('a' 'b' 'c' 'd')
165echo ${#a[@]}
166echo ${#b[@]}
167[[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
168
169shopt -s strict_array || true
170[[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
171
172## status: 1
173## STDOUT:
1742
1754
176EQUAL
177## END
178## OK bash/mksh status: 0
179## OK bash/mksh STDOUT:
1802
1814
182EQUAL
183EQUAL
184## END
185## N-I dash status: 2
186## N-I dash stdout-json: ""
187
188#### automatically creating arrays WITHOUT strict_array
189undef[2]=x
190undef[3]=y
191argv.py "${undef[@]}"
192## STDOUT:
193['x', 'y']
194## END
195## N-I dash status: 2
196## N-I dash stdout-json: ""
197
198#### automatically creating arrays are INDEXED, not associative
199shopt -u strict_arith || true
200
201undef[2]=x
202undef[3]=y
203x='bad'
204# bad gets coerced to zero, but this is part of the RECURSIVE arithmetic
205# behavior, which we want to disallow. Consider disallowing in OSH.
206
207undef[$x]=zzz
208argv.py "${undef[@]}"
209## STDOUT:
210['zzz', 'x', 'y']
211## END
212## N-I dash status: 2
213## N-I dash stdout-json: ""
214
215#### simple_eval_builtin
216for i in 1 2; do
217 eval # zero args
218 echo status=$?
219 eval echo one
220 echo status=$?
221 eval 'echo two'
222 echo status=$?
223 shopt -s simple_eval_builtin
224 echo ---
225done
226## STDOUT:
227status=0
228one
229status=0
230two
231status=0
232---
233status=2
234status=2
235two
236status=0
237---
238## END
239## N-I dash/bash/mksh STDOUT:
240status=0
241one
242status=0
243two
244status=0
245---
246status=0
247one
248status=0
249two
250status=0
251---
252## END
253
254
255#### strict_parse_slice means you need explicit length
256case $SH in bash*|dash|mksh) exit ;; esac
257
258$SH -c '
259a=(1 2 3); echo /${a[@]::}/
260'
261echo status=$?
262
263$SH -c '
264shopt --set strict_parse_slice
265
266a=(1 2 3); echo /${a[@]::}/
267'
268echo status=$?
269
270## STDOUT:
271//
272status=0
273status=2
274## END
275
276## N-I bash/dash/mksh STDOUT:
277## END