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