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
33 shopt -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
39 echo one
40 . $REPO_ROOT/spec/testdata/return-helper.sh
41 echo $?
42 echo two
43 ## STDOUT:
44 one
45 return-helper.sh
46 42
47 two
48 ## END
49
50 #### top level control flow
51 $SH $REPO_ROOT/spec/testdata/top-level-control-flow.sh
52 ## status: 0
53 ## STDOUT:
54 SUBSHELL
55 BREAK
56 CONTINUE
57 RETURN
58 ## OK bash STDOUT:
59 SUBSHELL
60 BREAK
61 CONTINUE
62 RETURN
63 DONE
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:
71 SUBSHELL
72 ## END
73
74 #### shopt -s strict_control_flow
75 shopt -s strict_control_flow || true
76 echo break
77 break
78 echo hi
79 ## STDOUT:
80 break
81 ## END
82 ## status: 1
83 ## N-I dash/bash/mksh STDOUT:
84 break
85 hi
86 # END
87 ## N-I dash/bash/mksh status: 0
88
89 #### return at top level is an error
90 return
91 echo "status=$?"
92 ## stdout-json: ""
93 ## OK bash STDOUT:
94 status=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.
99 continue
100 echo status=$?
101 ## stdout: status=0
102
103 #### break at top level is NOT an error
104 break
105 echo status=$?
106 ## stdout: status=0
107
108 #### empty argv WITHOUT strict_argv
109 x=''
110 $x
111 echo status=$?
112
113 if $x; then
114 echo VarSub
115 fi
116
117 if $(echo foo >/dev/null); then
118 echo CommandSub
119 fi
120
121 if "$x"; then
122 echo VarSub
123 else
124 echo VarSub FAILED
125 fi
126
127 if "$(echo foo >/dev/null)"; then
128 echo CommandSub
129 else
130 echo CommandSub FAILED
131 fi
132
133 ## STDOUT:
134 status=0
135 VarSub
136 CommandSub
137 VarSub FAILED
138 CommandSub FAILED
139 ## END
140
141 #### empty argv WITH strict_argv
142 shopt -s strict_argv || true
143 echo empty
144 x=''
145 $x
146 echo status=$?
147 ## status: 1
148 ## STDOUT:
149 empty
150 ## END
151 ## N-I dash/bash/mksh status: 0
152 ## N-I dash/bash/mksh STDOUT:
153 empty
154 status=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
163 a=('a b' 'c d')
164 b=('a' 'b' 'c' 'd')
165 echo ${#a[@]}
166 echo ${#b[@]}
167 [[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
168
169 shopt -s strict_array || true
170 [[ "${a[@]}" == "${b[@]}" ]] && echo EQUAL
171
172 ## status: 1
173 ## STDOUT:
174 2
175 4
176 EQUAL
177 ## END
178 ## OK bash/mksh status: 0
179 ## OK bash/mksh STDOUT:
180 2
181 4
182 EQUAL
183 EQUAL
184 ## END
185 ## N-I dash status: 2
186 ## N-I dash stdout-json: ""
187
188 #### automatically creating arrays WITHOUT strict_array
189 undef[2]=x
190 undef[3]=y
191 argv.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
199 shopt -u strict_arith || true
200
201 undef[2]=x
202 undef[3]=y
203 x='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
207 undef[$x]=zzz
208 argv.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
216 for 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 ---
225 done
226 ## STDOUT:
227 status=0
228 one
229 status=0
230 two
231 status=0
232 ---
233 status=2
234 status=2
235 two
236 status=0
237 ---
238 ## END
239 ## N-I dash/bash/mksh STDOUT:
240 status=0
241 one
242 status=0
243 two
244 status=0
245 ---
246 status=0
247 one
248 status=0
249 two
250 status=0
251 ---
252 ## END