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